11use ark_ec:: { bn:: BnConfig , short_weierstrass:: SWCurveConfig } ;
22use ark_ff:: { AdditiveGroup , Field , Fp2Config } ;
3- use crate :: { bag:: * , circuits:: bn254:: { fp254impl:: Fp254Impl , fq:: Fq , fq12:: Fq12 , fq2:: Fq2 , utils:: wires_set_from_fq2} } ;
3+ use crate :: { bag:: * , circuits:: bn254:: { fp254impl:: Fp254Impl , fq:: Fq , fq12:: Fq12 , fq2:: Fq2 , utils:: { fq12_from_wires , fq2_from_wires , g1p_from_wires , g2a_from_wires , wires_set_from_fq12 , wires_set_from_fq2} } } ;
44
55pub fn double_in_place ( r : & mut ark_bn254:: G2Projective ) -> ( ark_bn254:: Fq2 , ark_bn254:: Fq2 , ark_bn254:: Fq2 ) {
66 let half = ark_bn254:: Fq :: from ( Fq :: half_modulus ( ) ) ;
@@ -332,6 +332,18 @@ pub fn ell(f: &mut ark_bn254::Fq12, coeffs: (ark_bn254::Fq2, ark_bn254::Fq2, ark
332332 f. mul_by_034 ( & c0, & c1, & c2) ;
333333}
334334
335+ pub fn ell2 ( f : ark_bn254:: Fq12 , coeffs : ( ark_bn254:: Fq2 , ark_bn254:: Fq2 , ark_bn254:: Fq2 ) , p : ark_bn254:: G1Projective ) -> ark_bn254:: Fq12 {
336+ let mut new_f = f. clone ( ) ;
337+ let mut c0 = coeffs. 0 ;
338+ let mut c1 = coeffs. 1 ;
339+ let c2 = coeffs. 2 ;
340+
341+ c0. mul_assign_by_fp ( & p. y ) ;
342+ c1. mul_assign_by_fp ( & p. x ) ;
343+ new_f. mul_by_034 ( & c0, & c1, & c2) ;
344+ new_f
345+ }
346+
335347pub fn ell_circuit ( f : Wires , coeffs : ( Wires , Wires , Wires ) , p : Wires ) -> Circuit {
336348 let mut circuit = Circuit :: empty ( ) ;
337349 let c0 = coeffs. 0 ;
@@ -349,12 +361,35 @@ pub fn ell_circuit(f: Wires, coeffs: (Wires, Wires, Wires), p: Wires) -> Circuit
349361 circuit
350362}
351363
364+ pub fn ell_circuit_evaluate ( f : Wires , coeffs : ( Wires , Wires , Wires ) , p : Wires ) -> ( Wires , usize ) {
365+ let circuit = ell_circuit ( f, coeffs, p) ;
366+
367+ let n = circuit. 1 . len ( ) ;
368+
369+ for mut gate in circuit. 1 {
370+ gate. evaluate ( ) ;
371+ }
372+
373+ ( circuit. 0 , n)
374+ }
375+
376+ pub fn fq12_square_evaluate ( f : Wires ) -> ( Wires , usize ) {
377+ let circuit = Fq12 :: square ( f) ;
378+
379+ let n = circuit. 1 . len ( ) ;
380+
381+ for mut gate in circuit. 1 {
382+ gate. evaluate ( ) ;
383+ }
384+
385+ ( circuit. 0 , n)
386+ }
387+
352388pub fn miller_loop ( p : ark_bn254:: G1Projective , q : ark_bn254:: G2Affine ) -> ark_bn254:: Fq12 {
353389 let qell = ell_coeffs ( q) ;
354390 let mut q_ell = qell. iter ( ) ;
355391
356392 let mut f = ark_bn254:: Fq12 :: ONE ;
357-
358393 for i in ( 1 ..ark_bn254:: Config :: ATE_LOOP_COUNT . len ( ) ) . rev ( ) {
359394 if i != ark_bn254:: Config :: ATE_LOOP_COUNT . len ( ) - 1 {
360395 f. square_in_place ( ) ;
@@ -374,6 +409,48 @@ pub fn miller_loop(p: ark_bn254::G1Projective, q: ark_bn254::G2Affine) -> ark_bn
374409 f
375410}
376411
412+ pub fn miller_loop_circuit_evaluate ( p : Wires , q : Wires ) -> ( Wires , usize ) {
413+ let mut gate_count = 0 ;
414+ let ( qell, gc) = ( ell_coeffs ( g2a_from_wires ( q) ) . iter ( ) . map ( |( c0, c1, c2) | { ( wires_set_from_fq2 ( * c0) , wires_set_from_fq2 ( * c1) , wires_set_from_fq2 ( * c2) ) } ) . collect :: < Vec < _ > > ( ) , 0 ) ; // ell_coeffs_circuit_evaluate(q);
415+ gate_count += gc;
416+ let mut q_ell = qell. iter ( ) ;
417+
418+ let mut f = wires_set_from_fq12 ( ark_bn254:: Fq12 :: ONE ) ;
419+
420+ for i in ( 1 ..ark_bn254:: Config :: ATE_LOOP_COUNT . len ( ) ) . rev ( ) {
421+ if i != ark_bn254:: Config :: ATE_LOOP_COUNT . len ( ) - 1 {
422+ let ( new_f, gc) = ( wires_set_from_fq12 ( fq12_from_wires ( f) . square ( ) ) , 1 ) ; // fq12_square_evaluate(f);
423+ f = new_f;
424+ gate_count += gc;
425+ }
426+
427+ let qell_next = q_ell. next ( ) . unwrap ( ) . clone ( ) ;
428+ let ( new_f, gc) = ( wires_set_from_fq12 ( ell2 ( fq12_from_wires ( f) , ( fq2_from_wires ( qell_next. 0 ) , fq2_from_wires ( qell_next. 1 ) , fq2_from_wires ( qell_next. 2 ) ) , g1p_from_wires ( p. clone ( ) ) ) ) , 1000000000000 ) ; // ell_circuit_evaluate(f, q_ell.next().unwrap().clone(), p.clone());
429+ f = new_f;
430+ gate_count += gc;
431+
432+ let bit = ark_bn254:: Config :: ATE_LOOP_COUNT [ i - 1 ] ;
433+ if bit == 1 || bit == -1 {
434+ let qell_next = q_ell. next ( ) . unwrap ( ) . clone ( ) ;
435+ let ( new_f, gc) = ( wires_set_from_fq12 ( ell2 ( fq12_from_wires ( f) , ( fq2_from_wires ( qell_next. 0 ) , fq2_from_wires ( qell_next. 1 ) , fq2_from_wires ( qell_next. 2 ) ) , g1p_from_wires ( p. clone ( ) ) ) ) , 1000000000000 ) ; // ell_circuit_evaluate(f, q_ell.next().unwrap().clone(), p.clone());
436+ f = new_f;
437+ gate_count += gc;
438+ }
439+ }
440+
441+ let qell_next = q_ell. next ( ) . unwrap ( ) . clone ( ) ;
442+ let ( new_f, gc) = ( wires_set_from_fq12 ( ell2 ( fq12_from_wires ( f) , ( fq2_from_wires ( qell_next. 0 ) , fq2_from_wires ( qell_next. 1 ) , fq2_from_wires ( qell_next. 2 ) ) , g1p_from_wires ( p. clone ( ) ) ) ) , 1000000000000 ) ; // ell_circuit_evaluate(f, q_ell.next().unwrap().clone(), p.clone());
443+ f = new_f;
444+ gate_count += gc;
445+ println ! ( "f: {:?}" , fq12_from_wires( f. clone( ) ) ) ;
446+ let qell_next = q_ell. next ( ) . unwrap ( ) . clone ( ) ;
447+ let ( new_f, gc) = ( wires_set_from_fq12 ( ell2 ( fq12_from_wires ( f) , ( fq2_from_wires ( qell_next. 0 ) , fq2_from_wires ( qell_next. 1 ) , fq2_from_wires ( qell_next. 2 ) ) , g1p_from_wires ( p. clone ( ) ) ) ) , 1000000000000 ) ; // ell_circuit_evaluate(f, q_ell.next().unwrap().clone(), p.clone());
448+ f = new_f;
449+ gate_count += gc;
450+
451+ ( f, gate_count)
452+ }
453+
377454#[ cfg( test) ]
378455mod tests {
379456 use std:: iter:: zip;
@@ -485,7 +562,7 @@ mod tests {
485562 let ( coeffs, gate_count) = ell_coeffs_circuit_evaluate ( wires_set_from_g2a ( q) ) ;
486563 println ! ( "gate_count: {:?}" , gate_count) ;
487564
488- for ( a, b) in zip ( coeffs, expected_coeffs) {
565+ for ( a, b) in zip ( coeffs, expected_coeffs) {
489566 assert_eq ! ( fq2_from_wires( a. 0 ) , b. 0 ) ;
490567 assert_eq ! ( fq2_from_wires( a. 1 ) , b. 1 ) ;
491568 assert_eq ! ( fq2_from_wires( a. 2 ) , b. 2 ) ;
@@ -519,4 +596,18 @@ mod tests {
519596 let d = miller_loop ( p, q) ;
520597 assert_eq ! ( c, d) ;
521598 }
599+
600+ #[ test]
601+ fn test_miller_loop_circuit_evaluate ( ) {
602+ // since it takes too much time to run, we cheat a bit just to test if it is correct or not, gate_count shows the number of ells and squares separated by a bunch of zeroes, (87, 63)
603+ let mut prng = ChaCha20Rng :: seed_from_u64 ( 0 ) ;
604+ let p = ark_bn254:: G1Projective :: rand ( & mut prng) ;
605+ let q = ark_bn254:: G2Affine :: rand ( & mut prng) ;
606+
607+ let expected_f = miller_loop ( p, q) ;
608+ let ( f, gate_count) = miller_loop_circuit_evaluate ( wires_set_from_g1p ( p) , wires_set_from_g2a ( q) ) ;
609+ println ! ( "gate_count: {:?}" , gate_count) ;
610+
611+ assert_eq ! ( fq12_from_wires( f) , expected_f) ;
612+ }
522613}
0 commit comments