| 210 | } |
| 211 | |
| 212 | fn utils_point_add_eval( |
| 213 | t: ark_bn254::G2Affine, |
| 214 | q4: ark_bn254::G2Affine, |
| 215 | p: ark_bn254::G1Affine, |
| 216 | is_frob: bool, |
| 217 | ate_bit: i8, |
| 218 | ) -> ( |
| 219 | (ark_bn254::G2Affine, (ark_bn254::Fq2, ark_bn254::Fq2)), |
| 220 | Script, |
| 221 | Vec<Hint>, |
| 222 | ) { |
| 223 | let mut hints = vec![]; |
| 224 | |
| 225 | // Precompute Q |
| 226 | let temp_q = q4; |
| 227 | let (qq, precomp_q_scr, precomp_q_hint) = if is_frob { |
| 228 | if ate_bit == 1 { |
| 229 | hinted_mul_by_char_on_q(temp_q) |
| 230 | } else { |
| 231 | hinted_mul_by_char_on_phi_q(temp_q) |
| 232 | } |
| 233 | } else if ate_bit == -1 { |
| 234 | ( |
| 235 | temp_q.neg(), |
| 236 | script! { |
| 237 | // [q4] |
| 238 | {Fq::toaltstack()} |
| 239 | {Fq::neg(0)} |
| 240 | {Fq::fromaltstack()} |
| 241 | {Fq::neg(0)} |
| 242 | // [-q4] |
| 243 | }, |
| 244 | vec![], |
| 245 | ) |
| 246 | } else { |
| 247 | (temp_q, script! {}, vec![]) |
| 248 | }; |
| 249 | hints.extend(precomp_q_hint); |
| 250 | |
| 251 | // Point Add |
| 252 | let t_is_zero = t.is_zero() |
| 253 | || (t == ark_bn254::G2Affine::new_unchecked(ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO)); // t is none or Some(0) |
| 254 | let q_is_zero = qq.is_zero() |
| 255 | || (qq == ark_bn254::G2Affine::new_unchecked(ark_bn254::Fq2::ZERO, ark_bn254::Fq2::ZERO)); // q is none or Some(0) |
| 256 | let is_valid_input = !t_is_zero && !q_is_zero && t != -qq; |
| 257 | |
| 258 | // if it's valid input, you can compute line coefficients, else hardcode degenerate values |
| 259 | let (alpha, bias) = if is_valid_input { |
| 260 | if t == qq { |
| 261 | let alpha = (t.x.square() + t.x.square() + t.x.square()) / (t.y + t.y); |
| 262 | let bias = t.y - alpha * t.x; |
| 263 | (alpha, bias) |
| 264 | } else { |
| 265 | let alpha = (t.y - qq.y) / (t.x - qq.x); |
| 266 | let bias = t.y - alpha * t.x; |
| 267 | (alpha, bias) |
| 268 | } |
| 269 | } else { |