| 111 | } |
| 112 | |
| 113 | fn utils_point_double_eval( |
| 114 | t: ark_bn254::G2Affine, |
| 115 | p: ark_bn254::G1Affine, |
| 116 | ) -> ( |
| 117 | (ark_bn254::G2Affine, (ark_bn254::Fq2, ark_bn254::Fq2)), |
| 118 | Script, |
| 119 | Vec<Hint>, |
| 120 | ) { |
| 121 | let mut hints = vec![]; |
| 122 | |
| 123 | let t_is_zero = t.is_zero() |
| 124 | || (t == ark_bn254::G2Affine::new_unchecked(ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO)); // t is none or Some(0) |
| 125 | let is_valid_input = !t_is_zero; |
| 126 | let (alpha, bias) = if is_valid_input { |
| 127 | let alpha = (t.x.square() + t.x.square() + t.x.square()) / (t.y + t.y); |
| 128 | let bias = t.y - alpha * t.x; |
| 129 | (alpha, bias) |
| 130 | } else { |
| 131 | (ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO) |
| 132 | }; |
| 133 | |
| 134 | let (hinted_script1, hint1) = hinted_check_tangent_line_keep_elements(t, alpha, -bias); |
| 135 | let (hinted_script2, hint2) = hinted_affine_double_line(t.x, alpha, -bias); |
| 136 | let (hinted_script3, hint3) = hinted_ell_by_constant_affine(p.x, p.y, alpha, -bias); |
| 137 | |
| 138 | let result = if is_valid_input { |
| 139 | let mut dbl_le0 = alpha; |
| 140 | dbl_le0.mul_assign_by_fp(&p.x); |
| 141 | let mut dbl_le1 = -bias; |
| 142 | dbl_le1.mul_assign_by_fp(&p.y); |
| 143 | ((t + t).into_affine(), (dbl_le0, dbl_le1)) |
| 144 | } else { |
| 145 | let zero_pt = |
| 146 | ark_bn254::G2Affine::new_unchecked(ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO); |
| 147 | (zero_pt, (ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO)) |
| 148 | }; |
| 149 | |
| 150 | if is_valid_input { |
| 151 | hints.push(Hint::Fq(alpha.c0)); |
| 152 | hints.push(Hint::Fq(alpha.c1)); |
| 153 | hints.push(Hint::Fq(-bias.c0)); |
| 154 | hints.push(Hint::Fq(-bias.c1)); |
| 155 | hints.extend(hint1); |
| 156 | hints.extend(hint2); |
| 157 | hints.extend(hint3); |
| 158 | } |
| 159 | |
| 160 | let script = script! { |
| 161 | // tx, ty, px, py |
| 162 | { Fq2::toaltstack()} |
| 163 | { G2Affine::is_zero_keep_element() } // ... (dependent on input), x, y, 0/1 |
| 164 | OP_IF |
| 165 | // [t] [p] |
| 166 | {Fq2::fromaltstack()} {Fq2::drop()} |
| 167 | // [t] |
| 168 | {Fq2::push(ark_bn254::Fq2::ZERO)} |
| 169 | {Fq2::push(ark_bn254::Fq2::ZERO)} |
| 170 | // [t, nt] |