@@ -1060,53 +1060,117 @@ impl EcMulOp {
1060
1060
/// call are < 4, we append (G1::infinity, G2::generator) until we have the required no. of inputs.
1061
1061
pub const N_PAIRING_PER_OP : usize = 4 ;
1062
1062
1063
+ /// The number of bytes taken to represent a pair (G1, G2).
1064
+ pub const N_BYTES_PER_PAIR : usize = 192 ;
1065
+
1066
+ /// Pair of (G1, G2).
1067
+ #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
1068
+ pub struct EcPairingPair {
1069
+ /// G1 point.
1070
+ pub g1_point : G1Affine ,
1071
+ /// G2 point.
1072
+ pub g2_point : G2Affine ,
1073
+ }
1074
+
1075
+ impl EcPairingPair {
1076
+ /// Returns the big-endian representation of the G1 point in the pair.
1077
+ pub fn g1_bytes_be ( & self ) -> Vec < u8 > {
1078
+ std:: iter:: empty ( )
1079
+ . chain ( self . g1_point . x . to_bytes ( ) . iter ( ) . rev ( ) )
1080
+ . chain ( self . g1_point . y . to_bytes ( ) . iter ( ) . rev ( ) )
1081
+ . cloned ( )
1082
+ . collect ( )
1083
+ }
1084
+
1085
+ /// Returns the big-endian representation of the G2 point in the pair.
1086
+ pub fn g2_bytes_be ( & self ) -> Vec < u8 > {
1087
+ std:: iter:: empty ( )
1088
+ . chain ( self . g2_point . x . c0 . to_bytes ( ) . iter ( ) . rev ( ) )
1089
+ . chain ( self . g2_point . x . c1 . to_bytes ( ) . iter ( ) . rev ( ) )
1090
+ . chain ( self . g2_point . y . c0 . to_bytes ( ) . iter ( ) . rev ( ) )
1091
+ . chain ( self . g2_point . y . c1 . to_bytes ( ) . iter ( ) . rev ( ) )
1092
+ . cloned ( )
1093
+ . collect ( )
1094
+ }
1095
+
1096
+ /// Returns the uncompressed big-endian byte representation of the (G1, G2) pair.
1097
+ pub fn to_bytes_be ( & self ) -> Vec < u8 > {
1098
+ std:: iter:: empty ( )
1099
+ . chain ( self . g1_point . x . to_bytes ( ) . iter ( ) . rev ( ) )
1100
+ . chain ( self . g1_point . y . to_bytes ( ) . iter ( ) . rev ( ) )
1101
+ . chain ( self . g2_point . x . c0 . to_bytes ( ) . iter ( ) . rev ( ) )
1102
+ . chain ( self . g2_point . x . c1 . to_bytes ( ) . iter ( ) . rev ( ) )
1103
+ . chain ( self . g2_point . y . c0 . to_bytes ( ) . iter ( ) . rev ( ) )
1104
+ . chain ( self . g2_point . y . c1 . to_bytes ( ) . iter ( ) . rev ( ) )
1105
+ . cloned ( )
1106
+ . collect ( )
1107
+ }
1108
+
1109
+ /// Create a new pair.
1110
+ pub fn new ( g1_point : G1Affine , g2_point : G2Affine ) -> Self {
1111
+ Self { g1_point, g2_point }
1112
+ }
1113
+
1114
+ /// Padding pair for ECC circuit. The pairing check is done with a constant number
1115
+ /// `N_PAIRING_PER_OP` of (G1, G2) pairs. The ECC circuit under the hood uses halo2-lib to
1116
+ /// compute the multi-miller loop, which allows `(G1::Infinity, G2::Generator)` pair to skip
1117
+ /// the loop for that pair. So in case the EVM inputs are less than `N_PAIRING_PER_OP` we pad
1118
+ /// the ECC Circuit inputs by this pair. Any EVM input of `(G1::Infinity, G2)` or
1119
+ /// `(G1, G2::Infinity)` is also transformed into `(G1::Infinity, G2::Generator)`.
1120
+ pub fn ecc_padding ( ) -> Self {
1121
+ Self {
1122
+ g1_point : G1Affine :: identity ( ) ,
1123
+ g2_point : G2Affine :: generator ( ) ,
1124
+ }
1125
+ }
1126
+
1127
+ /// Padding pair for EVM circuit. The pairing check is done with a constant number
1128
+ /// `N_PAIRING_PER_OP` of (G1, G2) pairs. In case EVM inputs are less in number, we pad them
1129
+ /// with `(G1::Infinity, G2::Infinity)` for simplicity.
1130
+ pub fn evm_padding ( ) -> Self {
1131
+ Self {
1132
+ g1_point : G1Affine :: identity ( ) ,
1133
+ g2_point : G2Affine :: identity ( ) ,
1134
+ }
1135
+ }
1136
+ }
1137
+
1063
1138
/// EcPairing operation
1064
- #[ derive( Clone , Debug ) ]
1139
+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
1065
1140
pub struct EcPairingOp {
1066
- /// tuples of G1 and G2 points.
1067
- pub inputs : [ ( G1Affine , G2Affine ) ; N_PAIRING_PER_OP ] ,
1141
+ /// tuples of G1 and G2 points supplied to the ECC circuit .
1142
+ pub pairs : [ EcPairingPair ; N_PAIRING_PER_OP ] ,
1068
1143
/// Result from the pairing check.
1069
1144
pub output : Word ,
1070
1145
}
1071
1146
1072
1147
impl Default for EcPairingOp {
1073
1148
fn default ( ) -> Self {
1149
+ let g1_point = G1Affine :: generator ( ) ;
1150
+ let g2_point = G2Affine :: generator ( ) ;
1074
1151
Self {
1075
- inputs : [
1076
- ( G1Affine :: generator ( ) , G2Affine :: generator ( ) ) ,
1077
- ( G1Affine :: identity ( ) , G2Affine :: generator ( ) ) ,
1078
- ( G1Affine :: identity ( ) , G2Affine :: generator ( ) ) ,
1079
- ( G1Affine :: identity ( ) , G2Affine :: generator ( ) ) ,
1152
+ pairs : [
1153
+ EcPairingPair { g1_point , g2_point } ,
1154
+ EcPairingPair { g1_point , g2_point } ,
1155
+ EcPairingPair { g1_point , g2_point } ,
1156
+ EcPairingPair { g1_point , g2_point } ,
1080
1157
] ,
1081
1158
output : Word :: zero ( ) ,
1082
1159
}
1083
1160
}
1084
1161
}
1085
1162
1086
1163
impl EcPairingOp {
1087
- /// Returns the uncompressed little -endian byte representation of inputs to the EcPairingOp.
1088
- pub fn to_bytes_le ( & self ) -> Vec < u8 > {
1089
- self . inputs
1164
+ /// Returns the uncompressed big -endian byte representation of inputs to the EcPairingOp.
1165
+ pub fn to_bytes_be ( & self ) -> Vec < u8 > {
1166
+ self . pairs
1090
1167
. iter ( )
1091
- . flat_map ( |i| {
1092
- std:: iter:: empty ( )
1093
- . chain ( i. 0 . x . to_bytes ( ) . iter ( ) )
1094
- . chain ( i. 0 . y . to_bytes ( ) . iter ( ) )
1095
- . chain ( i. 1 . x . c0 . to_bytes ( ) . iter ( ) )
1096
- . chain ( i. 1 . x . c1 . to_bytes ( ) . iter ( ) )
1097
- . chain ( i. 1 . y . c0 . to_bytes ( ) . iter ( ) )
1098
- . chain ( i. 1 . y . c1 . to_bytes ( ) . iter ( ) )
1099
- . cloned ( )
1100
- . collect :: < Vec < u8 > > ( )
1101
- } )
1168
+ . flat_map ( |pair| pair. to_bytes_be ( ) )
1102
1169
. collect :: < Vec < u8 > > ( )
1103
1170
}
1104
1171
1105
1172
/// A check on the op to tell the ECC Circuit whether or not to skip the op.
1106
1173
pub fn skip_by_ecc_circuit ( & self ) -> bool {
1107
- self . inputs [ 0 ] . 0 . is_identity ( ) . into ( )
1108
- && self . inputs [ 1 ] . 0 . is_identity ( ) . into ( )
1109
- && self . inputs [ 2 ] . 0 . is_identity ( ) . into ( )
1110
- && self . inputs [ 3 ] . 0 . is_identity ( ) . into ( )
1174
+ false
1111
1175
}
1112
1176
}
0 commit comments