@@ -22,8 +22,13 @@ use crate::{
2222 CircuitContext , Fp254Impl ,
2323 circuit:: { FromWires , OffCircuitParam , WiresArity , WiresObject } ,
2424 gadgets:: bn254:: {
25- final_exponentiation:: final_exponentiation_montgomery, fq:: Fq , fq2:: Fq2 , fq6:: Fq6 ,
26- fq12:: Fq12 , g1:: G1Projective , g2:: G2Projective ,
25+ final_exponentiation:: final_exponentiation_montgomery,
26+ fq:: Fq ,
27+ fq2:: Fq2 ,
28+ fq6:: Fq6 ,
29+ fq12:: { Fq12 , ValidFq12 } ,
30+ g1:: G1Projective ,
31+ g2:: G2Projective ,
2732 } ,
2833} ;
2934
@@ -883,7 +888,7 @@ pub fn pairing_const_q<C: CircuitContext>(
883888 circuit : & mut C ,
884889 p : & G1Projective ,
885890 q : & ark_bn254:: G2Affine ,
886- ) -> Fq12 {
891+ ) -> ValidFq12 {
887892 let f = miller_loop_const_q ( circuit, p, q) ;
888893 final_exponentiation_montgomery ( circuit, & f)
889894}
@@ -894,7 +899,7 @@ pub fn multi_pairing_const_q<C: CircuitContext>(
894899 circuit : & mut C ,
895900 ps : & [ G1Projective ] ,
896901 qs : & [ ark_bn254:: G2Affine ] ,
897- ) -> Fq12 {
902+ ) -> ValidFq12 {
898903 let f = multi_miller_loop_const_q ( circuit, ps, qs) ;
899904 final_exponentiation_montgomery ( circuit, & f)
900905}
@@ -1146,7 +1151,10 @@ mod tests {
11461151 } ;
11471152 let result =
11481153 CircuitBuilder :: streaming_execute :: < _ , _ , Fq12Output > ( input, 10_000 , |ctx, w| {
1149- ell_montgomery ( ctx, & w. f , & w. c , & w. p )
1154+ ValidFq12 {
1155+ f : ell_montgomery ( ctx, & w. f , & w. c , & w. p ) ,
1156+ is_valid : TRUE_WIRE ,
1157+ }
11501158 } ) ;
11511159
11521160 assert_eq ! ( result. output_value. value, expected_m) ;
@@ -1720,6 +1728,7 @@ mod tests {
17201728
17211729 struct FinalExpOutput {
17221730 value : ark_bn254:: Fq12 ,
1731+ is_valid : bool ,
17231732 }
17241733 impl CircuitInput for FEInput {
17251734 type WireRepr = FEWires ;
@@ -1740,7 +1749,7 @@ mod tests {
17401749 }
17411750 }
17421751 impl CircuitOutput < ExecuteMode > for FinalExpOutput {
1743- type WireRepr = Fq12 ;
1752+ type WireRepr = ValidFq12 ;
17441753 fn decode ( wires : Self :: WireRepr , cache : & mut ExecuteMode ) -> Self {
17451754 // Reuse local decoder helpers
17461755 fn decode_fq6_from_wires (
@@ -1779,10 +1788,14 @@ mod tests {
17791788 ark_bn254:: Fq2 :: new ( ark_bn254:: Fq :: from ( c2_c0) , ark_bn254:: Fq :: from ( c2_c1) ) ;
17801789 ark_bn254:: Fq6 :: new ( c0, c1, c2)
17811790 }
1782- let c0 = decode_fq6_from_wires ( & wires. 0 [ 0 ] , cache) ;
1783- let c1 = decode_fq6_from_wires ( & wires. 0 [ 1 ] , cache) ;
1791+ let c0 = decode_fq6_from_wires ( & wires. f . 0 [ 0 ] , cache) ;
1792+ let c1 = decode_fq6_from_wires ( & wires. f . 0 [ 1 ] , cache) ;
1793+ let is_valid = cache
1794+ . lookup_wire ( wires. is_valid )
1795+ . expect ( "missing wire value" ) ;
17841796 Self {
17851797 value : ark_bn254:: Fq12 :: new ( c0, c1) ,
1798+ is_valid,
17861799 }
17871800 }
17881801 }
@@ -1794,7 +1807,14 @@ mod tests {
17941807 |ctx, input| final_exponentiation_montgomery ( ctx, & input. f ) ,
17951808 ) ;
17961809
1797- assert_eq ! ( result. output_value. value, expected_m) ;
1810+ assert_eq ! (
1811+ result. output_value. value, expected_m,
1812+ "final_exponentiation_montgomery output should be valid"
1813+ ) ;
1814+ assert ! (
1815+ result. output_value. is_valid,
1816+ "final_exponentiation_montgomery input should be valid"
1817+ ) ;
17981818 }
17991819
18001820 #[ test]
@@ -1914,14 +1934,19 @@ mod tests {
19141934
19151935 struct Fq12Output {
19161936 value : ark_bn254:: Fq12 ,
1937+ valid : bool ,
19171938 }
19181939 impl CircuitOutput < ExecuteMode > for Fq12Output {
1919- type WireRepr = Fq12 ;
1940+ type WireRepr = ValidFq12 ;
19201941 fn decode ( wires : Self :: WireRepr , cache : & mut ExecuteMode ) -> Self {
1921- let c0 = decode_fq6_from_wires ( & wires. 0 [ 0 ] , cache) ;
1922- let c1 = decode_fq6_from_wires ( & wires. 0 [ 1 ] , cache) ;
1942+ let c0 = decode_fq6_from_wires ( & wires. f . 0 [ 0 ] , cache) ;
1943+ let c1 = decode_fq6_from_wires ( & wires. f . 0 [ 1 ] , cache) ;
1944+ let is_valid = cache
1945+ . lookup_wire ( wires. is_valid )
1946+ . expect ( "missing wire value" ) ;
19231947 Self {
19241948 value : ark_bn254:: Fq12 :: new ( c0, c1) ,
1949+ valid : is_valid,
19251950 }
19261951 }
19271952 }
@@ -2018,7 +2043,10 @@ mod tests {
20182043 } ;
20192044 let result =
20202045 CircuitBuilder :: streaming_execute :: < _ , _ , Fq12Output > ( input, 10_000 , |ctx, input| {
2021- ell_eval_const ( ctx, & input. f , & coeff, & input. p )
2046+ ValidFq12 {
2047+ f : ell_eval_const ( ctx, & input. f , & coeff, & input. p ) ,
2048+ is_valid : TRUE_WIRE ,
2049+ }
20222050 } ) ;
20232051
20242052 assert_eq ! ( result. output_value. value, expected_m) ;
@@ -2095,7 +2123,10 @@ mod tests {
20952123 let result = CircuitBuilder :: streaming_execute :: < _ , _ , Fq12Output > (
20962124 In { p } ,
20972125 10_000 ,
2098- |ctx, input| miller_loop_const_q ( ctx, & input. p , & q) ,
2126+ |ctx, input| ValidFq12 {
2127+ f : miller_loop_const_q ( ctx, & input. p , & q) ,
2128+ is_valid : TRUE_WIRE ,
2129+ } ,
20992130 ) ;
21002131
21012132 assert_eq ! ( result. output_value. value, expected_m) ;
@@ -2175,7 +2206,8 @@ mod tests {
21752206 |ctx, input| pairing_const_q ( ctx, & input. p , & q) ,
21762207 ) ;
21772208
2178- assert_eq ! ( result. output_value. value, expected_m) ;
2209+ assert ! ( result. output_value. valid, "input should be valid" ) ;
2210+ assert_eq ! ( result. output_value. value, expected_m, "output should match" ) ;
21792211 }
21802212
21812213 #[ test]
@@ -2511,7 +2543,10 @@ mod tests {
25112543 let result = CircuitBuilder :: streaming_execute :: < _ , _ , Fq12Output > (
25122544 input,
25132545 40_000 ,
2514- |circuit, wires| multi_miller_loop_montgomery_fast ( circuit, & wires. ps , & wires. qs ) ,
2546+ |circuit, wires| ValidFq12 {
2547+ f : multi_miller_loop_montgomery_fast ( circuit, & wires. ps , & wires. qs ) ,
2548+ is_valid : TRUE_WIRE ,
2549+ } ,
25152550 ) ;
25162551
25172552 assert_eq ! ( result. output_value. value, expected_m) ;
@@ -2730,9 +2765,12 @@ mod tests {
27302765 let input = In { p1, p2, p3, q3 } ;
27312766 let result =
27322767 CircuitBuilder :: streaming_execute :: < _ , _ , Fq12Output > ( input, 80_000 , |ctx, w| {
2733- multi_miller_loop_groth16_evaluate_montgomery_fast (
2734- ctx, & w. p1 , & w. p2 , & w. p3 , q1, q2, & w. q3 ,
2735- )
2768+ ValidFq12 {
2769+ f : multi_miller_loop_groth16_evaluate_montgomery_fast (
2770+ ctx, & w. p1 , & w. p2 , & w. p3 , q1, q2, & w. q3 ,
2771+ ) ,
2772+ is_valid : TRUE_WIRE ,
2773+ }
27362774 } ) ;
27372775
27382776 assert_eq ! (
0 commit comments