22
33use std:: {
44 marker:: PhantomData ,
5- ops:: { Add , Mul } ,
5+ ops:: { Add , Mul , Neg } ,
66} ;
77
88use crate :: {
@@ -21,7 +21,11 @@ use ethers_core::k256::elliptic_curve::subtle::CtOption;
2121use gadgets:: impl_expr;
2222use halo2_proofs:: {
2323 arithmetic:: { CurveAffine , Field } ,
24- halo2curves:: bn256:: { Fq , Fq2 , Fr , G1Affine , G2Affine } ,
24+ circuit:: Value ,
25+ halo2curves:: {
26+ bn256:: { Fq , Fq2 , Fr , G1Affine , G2Affine } ,
27+ group:: prime:: PrimeCurveAffine ,
28+ } ,
2529 plonk:: Expression ,
2630} ;
2731
@@ -1175,6 +1179,28 @@ impl EcPairingPair {
11751179 . collect ( )
11761180 }
11771181
1182+ /// ...
1183+ pub fn to_g1_affine_tuple ( & self ) -> ( Value < Fq > , Value < Fq > ) {
1184+ (
1185+ Value :: known ( Fq :: from_bytes ( & self . g1_point . 0 . to_le_bytes ( ) ) . unwrap ( ) ) ,
1186+ Value :: known ( Fq :: from_bytes ( & self . g1_point . 1 . to_le_bytes ( ) ) . unwrap ( ) ) ,
1187+ )
1188+ }
1189+
1190+ /// ...
1191+ pub fn to_g2_affine_tuple ( & self ) -> ( Value < Fq2 > , Value < Fq2 > ) {
1192+ (
1193+ Value :: known ( Fq2 {
1194+ c0 : Fq :: from_bytes ( & self . g2_point . 1 . to_le_bytes ( ) ) . unwrap ( ) ,
1195+ c1 : Fq :: from_bytes ( & self . g2_point . 0 . to_le_bytes ( ) ) . unwrap ( ) ,
1196+ } ) ,
1197+ Value :: known ( Fq2 {
1198+ c0 : Fq :: from_bytes ( & self . g2_point . 3 . to_le_bytes ( ) ) . unwrap ( ) ,
1199+ c1 : Fq :: from_bytes ( & self . g2_point . 2 . to_le_bytes ( ) ) . unwrap ( ) ,
1200+ } ) ,
1201+ )
1202+ }
1203+
11781204 /// Returns the big-endian representation of the G2 point in the pair.
11791205 pub fn g2_bytes_be ( & self ) -> Vec < u8 > {
11801206 std:: iter:: empty ( )
@@ -1199,69 +1225,16 @@ impl EcPairingPair {
11991225 . collect ( )
12001226 }
12011227
1202- /// Padding pair for ECC circuit. The pairing check is done with a constant number
1203- /// `N_PAIRING_PER_OP` of (G1, G2) pairs. The ECC circuit under the hood uses halo2-lib to
1204- /// compute the multi-miller loop, which allows `(G1::Infinity, G2::Generator)` pair to skip
1205- /// the loop for that pair. So in case the EVM inputs are less than `N_PAIRING_PER_OP` we pad
1206- /// the ECC Circuit inputs by this pair. Any EVM input of `(G1::Infinity, G2)` or
1207- /// `(G1, G2::Infinity)` is also transformed into `(G1::Infinity, G2::Generator)`.
1208- pub fn ecc_padding ( ) -> Self {
1209- Self {
1210- g1_point : ( U256 :: zero ( ) , U256 :: zero ( ) ) ,
1211- g2_point : (
1212- U256 ( [
1213- 0x97e485b7aef312c2 ,
1214- 0xf1aa493335a9e712 ,
1215- 0x7260bfb731fb5d25 ,
1216- 0x198e9393920d483a ,
1217- ] ) ,
1218- U256 ( [
1219- 0x46debd5cd992f6ed ,
1220- 0x674322d4f75edadd ,
1221- 0x426a00665e5c4479 ,
1222- 0x1800deef121f1e76 ,
1223- ] ) ,
1224- U256 ( [
1225- 0x55acdadcd122975b ,
1226- 0xbc4b313370b38ef3 ,
1227- 0xec9e99ad690c3395 ,
1228- 0x090689d0585ff075 ,
1229- ] ) ,
1230- U256 ( [
1231- 0x4ce6cc0166fa7daa ,
1232- 0xe3d1e7690c43d37b ,
1233- 0x4aab71808dcb408f ,
1234- 0x12c85ea5db8c6deb ,
1235- ] ) ,
1236- ) ,
1237- }
1238- }
1239-
1240- /// Padding pair for EVM circuit. The pairing check is done with a constant number
1228+ /// Padding pair for EcPairing operation. The pairing check is done with a constant number
12411229 /// `N_PAIRING_PER_OP` of (G1, G2) pairs. In case EVM inputs are less in number, we pad them
12421230 /// with `(G1::Infinity, G2::Infinity)` for simplicity.
1243- pub fn evm_padding ( ) -> Self {
1231+ pub fn padding_pair ( ) -> Self {
12441232 Self {
12451233 g1_point : ( U256 :: zero ( ) , U256 :: zero ( ) ) ,
12461234 g2_point : ( U256 :: zero ( ) , U256 :: zero ( ) , U256 :: zero ( ) , U256 :: zero ( ) ) ,
12471235 }
12481236 }
12491237
1250- /// Whether or not we swap the EVM pair with ECC pair. We do this iff:
1251- /// - G1 is (0, 0)
1252- /// - G2 is (0, 0, 0, 0)
1253- ///
1254- /// because for the above case, we have:
1255- /// - (G1::identity, G2::identity) as inputs from the EVM.
1256- /// - (G1::identity, G2::generator) as inputs to ECC Circuit.
1257- pub fn swap ( & self ) -> bool {
1258- ( self . g1_point . 0 . is_zero ( ) && self . g1_point . 1 . is_zero ( ) )
1259- && ( self . g2_point . 0 . is_zero ( )
1260- && self . g2_point . 1 . is_zero ( )
1261- && self . g2_point . 2 . is_zero ( )
1262- && self . g2_point . 3 . is_zero ( ) )
1263- }
1264-
12651238 fn is_valid ( & self ) -> bool {
12661239 let fq_from_u256 = |buf : & mut [ u8 ; 32 ] , u256 : U256 | -> CtOption < Fq > {
12671240 u256. to_little_endian ( buf) ;
@@ -1353,6 +1326,24 @@ impl EcPairingOp {
13531326 pub fn is_valid ( & self ) -> bool {
13541327 self . pairs . iter ( ) . all ( |pair| pair. is_valid ( ) )
13551328 }
1329+
1330+ /// Dummy pairing op that satisfies the pairing check.
1331+ pub fn dummy_pairing_check_ok ( ) -> Self {
1332+ let g1 = G1Affine :: from ( G1Affine :: generator ( ) * Fr :: from ( 2 ) ) ;
1333+ let g1_neg = g1. neg ( ) ;
1334+ let g2 = G2Affine :: from ( G2Affine :: generator ( ) * Fr :: from ( 3 ) ) ;
1335+ let other_g1 = G1Affine :: from ( G1Affine :: generator ( ) * Fr :: from ( 6 ) ) ;
1336+ let other_g2 = G2Affine :: generator ( ) ;
1337+ Self {
1338+ pairs : [
1339+ EcPairingPair :: new ( g1_neg, g2) ,
1340+ EcPairingPair :: new ( other_g1, other_g2) ,
1341+ EcPairingPair :: new ( G1Affine :: identity ( ) , G2Affine :: generator ( ) ) ,
1342+ EcPairingPair :: new ( G1Affine :: identity ( ) , G2Affine :: generator ( ) ) ,
1343+ ] ,
1344+ output : 1 . into ( ) ,
1345+ }
1346+ }
13561347}
13571348
13581349/// Event representating an exponentiation `a ^ b == d (mod m)` in precompile modexp.
0 commit comments