@@ -5,15 +5,17 @@ use subtle::{Choice, ConditionallySelectable};
55
66use blst:: * ;
77
8- /// Execute a complete pairing operation `(p, q)`.
9- pub fn pairing ( p : & G1Affine , q : & G2Affine ) -> Gt {
8+ /// Execute a Miller loop operation `(p, q)`, which is the first part of the
9+ /// full [`pairing`] operation.
10+ pub fn miller_loop ( p : & G1Affine , q : & G2Affine ) -> MillerLoopResult {
1011 let mut tmp = blst_fp12:: default ( ) ;
1112 unsafe { blst_miller_loop ( & mut tmp, & q. 0 , & p. 0 ) } ;
13+ MillerLoopResult ( Fp12 ( tmp) )
14+ }
1215
13- let mut out = blst_fp12:: default ( ) ;
14- unsafe { blst_final_exp ( & mut out, & tmp) } ;
15-
16- Gt ( Fp12 ( out) )
16+ /// Execute a complete pairing operation `(p, q)`.
17+ pub fn pairing ( p : & G1Affine , q : & G2Affine ) -> Gt {
18+ miller_loop ( p, q) . final_exponentiation ( )
1719}
1820
1921macro_rules! impl_pairing {
@@ -146,12 +148,38 @@ pub fn unique_messages(msgs: &[&[u8]]) -> bool {
146148}
147149
148150/// Represents results of a Miller loop, one of the most expensive portions
149- /// of the pairing function. `MillerLoopResult`s cannot be compared with each
150- /// other until `.final_exponentiation()` is called, which is also expensive.
151- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
151+ /// of the pairing function.
152+ ///
153+ /// `MillerLoopResult`s can't be compared together numerically for equality. However, two
154+ /// `MillerLoopResult`s can be compared with [`MillerLoopResult::final_verify`], which is
155+ /// faster than performing [`MillerLoopResult::final_exponentiation`] on both and then comparing
156+ /// the results.
157+ #[ derive( Copy , Clone , Debug ) ]
152158#[ repr( transparent) ]
153159pub struct MillerLoopResult ( pub ( crate ) Fp12 ) ;
154160
161+ impl MillerLoopResult {
162+ /// Perform the final exponentiation to convert the Miller loop result
163+ /// into a full pairing result.
164+ pub fn final_exponentiation ( & self ) -> Gt {
165+ let mut out = blst_fp12:: default ( ) ;
166+ unsafe { blst_final_exp ( & mut out, & self . 0 . 0 ) } ;
167+ Gt ( Fp12 ( out) )
168+ }
169+
170+ pub fn final_verify ( & self , other : & MillerLoopResult ) -> bool {
171+ unsafe { blst:: blst_fp12_finalverify ( & self . 0 . 0 , & other. 0 . 0 ) }
172+ }
173+ }
174+
175+ impl PartialEq for MillerLoopResult {
176+ fn eq ( & self , other : & Self ) -> bool {
177+ self . final_verify ( other)
178+ }
179+ }
180+
181+ impl Eq for MillerLoopResult { }
182+
155183impl ConditionallySelectable for MillerLoopResult {
156184 fn conditional_select ( a : & Self , b : & Self , choice : Choice ) -> Self {
157185 MillerLoopResult ( Fp12 :: conditional_select ( & a. 0 , & b. 0 , choice) )
0 commit comments