1use ark_bls12_381::{
6 Bls12_381, Fq as bls12_381_fq, Fq2 as bls12_381_Fq2, Fr as bls12_381_Fr,
7 G1Affine as bls12_381_G1Affine, G2Affine as bls12_381_G2Affine,
8};
9use ark_bn254::{
10 Bn254, Fq as bn254_Fq, Fq2 as bn254_Fq2, Fr as bn254_Fr, G1Affine as bn254_G1Affine,
11 G2Affine as bn254_G2Affine,
12};
13use ark_ec::AffineRepr;
14use ark_ff::{BigInteger, PrimeField};
15use ark_serialize::CanonicalDeserialize;
16use num::BigUint;
17use num_traits::Zero;
18use serde::{Deserialize, Serialize};
19
20pub const PROTOCOL_GROTH16: &str = "groth16";
21pub const CURVE_BN254: &str = "bn128";
22pub const CURVE_BLS12_381: &str = "bls12381";
23
24pub struct Inputs(pub Vec<BigUint>);
25
26impl From<&[bn254_Fr]> for Inputs {
27 fn from(src: &[bn254_Fr]) -> Self {
28 let els = src.iter().map(|point| point_to_biguint(*point)).collect();
29 Self(els)
30 }
31}
32
33impl From<&[bls12_381_Fr]> for Inputs {
34 fn from(src: &[bls12_381_Fr]) -> Self {
35 let els = src.iter().map(|point| point_to_biguint(*point)).collect();
36 Self(els)
37 }
38}
39
40impl From<Inputs> for Vec<bn254_Fr> {
41 fn from(inputs: Inputs) -> Self {
42 inputs
43 .0
44 .iter()
45 .map(|biguint| biguint_to_point(biguint.clone()))
46 .collect()
47 }
48}
49
50impl From<Inputs> for Vec<bls12_381_Fr> {
51 fn from(inputs: Inputs) -> Self {
52 inputs
53 .0
54 .iter()
55 .map(|biguint| biguint_to_point(biguint.clone()))
56 .collect()
57 }
58}
59
60#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
62pub struct G1 {
63 pub x: BigUint,
64 pub y: BigUint,
65 pub z: BigUint,
66}
67
68type G1Tup = (BigUint, BigUint, BigUint);
69
70impl G1 {
71 pub fn as_tuple(&self) -> (BigUint, BigUint, BigUint) {
72 (self.x.clone(), self.y.clone(), self.z.clone())
73 }
74
75 pub fn to_bn254(self) -> bn254_G1Affine {
77 let x: bn254_Fq = biguint_to_point(self.x);
78 let y: bn254_Fq = biguint_to_point(self.y);
79 if x.is_zero() && y.is_zero() {
80 bn254_G1Affine::identity()
81 } else {
82 bn254_G1Affine::new(x, y)
83 }
84 }
85
86 pub fn from_bn254(p: &bn254_G1Affine) -> Self {
87 let p_z = p.into_group();
88 Self {
89 x: point_to_biguint(p.x),
90 y: point_to_biguint(p.y),
91 z: point_to_biguint(p_z.z),
92 }
93 }
94
95 pub fn to_bls12_381(self) -> bls12_381_G1Affine {
97 let x: bls12_381_fq = biguint_to_point(self.x);
98 let y: bls12_381_fq = biguint_to_point(self.y);
99 if x.is_zero() && y.is_zero() {
100 bls12_381_G1Affine::identity()
101 } else {
102 bls12_381_G1Affine::new(x, y)
103 }
104 }
105
106 pub fn from_bls12_381(p: &bls12_381_G1Affine) -> Self {
107 let p_z = p.into_group();
108 Self {
109 x: point_to_biguint(p.x),
110 y: point_to_biguint(p.y),
111 z: point_to_biguint(p_z.z),
112 }
113 }
114}
115
116#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
117pub struct G2 {
118 pub x: [BigUint; 2],
119 pub y: [BigUint; 2],
120 pub z: [BigUint; 2],
121}
122
123type G2Tup = ([BigUint; 2], [BigUint; 2], [BigUint; 2]);
124
125impl G2 {
126 pub fn as_tuple(&self) -> G2Tup {
128 (
129 [self.x[1].clone(), self.x[0].clone()],
130 [self.y[1].clone(), self.y[0].clone()],
131 [self.z[1].clone(), self.z[0].clone()],
132 )
133 }
134
135 pub fn to_bn254(self) -> bn254_G2Affine {
137 let c0 = biguint_to_point(self.x[0].clone());
138 let c1 = biguint_to_point(self.x[1].clone());
139 let x = bn254_Fq2::new(c0, c1);
140
141 let c0 = biguint_to_point(self.y[0].clone());
142 let c1 = biguint_to_point(self.y[1].clone());
143 let y = bn254_Fq2::new(c0, c1);
144
145 if x.is_zero() && y.is_zero() {
146 bn254_G2Affine::identity()
147 } else {
148 bn254_G2Affine::new(x, y)
149 }
150 }
151
152 pub fn from_bn254(p: &bn254_G2Affine) -> Self {
153 let p_z = p.into_group();
154 Self {
155 x: [point_to_biguint(p.x.c0), point_to_biguint(p.x.c1)],
156 y: [point_to_biguint(p.y.c0), point_to_biguint(p.y.c1)],
157 z: [point_to_biguint(p_z.z.c0), point_to_biguint(p_z.z.c1)],
158 }
159 }
160
161 pub fn to_bls12_381(self) -> bls12_381_G2Affine {
163 let c0 = biguint_to_point(self.x[0].clone());
164 let c1 = biguint_to_point(self.x[1].clone());
165 let x = bls12_381_Fq2::new(c0, c1);
166
167 let c0 = biguint_to_point(self.y[0].clone());
168 let c1 = biguint_to_point(self.y[1].clone());
169 let y = bls12_381_Fq2::new(c0, c1);
170
171 if x.is_zero() && y.is_zero() {
172 bls12_381_G2Affine::identity()
173 } else {
174 bls12_381_G2Affine::new(x, y)
175 }
176 }
177
178 pub fn from_bls12_381(p: &bls12_381_G2Affine) -> Self {
179 let p_z = p.into_group();
180 Self {
181 x: [point_to_biguint(p.x.c0), point_to_biguint(p.x.c1)],
182 y: [point_to_biguint(p.y.c0), point_to_biguint(p.y.c1)],
183 z: [point_to_biguint(p_z.z.c0), point_to_biguint(p_z.z.c1)],
184 }
185 }
186}
187
188#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
189pub struct Proof {
190 pub a: G1,
191 pub b: G2,
192 pub c: G1,
193 pub protocol: String,
194 pub curve: String,
195}
196
197impl Proof {
198 pub fn as_tuple(&self) -> (G1Tup, G2Tup, G1Tup) {
199 (self.a.as_tuple(), self.b.as_tuple(), self.c.as_tuple())
200 }
201}
202
203impl From<ark_groth16::Proof<Bn254>> for Proof {
204 fn from(proof: ark_groth16::Proof<Bn254>) -> Self {
205 Self {
206 a: G1::from_bn254(&proof.a),
207 b: G2::from_bn254(&proof.b),
208 c: G1::from_bn254(&proof.c),
209 protocol: PROTOCOL_GROTH16.to_string(),
210 curve: CURVE_BN254.to_string(),
211 }
212 }
213}
214
215impl From<ark_groth16::Proof<Bls12_381>> for Proof {
216 fn from(proof: ark_groth16::Proof<Bls12_381>) -> Self {
217 Self {
218 a: G1::from_bls12_381(&proof.a),
219 b: G2::from_bls12_381(&proof.b),
220 c: G1::from_bls12_381(&proof.c),
221 protocol: PROTOCOL_GROTH16.to_string(),
222 curve: CURVE_BLS12_381.to_string(),
223 }
224 }
225}
226
227impl From<Proof> for ark_groth16::Proof<Bn254> {
228 fn from(src: Proof) -> Self {
229 ark_groth16::Proof {
230 a: src.a.to_bn254(),
231 b: src.b.to_bn254(),
232 c: src.c.to_bn254(),
233 }
234 }
235}
236
237impl From<Proof> for ark_groth16::Proof<Bls12_381> {
238 fn from(src: Proof) -> Self {
239 ark_groth16::Proof {
240 a: src.a.to_bls12_381(),
241 b: src.b.to_bls12_381(),
242 c: src.c.to_bls12_381(),
243 }
244 }
245}
246
247fn biguint_to_point<F: PrimeField>(point: BigUint) -> F {
249 let buf_size: usize = F::MODULUS_BIT_SIZE.div_ceil(8).try_into().unwrap(); let mut buf = point.to_bytes_le();
251 buf.resize(buf_size, 0u8);
252 let bigint = F::BigInt::deserialize_uncompressed(&buf[..]).expect("always works");
253 F::from_bigint(bigint).expect("always works")
254}
255
256fn point_to_biguint<F: PrimeField>(point: F) -> BigUint {
259 let point = point.into_bigint();
260 let point_bytes = point.to_bytes_be();
261 BigUint::from_bytes_be(&point_bytes[..])
262}
263
264#[cfg(test)]
265mod tests {
266 use crate::prover::circom::{biguint_to_point, point_to_biguint, Inputs, Proof, G1, G2};
267 use num::BigUint;
268
269 mod bn254 {
270 use super::*;
271 use ark_bn254::{Bn254, Fq, Fr, G1Affine, G2Affine};
272 use ark_std::UniformRand;
273
274 fn fq() -> Fq {
275 Fq::from(2)
276 }
277
278 fn fr() -> Fr {
279 Fr::from(2)
280 }
281
282 fn g1() -> G1Affine {
283 let rng = &mut ark_std::test_rng();
284 G1Affine::rand(rng)
285 }
286
287 fn g2() -> G2Affine {
288 let rng = &mut ark_std::test_rng();
289 G2Affine::rand(rng)
290 }
291
292 #[test]
293 fn convert_fq() {
294 let el = fq();
295 let el2 = point_to_biguint(el);
296 let el3: Fq = biguint_to_point(el2.clone());
297 let el4 = point_to_biguint(el3);
298 assert_eq!(el, el3);
299 assert_eq!(el2, el4);
300 }
301
302 #[test]
303 fn convert_fr() {
304 let el = fr();
305 let el2 = point_to_biguint(el);
306 let el3: Fr = biguint_to_point(el2.clone());
307 let el4 = point_to_biguint(el3);
308 assert_eq!(el, el3);
309 assert_eq!(el2, el4);
310 }
311
312 #[test]
313 fn convert_g1() {
314 let el = g1();
315 let el2 = G1::from_bn254(&el);
316 let el3: G1Affine = el2.clone().to_bn254();
317 let el4 = G1::from_bn254(&el3);
318 assert_eq!(el, el3);
319 assert_eq!(el2, el4);
320 }
321
322 #[test]
323 fn convert_g2() {
324 let el = g2();
325 let el2 = G2::from_bn254(&el);
326 let el3: G2Affine = el2.clone().to_bn254();
327 let el4 = G2::from_bn254(&el3);
328 assert_eq!(el, el3);
329 assert_eq!(el2, el4);
330 }
331
332 #[test]
333 fn convert_proof() {
334 let p = ark_groth16::Proof::<Bn254> {
335 a: g1(),
336 b: g2(),
337 c: g1(),
338 };
339 let p2 = Proof::from(p.clone());
340 let p3 = ark_groth16::Proof::from(p2);
341 assert_eq!(p, p3);
342 }
343
344 #[test]
345 fn convert_fr_inputs_to_biguint() {
346 let bn254_1 = Fr::from(1u32);
347 let bn254_2 = Fr::from(2u32);
348 let bn254_3 = Fr::from(3u32);
349
350 let bn254_slice: &[Fr] = &[bn254_1, bn254_2, bn254_3];
351
352 let result: Inputs = bn254_slice.into();
353
354 assert_eq!(result.0.len(), 3);
355
356 assert_eq!(result.0[0], BigUint::from(1u32));
357 assert_eq!(result.0[1], BigUint::from(2u32));
358 assert_eq!(result.0[2], BigUint::from(3u32));
359 }
360
361 #[test]
362 fn convert_biguint_to_fr_inputs() {
363 let biguint1 = BigUint::from(1u32);
364 let biguint2 = BigUint::from(2u32);
365 let biguint3 = BigUint::from(3u32);
366
367 let inputs = Inputs(vec![biguint1, biguint2, biguint3]);
368
369 let result: Vec<Fr> = inputs.into();
370
371 assert_eq!(result.len(), 3);
372
373 assert_eq!(result[0], Fr::from(BigUint::from(1u32)));
374 assert_eq!(result[1], Fr::from(BigUint::from(2u32)));
375 assert_eq!(result[2], Fr::from(BigUint::from(3u32)));
376 }
377 }
378
379 mod bls12_381 {
380 use super::*;
381 use ark_bls12_381::{Bls12_381, Fq, Fr, G1Affine, G2Affine};
382 use ark_std::UniformRand;
383
384 fn fq() -> Fq {
385 Fq::from(2)
386 }
387
388 fn fr() -> Fr {
389 Fr::from(2)
390 }
391
392 fn g1() -> G1Affine {
393 let rng = &mut ark_std::test_rng();
394 G1Affine::rand(rng)
395 }
396
397 fn g2() -> G2Affine {
398 let rng = &mut ark_std::test_rng();
399 G2Affine::rand(rng)
400 }
401
402 #[test]
403 fn convert_fq() {
404 let el = fq();
405 let el2 = point_to_biguint(el);
406 let el3: Fq = biguint_to_point(el2.clone());
407 let el4 = point_to_biguint(el3);
408 assert_eq!(el, el3);
409 assert_eq!(el2, el4);
410 }
411
412 #[test]
413 fn convert_fr() {
414 let el = fr();
415 let el2 = point_to_biguint(el);
416 let el3: Fr = biguint_to_point(el2.clone());
417 let el4 = point_to_biguint(el3);
418 assert_eq!(el, el3);
419 assert_eq!(el2, el4);
420 }
421
422 #[test]
423 fn convert_g1() {
424 let el = g1();
425 let el2 = G1::from_bls12_381(&el);
426 let el3: G1Affine = el2.clone().to_bls12_381();
427 let el4 = G1::from_bls12_381(&el3);
428 assert_eq!(el, el3);
429 assert_eq!(el2, el4);
430 }
431
432 #[test]
433 fn convert_g2() {
434 let el = g2();
435 let el2 = G2::from_bls12_381(&el);
436 let el3: G2Affine = el2.clone().to_bls12_381();
437 let el4 = G2::from_bls12_381(&el3);
438 assert_eq!(el, el3);
439 assert_eq!(el2, el4);
440 }
441
442 #[test]
443 fn convert_proof() {
444 let p = ark_groth16::Proof::<Bls12_381> {
445 a: g1(),
446 b: g2(),
447 c: g1(),
448 };
449 let p2 = Proof::from(p.clone());
450 let p3 = ark_groth16::Proof::from(p2);
451 assert_eq!(p, p3);
452 }
453
454 #[test]
455 fn convert_fr_inputs_to_biguint() {
456 let bn254_1 = Fr::from(1u32);
457 let bn254_2 = Fr::from(2u32);
458 let bn254_3 = Fr::from(3u32);
459
460 let bn254_slice: &[Fr] = &[bn254_1, bn254_2, bn254_3];
461
462 let result: Inputs = bn254_slice.into();
463
464 assert_eq!(result.0.len(), 3);
465
466 assert_eq!(result.0[0], BigUint::from(1u32));
467 assert_eq!(result.0[1], BigUint::from(2u32));
468 assert_eq!(result.0[2], BigUint::from(3u32));
469 }
470
471 #[test]
472 fn convert_biguint_to_fr_inputs() {
473 let biguint1 = BigUint::from(1u32);
474 let biguint2 = BigUint::from(2u32);
475 let biguint3 = BigUint::from(3u32);
476
477 let inputs = Inputs(vec![biguint1, biguint2, biguint3]);
478
479 let result: Vec<Fr> = inputs.into();
480
481 assert_eq!(result.len(), 3);
482
483 assert_eq!(result[0], Fr::from(BigUint::from(1u32)));
484 assert_eq!(result[1], Fr::from(BigUint::from(2u32)));
485 assert_eq!(result[2], Fr::from(BigUint::from(3u32)));
486 }
487 }
488}