1use crate::{
3 impl_traits,
4 provider::{
5 msm::{msm, msm_small, msm_small_with_max_num_bits},
6 traits::{DlogGroup, DlogGroupExt, PairingGroup},
7 },
8 traits::{Group, PrimeFieldExt, TranscriptReprTrait},
9};
10use digest::{ExtendableOutput, Update};
11use ff::{Field, FromUniformBytes};
12use halo2curves::{
13 bn256::{Bn256, G1Affine as Bn256Affine, G2Affine, G2Compressed, Gt, G1 as Bn256Point, G2},
14 group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup},
15 grumpkin::{G1Affine as GrumpkinAffine, G1 as GrumpkinPoint},
16 pairing::Engine as H2CEngine,
17 CurveAffine, CurveExt,
18};
19use num_bigint::BigInt;
20use num_integer::Integer;
21use num_traits::{Num, ToPrimitive};
22use rayon::prelude::*;
23use sha3::Shake256;
24
25pub mod bn256 {
27 pub use halo2curves::bn256::{Fq as Base, Fr as Scalar, G1Affine as Affine, G1 as Point};
28}
29
30pub mod grumpkin {
32 pub use halo2curves::grumpkin::{Fq as Base, Fr as Scalar, G1Affine as Affine, G1 as Point};
33}
34
35crate::impl_traits_no_dlog_ext!(
36 bn256,
37 Bn256Point,
38 Bn256Affine,
39 "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
40 "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
41);
42
43impl DlogGroupExt for bn256::Point {
44 #[cfg(not(feature = "blitzar"))]
45 fn vartime_multiscalar_mul(scalars: &[Self::Scalar], bases: &[Self::AffineGroupElement]) -> Self {
46 msm(scalars, bases)
47 }
48
49 fn vartime_multiscalar_mul_small<T: Integer + Into<u64> + Copy + Sync + ToPrimitive>(
50 scalars: &[T],
51 bases: &[Self::AffineGroupElement],
52 ) -> Self {
53 msm_small(scalars, bases)
54 }
55
56 fn vartime_multiscalar_mul_small_with_max_num_bits<
57 T: Integer + Into<u64> + Copy + Sync + ToPrimitive,
58 >(
59 scalars: &[T],
60 bases: &[Self::AffineGroupElement],
61 max_num_bits: usize,
62 ) -> Self {
63 msm_small_with_max_num_bits(scalars, bases, max_num_bits)
64 }
65
66 #[cfg(feature = "blitzar")]
67 fn vartime_multiscalar_mul(scalars: &[Self::Scalar], bases: &[Self::AffineGroupElement]) -> Self {
68 super::blitzar::vartime_multiscalar_mul(scalars, bases)
69 }
70
71 #[cfg(feature = "blitzar")]
72 fn batch_vartime_multiscalar_mul(
73 scalars: &[Vec<Self::Scalar>],
74 bases: &[Self::AffineGroupElement],
75 ) -> Vec<Self> {
76 super::blitzar::batch_vartime_multiscalar_mul(scalars, bases)
77 }
78}
79
80impl_traits!(
81 grumpkin,
82 GrumpkinPoint,
83 GrumpkinAffine,
84 "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
85 "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"
86);
87
88impl PairingGroup for Bn256Point {
89 type G2 = G2;
90 type GT = Gt;
91
92 fn pairing(p: &Self, q: &Self::G2) -> Self::GT {
93 <Bn256 as H2CEngine>::pairing(&p.affine(), &q.affine())
94 }
95}
96
97impl Group for G2 {
98 type Base = bn256::Base;
99 type Scalar = bn256::Scalar;
100
101 fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt) {
102 let A = bn256::Base::ZERO; let B = bn256::Base::from(3u64); let order = BigInt::from_str_radix(
109 "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
110 16,
111 )
112 .unwrap();
113 let base = BigInt::from_str_radix(
114 "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
115 16,
116 )
117 .unwrap();
118
119 (A, B, order, base)
120 }
121}
122
123impl DlogGroup for G2 {
124 type AffineGroupElement = G2Affine;
125
126 fn affine(&self) -> Self::AffineGroupElement {
127 self.to_affine()
128 }
129
130 fn group(p: &Self::AffineGroupElement) -> Self {
131 G2::from(*p)
132 }
133
134 fn from_label(_label: &'static [u8], _n: usize) -> Vec<Self::AffineGroupElement> {
135 unimplemented!()
136 }
137
138 fn zero() -> Self {
139 G2::identity()
140 }
141
142 fn gen() -> Self {
143 G2::generator()
144 }
145
146 fn to_coordinates(&self) -> (Self::Base, Self::Base, bool) {
147 unimplemented!()
148 }
149}
150
151impl<G: DlogGroup> TranscriptReprTrait<G> for G2Compressed {
152 fn to_transcript_bytes(&self) -> Vec<u8> {
153 self.as_ref().to_vec()
154 }
155}
156
157impl<G: DlogGroup> TranscriptReprTrait<G> for G2Affine {
158 fn to_transcript_bytes(&self) -> Vec<u8> {
159 unimplemented!()
160 }
161}
162
163impl crate::traits::evm_serde::CustomSerdeTrait for G2Affine {
165 #[cfg(feature = "evm")]
166 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
167 use crate::traits::evm_serde::EvmCompatSerde;
168 use serde::{Deserialize, Serialize};
169 use serde_with::serde_as;
170
171 #[serde_as]
172 #[derive(Deserialize, Serialize)]
173 struct HelperBase(
174 #[serde_as(as = "EvmCompatSerde")] bn256::Base,
175 #[serde_as(as = "EvmCompatSerde")] bn256::Base,
176 );
177
178 #[derive(Deserialize, Serialize)]
179 struct HelperAffine(HelperBase, HelperBase);
180
181 let affine = HelperAffine(
182 HelperBase(*self.x.c0(), *self.x.c1()),
183 HelperBase(*self.y.c0(), *self.y.c1()),
184 );
185
186 affine.serialize(serializer)
187 }
188
189 #[cfg(feature = "evm")]
190 fn deserialize<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
191 use crate::traits::evm_serde::EvmCompatSerde;
192 use halo2curves::bn256::Fq2;
193 use serde::{Deserialize, Serialize};
194 use serde_with::serde_as;
195
196 #[serde_as]
197 #[derive(Deserialize, Serialize)]
198 struct HelperBase(
199 #[serde_as(as = "EvmCompatSerde")] bn256::Base,
200 #[serde_as(as = "EvmCompatSerde")] bn256::Base,
201 );
202
203 #[derive(Deserialize, Serialize)]
204 struct HelperAffine(HelperBase, HelperBase);
205
206 let affine = HelperAffine::deserialize(deserializer)?;
207
208 Ok(G2Affine {
209 x: Fq2::new(affine.0 .0, affine.0 .1),
210 y: Fq2::new(affine.1 .0, affine.1 .1),
211 })
212 }
213}