| 98 | } |
| 99 | |
| 100 | pub fn hinted_mul( |
| 101 | mut a_depth: u32, |
| 102 | mut a: ark_bn254::Fq, |
| 103 | mut b_depth: u32, |
| 104 | mut b: ark_bn254::Fq, |
| 105 | ) -> (Script, Vec<Hint>) { |
| 106 | assert_ne!(a_depth, b_depth); |
| 107 | if a_depth > b_depth { |
| 108 | (a_depth, b_depth) = (b_depth, a_depth); |
| 109 | (a, b) = (b, a); |
| 110 | } |
| 111 | |
| 112 | let mut hints = Vec::new(); |
| 113 | let x = BigInt::from_str(&a.to_string()).unwrap(); |
| 114 | let y = BigInt::from_str(&b.to_string()).unwrap(); |
| 115 | let modulus = &Fq::modulus_as_bigint(); |
| 116 | let q = (x * y) / modulus; |
| 117 | |
| 118 | let script = script! { |
| 119 | for _ in 0..Self::N_LIMBS { |
| 120 | OP_DEPTH OP_1SUB OP_ROLL // hints |
| 121 | } |
| 122 | // { Fq::push(ark_bn254::Fq::from_str(&q.to_string()).unwrap()) } |
| 123 | { Fq::roll(a_depth + 1) } |
| 124 | { Fq::roll(b_depth + 1) } |
| 125 | { Fq::tmul() } |
| 126 | }; |
| 127 | hints.push(Hint::BigIntegerTmulLC1(q)); |
| 128 | |
| 129 | (script, hints) |
| 130 | } |
| 131 | |
| 132 | // TODO: Optimize by using the constant feature |
| 133 | pub fn hinted_mul_by_constant( |