@@ -686,6 +686,49 @@ pub trait Fp254Impl {
686686 ( script, hints)
687687 }
688688
689+ // Assumes tmul hint (1 BigInteger) at the top of stack
690+ // and operands (a, b, c, d) at stack depths (a_depth, b_depth, c_depth, d_depth)
691+ // Computes r = a * c + b * d (mod p)
692+ #[ allow( clippy:: too_many_arguments) ]
693+ fn hinted_mul_lc2_w4 (
694+ a_depth : u32 ,
695+ a : ark_bn254:: Fq ,
696+ b_depth : u32 ,
697+ b : ark_bn254:: Fq ,
698+ c_depth : u32 ,
699+ c : ark_bn254:: Fq ,
700+ d_depth : u32 ,
701+ d : ark_bn254:: Fq ,
702+ ) -> ( Script , Vec < Hint > ) {
703+ assert ! ( a_depth > b_depth && b_depth > c_depth && c_depth > d_depth) ;
704+
705+ let mut hints = Vec :: with_capacity ( 1 ) ;
706+
707+ let modulus = & Fq :: modulus_as_bigint ( ) ;
708+
709+ let x = BigInt :: from_str ( & a. to_string ( ) ) . unwrap ( ) ;
710+ let y = BigInt :: from_str ( & b. to_string ( ) ) . unwrap ( ) ;
711+ let z = BigInt :: from_str ( & c. to_string ( ) ) . unwrap ( ) ;
712+ let w = BigInt :: from_str ( & d. to_string ( ) ) . unwrap ( ) ;
713+
714+ let q = ( x * z + y * w) / modulus;
715+
716+ let script = script ! {
717+ for _ in 0 ..Self :: N_LIMBS {
718+ OP_DEPTH OP_1SUB OP_ROLL // hints
719+ }
720+ // { Fq::push(ark_bn254::Fq::from_str(&q.to_string()).unwrap()) }
721+ { Fq :: roll( a_depth + 1 ) }
722+ { Fq :: roll( b_depth + 2 ) }
723+ { Fq :: roll( c_depth + 3 ) }
724+ { Fq :: roll( d_depth + 4 ) }
725+ { Fq :: tmul_lc2_w4( ) }
726+ } ;
727+ hints. push ( Hint :: BigIntegerTmulLC2 ( q) ) ;
728+
729+ ( script, hints)
730+ }
731+
689732 #[ allow( clippy:: too_many_arguments) ]
690733 fn hinted_mul_lc4 (
691734 a_depth : u32 ,
@@ -792,6 +835,47 @@ pub trait Fp254Impl {
792835 ( script, hints)
793836 }
794837
838+ // Same as hinted_mul_lc2_keep_elements(), except retains operands (a, b, c, d) on stack
839+ #[ allow( clippy:: too_many_arguments) ]
840+ fn hinted_mul_lc2_keep_elements_w4 (
841+ a_depth : u32 ,
842+ a : ark_bn254:: Fq ,
843+ b_depth : u32 ,
844+ b : ark_bn254:: Fq ,
845+ c_depth : u32 ,
846+ c : ark_bn254:: Fq ,
847+ d_depth : u32 ,
848+ d : ark_bn254:: Fq ,
849+ ) -> ( Script , Vec < Hint > ) {
850+ assert ! ( a_depth > b_depth && b_depth > c_depth && c_depth > d_depth) ;
851+
852+ let mut hints = Vec :: with_capacity ( 1 ) ;
853+
854+ let modulus = & Fq :: modulus_as_bigint ( ) ;
855+
856+ let x = BigInt :: from_str ( & a. to_string ( ) ) . unwrap ( ) ;
857+ let y = BigInt :: from_str ( & b. to_string ( ) ) . unwrap ( ) ;
858+ let z = BigInt :: from_str ( & c. to_string ( ) ) . unwrap ( ) ;
859+ let w = BigInt :: from_str ( & d. to_string ( ) ) . unwrap ( ) ;
860+
861+ let q = ( x * z + y * w) / modulus;
862+
863+ let script = script ! {
864+ for _ in 0 ..Self :: N_LIMBS {
865+ OP_DEPTH OP_1SUB OP_ROLL // hints
866+ }
867+ // { Fq::push(ark_bn254::Fq::from_str(&q.to_string()).unwrap()) }
868+ { Fq :: copy( a_depth + 1 ) }
869+ { Fq :: copy( b_depth + 2 ) }
870+ { Fq :: copy( c_depth + 3 ) }
871+ { Fq :: copy( d_depth + 4 ) }
872+ { Fq :: tmul_lc2_w4( ) }
873+ } ;
874+ hints. push ( Hint :: BigIntegerTmulLC2 ( q) ) ;
875+
876+ ( script, hints)
877+ }
878+
795879 // TODO: Optimize using the sqaure feature
796880 fn hinted_square ( a : ark_bn254:: Fq ) -> ( Script , Vec < Hint > ) {
797881 let mut hints = Vec :: new ( ) ;
0 commit comments