@@ -23,7 +23,7 @@ pub enum TwistType {
2323 D ,
2424}
2525
26- pub trait BnConfig : ' static {
26+ pub trait BnConfig : ' static + Sized {
2727 /// The absolute value of the BN curve parameter `X`
2828 /// (as in `q = 36 X^4 + 36 X^3 + 24 X^2 + 6 X + 1`).
2929 const X : & ' static [ u64 ] ;
@@ -46,65 +46,11 @@ pub trait BnConfig: 'static {
4646 BaseField = Fp2 < Self :: Fp2Config > ,
4747 ScalarField = <Self :: G1Config as CurveConfig >:: ScalarField ,
4848 > ;
49- }
50-
51- pub mod g1;
52- pub mod g2;
53-
54- pub use self :: {
55- g1:: { G1Affine , G1Prepared , G1Projective } ,
56- g2:: { G2Affine , G2Prepared , G2Projective } ,
57- } ;
58-
59- #[ derive( Derivative ) ]
60- #[ derivative( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
61- pub struct Bn < P : BnConfig > ( PhantomData < fn ( ) -> P > ) ;
62-
63- impl < P : BnConfig > Bn < P > {
64- /// Evaluates the line function at point p.
65- fn ell ( f : & mut Fp12 < P :: Fp12Config > , coeffs : & g2:: EllCoeff < P > , p : & G1Affine < P > ) {
66- let mut c0 = coeffs. 0 ;
67- let mut c1 = coeffs. 1 ;
68- let mut c2 = coeffs. 2 ;
69-
70- match P :: TWIST_TYPE {
71- TwistType :: M => {
72- c2. mul_assign_by_fp ( & p. y ) ;
73- c1. mul_assign_by_fp ( & p. x ) ;
74- f. mul_by_014 ( & c0, & c1, & c2) ;
75- } ,
76- TwistType :: D => {
77- c0. mul_assign_by_fp ( & p. y ) ;
78- c1. mul_assign_by_fp ( & p. x ) ;
79- f. mul_by_034 ( & c0, & c1, & c2) ;
80- } ,
81- }
82- }
83-
84- fn exp_by_neg_x ( mut f : Fp12 < P :: Fp12Config > ) -> Fp12 < P :: Fp12Config > {
85- f = f. cyclotomic_exp ( & P :: X ) ;
86- if !P :: X_IS_NEGATIVE {
87- f. cyclotomic_inverse_in_place ( ) ;
88- }
89- f
90- }
91- }
92-
93- impl < P : BnConfig > Pairing for Bn < P > {
94- type BaseField = <P :: G1Config as CurveConfig >:: BaseField ;
95- type ScalarField = <P :: G1Config as CurveConfig >:: ScalarField ;
96- type G1 = G1Projective < P > ;
97- type G1Affine = G1Affine < P > ;
98- type G1Prepared = G1Prepared < P > ;
99- type G2 = G2Projective < P > ;
100- type G2Affine = G2Affine < P > ;
101- type G2Prepared = G2Prepared < P > ;
102- type TargetField = Fp12 < P :: Fp12Config > ;
10349
10450 fn multi_miller_loop (
105- a : impl IntoIterator < Item = impl Into < Self :: G1Prepared > > ,
106- b : impl IntoIterator < Item = impl Into < Self :: G2Prepared > > ,
107- ) -> MillerLoopOutput < Self > {
51+ a : impl IntoIterator < Item = impl Into < G1Prepared < Self > > > ,
52+ b : impl IntoIterator < Item = impl Into < G2Prepared < Self > > > ,
53+ ) -> MillerLoopOutput < Bn < Self > > {
10854 let mut pairs = a
10955 . into_iter ( )
11056 . zip_eq ( b)
@@ -119,44 +65,44 @@ impl<P: BnConfig> Pairing for Bn<P> {
11965
12066 let mut f = cfg_chunks_mut ! ( pairs, 4 )
12167 . map ( |pairs| {
122- let mut f = Self :: TargetField :: one ( ) ;
123- for i in ( 1 ..P :: ATE_LOOP_COUNT . len ( ) ) . rev ( ) {
124- if i != P :: ATE_LOOP_COUNT . len ( ) - 1 {
68+ let mut f = < Bn < Self > as Pairing > :: TargetField :: one ( ) ;
69+ for i in ( 1 ..Self :: ATE_LOOP_COUNT . len ( ) ) . rev ( ) {
70+ if i != Self :: ATE_LOOP_COUNT . len ( ) - 1 {
12571 f. square_in_place ( ) ;
12672 }
12773
12874 for ( p, coeffs) in pairs. iter_mut ( ) {
129- Self :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
75+ Bn :: < Self > :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
13076 }
13177
132- let bit = P :: ATE_LOOP_COUNT [ i - 1 ] ;
78+ let bit = Self :: ATE_LOOP_COUNT [ i - 1 ] ;
13379 if bit == 1 || bit == -1 {
13480 for ( p, coeffs) in pairs. iter_mut ( ) {
135- Self :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
81+ Bn :: < Self > :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
13682 }
13783 }
13884 }
13985 f
14086 } )
141- . product :: < Self :: TargetField > ( ) ;
87+ . product :: < < Bn < Self > as Pairing > :: TargetField > ( ) ;
14288
143- if P :: X_IS_NEGATIVE {
89+ if Self :: X_IS_NEGATIVE {
14490 f. cyclotomic_inverse_in_place ( ) ;
14591 }
14692
14793 for ( p, coeffs) in & mut pairs {
148- Self :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
94+ Bn :: < Self > :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
14995 }
15096
15197 for ( p, coeffs) in & mut pairs {
152- Self :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
98+ Bn :: < Self > :: ell ( & mut f, & coeffs. next ( ) . unwrap ( ) , & p. 0 ) ;
15399 }
154100
155101 MillerLoopOutput ( f)
156102 }
157103
158104 #[ allow( clippy:: let_and_return) ]
159- fn final_exponentiation ( f : MillerLoopOutput < Self > ) -> Option < PairingOutput < Self > > {
105+ fn final_exponentiation ( f : MillerLoopOutput < Bn < Self > > ) -> Option < PairingOutput < Bn < Self > > > {
160106 // Easy part: result = elt^((q^6-1)*(q^2+1)).
161107 // Follows, e.g., Beuchat et al page 9, by computing result as follows:
162108 // elt^((q^6-1)*(q^2+1)) = (conj(elt) * elt^(-1))^(q^2+1)
@@ -191,13 +137,13 @@ impl<P: BnConfig> Pairing for Bn<P> {
191137 //
192138 // result = elt^( 2z * ( 6z^2 + 3z + 1 ) * (q^4 - q^2 + 1)/r ).
193139
194- let y0 = Self :: exp_by_neg_x ( r) ;
140+ let y0 = Bn :: < Self > :: exp_by_neg_x ( r) ;
195141 let y1 = y0. cyclotomic_square ( ) ;
196142 let y2 = y1. cyclotomic_square ( ) ;
197143 let mut y3 = y2 * & y1;
198- let y4 = Self :: exp_by_neg_x ( y3) ;
144+ let y4 = Bn :: < Self > :: exp_by_neg_x ( y3) ;
199145 let y5 = y4. cyclotomic_square ( ) ;
200- let mut y6 = Self :: exp_by_neg_x ( y5) ;
146+ let mut y6 = Bn :: < Self > :: exp_by_neg_x ( y5) ;
201147 y3. cyclotomic_inverse_in_place ( ) ;
202148 y6. cyclotomic_inverse_in_place ( ) ;
203149 let y7 = y6 * & y4;
@@ -219,3 +165,68 @@ impl<P: BnConfig> Pairing for Bn<P> {
219165 } )
220166 }
221167}
168+
169+ pub mod g1;
170+ pub mod g2;
171+
172+ pub use self :: {
173+ g1:: { G1Affine , G1Prepared , G1Projective } ,
174+ g2:: { G2Affine , G2Prepared , G2Projective } ,
175+ } ;
176+
177+ #[ derive( Derivative ) ]
178+ #[ derivative( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
179+ pub struct Bn < P : BnConfig > ( PhantomData < fn ( ) -> P > ) ;
180+
181+ impl < P : BnConfig > Bn < P > {
182+ /// Evaluates the line function at point p.
183+ fn ell ( f : & mut Fp12 < P :: Fp12Config > , coeffs : & g2:: EllCoeff < P > , p : & G1Affine < P > ) {
184+ let mut c0 = coeffs. 0 ;
185+ let mut c1 = coeffs. 1 ;
186+ let mut c2 = coeffs. 2 ;
187+
188+ match P :: TWIST_TYPE {
189+ TwistType :: M => {
190+ c2. mul_assign_by_fp ( & p. y ) ;
191+ c1. mul_assign_by_fp ( & p. x ) ;
192+ f. mul_by_014 ( & c0, & c1, & c2) ;
193+ } ,
194+ TwistType :: D => {
195+ c0. mul_assign_by_fp ( & p. y ) ;
196+ c1. mul_assign_by_fp ( & p. x ) ;
197+ f. mul_by_034 ( & c0, & c1, & c2) ;
198+ } ,
199+ }
200+ }
201+
202+ fn exp_by_neg_x ( mut f : Fp12 < P :: Fp12Config > ) -> Fp12 < P :: Fp12Config > {
203+ f = f. cyclotomic_exp ( P :: X ) ;
204+ if !P :: X_IS_NEGATIVE {
205+ f. cyclotomic_inverse_in_place ( ) ;
206+ }
207+ f
208+ }
209+ }
210+
211+ impl < P : BnConfig > Pairing for Bn < P > {
212+ type BaseField = <P :: G1Config as CurveConfig >:: BaseField ;
213+ type ScalarField = <P :: G1Config as CurveConfig >:: ScalarField ;
214+ type G1 = G1Projective < P > ;
215+ type G1Affine = G1Affine < P > ;
216+ type G1Prepared = G1Prepared < P > ;
217+ type G2 = G2Projective < P > ;
218+ type G2Affine = G2Affine < P > ;
219+ type G2Prepared = G2Prepared < P > ;
220+ type TargetField = Fp12 < P :: Fp12Config > ;
221+
222+ fn multi_miller_loop (
223+ a : impl IntoIterator < Item = impl Into < Self :: G1Prepared > > ,
224+ b : impl IntoIterator < Item = impl Into < Self :: G2Prepared > > ,
225+ ) -> MillerLoopOutput < Self > {
226+ P :: multi_miller_loop ( a, b)
227+ }
228+
229+ fn final_exponentiation ( f : MillerLoopOutput < Self > ) -> Option < PairingOutput < Self > > {
230+ P :: final_exponentiation ( f)
231+ }
232+ }
0 commit comments