| 378 | // Same as hinted_mul_lc2_keep_elements(), except retains operands (a, b, c, d) on stack |
| 379 | #[allow(clippy::too_many_arguments)] |
| 380 | pub fn hinted_mul_lc2_keep_elements_w4( |
| 381 | a_depth: u32, |
| 382 | a: ark_bn254::Fq, |
| 383 | b_depth: u32, |
| 384 | b: ark_bn254::Fq, |
| 385 | c_depth: u32, |
| 386 | c: ark_bn254::Fq, |
| 387 | d_depth: u32, |
| 388 | d: ark_bn254::Fq, |
| 389 | ) -> (Script, Vec<Hint>) { |
| 390 | assert!(a_depth > b_depth && b_depth > c_depth && c_depth > d_depth); |
| 391 | |
| 392 | let mut hints = Vec::with_capacity(1); |
| 393 | |
| 394 | let modulus = &Fq::modulus_as_bigint(); |
| 395 | |
| 396 | let x = BigInt::from_str(&a.to_string()).unwrap(); |
| 397 | let y = BigInt::from_str(&b.to_string()).unwrap(); |
| 398 | let z = BigInt::from_str(&c.to_string()).unwrap(); |
| 399 | let w = BigInt::from_str(&d.to_string()).unwrap(); |
| 400 | |
| 401 | let q = (x * z + y * w) / modulus; |
| 402 | |
| 403 | let script = script! { |
| 404 | for _ in 0..Self::N_LIMBS { |
| 405 | OP_DEPTH OP_1SUB OP_ROLL // hints |
| 406 | } |
| 407 | // { Fq::push(ark_bn254::Fq::from_str(&q.to_string()).unwrap()) } |
| 408 | { Fq::copy(a_depth + 1) } |
| 409 | { Fq::copy(b_depth + 2) } |
| 410 | { Fq::copy(c_depth + 3) } |
| 411 | { Fq::copy(d_depth + 4) } |
| 412 | { Fq::tmul_lc2_w4() } |
| 413 | }; |
| 414 | hints.push(Hint::BigIntegerTmulLC2(q)); |
| 415 | |
| 416 | (script, hints) |
| 417 | } |
| 418 | |
| 419 | // TODO: Optimize using the sqaure feature |
| 420 | pub fn hinted_square(a: ark_bn254::Fq) -> (Script, Vec<Hint>) { |