arnaucube
arnaucube/circom-compatPublic Self-hosted repository
circom-compat/src/zkey.rs
src/zkey.rsRaw
  1//! ZKey Parsing
  2//!
  3//! Each ZKey file is broken into sections:
  4//!  Header(1)
  5//!       Prover Type 1 Groth
  6//!  HeaderGroth(2)
  7//!       n8q
  8//!       q
  9//!       n8r
 10//!       r
 11//!       NVars
 12//!       NPub
 13//!       DomainSize  (multiple of 2
 14//!       alpha1
 15//!       beta1
 16//!       delta1
 17//!       beta2
 18//!       gamma2
 19//!       delta2
 20//!  IC(3)
 21//!  Coefs(4)
 22//!  PointsA(5)
 23//!  PointsB1(6)
 24//!  PointsB2(7)
 25//!  PointsC(8)
 26//!  PointsH(9)
 27//!  Contributions(10)
 28use ark_ff::{BigInteger256, FromBytes};
 29use ark_serialize::{CanonicalDeserialize, SerializationError};
 30use ark_std::log2;
 31use byteorder::{LittleEndian, ReadBytesExt};
 32
 33use std::{
 34    collections::HashMap,
 35    io::{Read, Result as IoResult, Seek, SeekFrom},
 36};
 37
 38use ark_bn254::{Bn254, Fq, Fq2, G1Affine, G2Affine};
 39use ark_groth16::{ProvingKey, VerifyingKey};
 40use num_traits::Zero;
 41
 42#[derive(Clone, Debug)]
 43struct Section {
 44    position: u64,
 45    size: usize,
 46}
 47
 48/// Reads a SnarkJS ZKey file into an Arkworks ProvingKey.
 49pub fn read_zkey<R: Read + Seek>(reader: &mut R) -> IoResult<ProvingKey<Bn254>> {
 50    let mut binfile = BinFile::new(reader)?;
 51    binfile.proving_key()
 52}
 53
 54#[derive(Debug)]
 55struct BinFile<'a, R> {
 56    ftype: String,
 57    version: u32,
 58    sections: HashMap<u32, Vec<Section>>,
 59    reader: &'a mut R,
 60}
 61
 62impl<'a, R: Read + Seek> BinFile<'a, R> {
 63    fn new(reader: &'a mut R) -> IoResult<Self> {
 64        let mut magic = [0u8; 4];
 65        reader.read_exact(&mut magic)?;
 66
 67        let version = reader.read_u32::<LittleEndian>()?;
 68
 69        let num_sections = reader.read_u32::<LittleEndian>()?;
 70
 71        let mut sections = HashMap::new();
 72        for _ in 0..num_sections {
 73            let section_id = reader.read_u32::<LittleEndian>()?;
 74            let section_length = reader.read_u64::<LittleEndian>()?;
 75
 76            let section = sections.entry(section_id).or_insert_with(Vec::new);
 77            section.push(Section {
 78                position: reader.stream_position()?,
 79                size: section_length as usize,
 80            });
 81
 82            reader.seek(SeekFrom::Current(section_length as i64))?;
 83        }
 84
 85        Ok(Self {
 86            ftype: std::str::from_utf8(&magic[..]).unwrap().to_string(),
 87            version,
 88            sections,
 89            reader,
 90        })
 91    }
 92
 93    fn proving_key(&mut self) -> IoResult<ProvingKey<Bn254>> {
 94        let header = self.groth_header()?;
 95        let ic = self.ic(header.n_public)?;
 96
 97        let a_query = self.a_query(header.n_vars)?;
 98        let b_g1_query = self.b_g1_query(header.n_vars)?;
 99        let b_g2_query = self.b_g2_query(header.n_vars)?;
100        let l_query = self.l_query(header.n_vars - header.n_public - 1)?;
101        let h_query = self.h_query(header.domain_size as usize)?;
102
103        let vk = VerifyingKey::<Bn254> {
104            alpha_g1: header.verifying_key.alpha_g1,
105            beta_g2: header.verifying_key.beta_g2,
106            gamma_g2: header.verifying_key.gamma_g2,
107            delta_g2: header.verifying_key.delta_g2,
108            gamma_abc_g1: ic,
109        };
110
111        let pk = ProvingKey::<Bn254> {
112            vk,
113            beta_g1: header.verifying_key.beta_g1,
114            delta_g1: header.verifying_key.delta_g1,
115            a_query,
116            b_g1_query,
117            b_g2_query,
118            h_query,
119            l_query,
120        };
121
122        Ok(pk)
123    }
124
125    fn get_section(&self, id: u32) -> Section {
126        self.sections.get(&id).unwrap()[0].clone()
127    }
128
129    fn groth_header(&mut self) -> IoResult<HeaderGroth> {
130        let section = self.get_section(2);
131        let header = HeaderGroth::new(&mut self.reader, &section)?;
132        Ok(header)
133    }
134
135    fn ic(&mut self, n_public: usize) -> IoResult<Vec<G1Affine>> {
136        // the range is non-inclusive so we do +1 to get all inputs
137        self.g1_section(n_public + 1, 3)
138    }
139
140    // Section 4 is the coefficients, we ignore it
141
142    fn a_query(&mut self, n_vars: usize) -> IoResult<Vec<G1Affine>> {
143        self.g1_section(n_vars, 5)
144    }
145
146    fn b_g1_query(&mut self, n_vars: usize) -> IoResult<Vec<G1Affine>> {
147        self.g1_section(n_vars, 6)
148    }
149
150    fn b_g2_query(&mut self, n_vars: usize) -> IoResult<Vec<G2Affine>> {
151        self.g2_section(n_vars, 7)
152    }
153
154    fn l_query(&mut self, n_vars: usize) -> IoResult<Vec<G1Affine>> {
155        self.g1_section(n_vars, 8)
156    }
157
158    fn h_query(&mut self, n_vars: usize) -> IoResult<Vec<G1Affine>> {
159        self.g1_section(n_vars, 9)
160    }
161
162    fn g1_section(&mut self, num: usize, section_id: usize) -> IoResult<Vec<G1Affine>> {
163        let section = self.get_section(section_id as u32);
164        self.reader.seek(SeekFrom::Start(section.position))?;
165        deserialize_g1_vec(self.reader, num as u32)
166    }
167
168    fn g2_section(&mut self, num: usize, section_id: usize) -> IoResult<Vec<G2Affine>> {
169        let section = self.get_section(section_id as u32);
170        self.reader.seek(SeekFrom::Start(section.position))?;
171        deserialize_g2_vec(self.reader, num as u32)
172    }
173}
174
175#[derive(Default, Clone, Debug, CanonicalDeserialize)]
176pub struct ZVerifyingKey {
177    alpha_g1: G1Affine,
178    beta_g1: G1Affine,
179    beta_g2: G2Affine,
180    gamma_g2: G2Affine,
181    delta_g1: G1Affine,
182    delta_g2: G2Affine,
183}
184
185impl ZVerifyingKey {
186    fn new<R: Read>(reader: &mut R) -> IoResult<Self> {
187        let alpha_g1 = deserialize_g1(reader)?;
188        let beta_g1 = deserialize_g1(reader)?;
189        let beta_g2 = deserialize_g2(reader)?;
190        let gamma_g2 = deserialize_g2(reader)?;
191        let delta_g1 = deserialize_g1(reader)?;
192        let delta_g2 = deserialize_g2(reader)?;
193
194        Ok(Self {
195            alpha_g1,
196            beta_g1,
197            beta_g2,
198            gamma_g2,
199            delta_g1,
200            delta_g2,
201        })
202    }
203}
204
205#[derive(Clone, Debug)]
206struct HeaderGroth {
207    n8q: u32,
208    q: BigInteger256,
209
210    n8r: u32,
211    r: BigInteger256,
212
213    n_vars: usize,
214    n_public: usize,
215
216    domain_size: u32,
217    power: u32,
218
219    verifying_key: ZVerifyingKey,
220}
221
222impl HeaderGroth {
223    fn new<R: Read + Seek>(reader: &mut R, section: &Section) -> IoResult<Self> {
224        reader.seek(SeekFrom::Start(section.position))?;
225        Self::read(reader)
226    }
227
228    fn read<R: Read>(mut reader: &mut R) -> IoResult<Self> {
229        // TODO: Impl From<u32> in Arkworks
230        let n8q: u32 = FromBytes::read(&mut reader)?;
231        // group order r of Bn254
232        let q = BigInteger256::read(&mut reader)?;
233
234        let n8r: u32 = FromBytes::read(&mut reader)?;
235        // Prime field modulus
236        let r = BigInteger256::read(&mut reader)?;
237
238        let n_vars = u32::read(&mut reader)? as usize;
239        let n_public = u32::read(&mut reader)? as usize;
240
241        let domain_size: u32 = FromBytes::read(&mut reader)?;
242        let power = log2(domain_size as usize);
243
244        let verifying_key = ZVerifyingKey::new(&mut reader)?;
245
246        Ok(Self {
247            n8q,
248            q,
249            n8r,
250            r,
251            n_vars,
252            n_public,
253            domain_size,
254            power,
255            verifying_key,
256        })
257    }
258}
259
260// skips the multiplication by R because Circom points are already in Montgomery form
261fn deserialize_field<R: Read>(reader: &mut R) -> IoResult<Fq> {
262    let bigint = BigInteger256::read(reader)?;
263    // if you use ark_ff::PrimeField::from_repr it multiplies by R
264    Ok(Fq::new(bigint))
265}
266
267pub fn deserialize_field2<R: Read>(reader: &mut R) -> IoResult<Fq2> {
268    let c0 = deserialize_field(reader)?;
269    let c1 = deserialize_field(reader)?;
270    Ok(Fq2::new(c0, c1))
271}
272
273fn deserialize_g1<R: Read>(reader: &mut R) -> IoResult<G1Affine> {
274    let x = deserialize_field(reader)?;
275    let y = deserialize_field(reader)?;
276    let infinity = x.is_zero() && y.is_zero();
277    Ok(G1Affine::new(x, y, infinity))
278}
279
280fn deserialize_g2<R: Read>(reader: &mut R) -> IoResult<G2Affine> {
281    let f1 = deserialize_field2(reader)?;
282    let f2 = deserialize_field2(reader)?;
283    let infinity = f1.is_zero() && f2.is_zero();
284    Ok(G2Affine::new(f1, f2, infinity))
285}
286
287fn deserialize_g1_vec<R: Read>(reader: &mut R, n_vars: u32) -> IoResult<Vec<G1Affine>> {
288    (0..n_vars).map(|_| deserialize_g1(reader)).collect()
289}
290
291fn deserialize_g2_vec<R: Read>(reader: &mut R, n_vars: u32) -> IoResult<Vec<G2Affine>> {
292    (0..n_vars).map(|_| deserialize_g2(reader)).collect()
293}
294
295#[cfg(test)]
296mod tests {
297    use super::*;
298    use ark_bn254::{G1Projective, G2Projective};
299    use num_bigint::BigUint;
300    use serde_json::Value;
301    use std::fs::File;
302
303    use crate::{circom::CircomReduction, CircomBuilder, CircomConfig};
304    use ark_groth16::{
305        create_random_proof_with_reduction as prove, prepare_verifying_key, verify_proof,
306    };
307    use ark_std::rand::thread_rng;
308    use num_traits::{One, Zero};
309    use std::str::FromStr;
310
311    use std::convert::TryFrom;
312
313    fn fq_from_str(s: &str) -> Fq {
314        BigInteger256::try_from(BigUint::from_str(s).unwrap())
315            .unwrap()
316            .into()
317    }
318
319    // Circom snarkjs code:
320    // console.log(curve.G1.F.one)
321    fn fq_buf() -> Vec<u8> {
322        vec![
323            157, 13, 143, 197, 141, 67, 93, 211, 61, 11, 199, 245, 40, 235, 120, 10, 44, 70, 121,
324            120, 111, 163, 110, 102, 47, 223, 7, 154, 193, 119, 10, 14,
325        ]
326    }
327
328    // Circom snarkjs code:
329    // const buff = new Uint8Array(curve.G1.F.n8*2);
330    // curve.G1.toRprLEM(buff, 0, curve.G1.one);
331    // console.dir( buff, { 'maxArrayLength': null })
332    fn g1_buf() -> Vec<u8> {
333        vec![
334            157, 13, 143, 197, 141, 67, 93, 211, 61, 11, 199, 245, 40, 235, 120, 10, 44, 70, 121,
335            120, 111, 163, 110, 102, 47, 223, 7, 154, 193, 119, 10, 14, 58, 27, 30, 139, 27, 135,
336            186, 166, 123, 22, 142, 235, 81, 214, 241, 20, 88, 140, 242, 240, 222, 70, 221, 204,
337            94, 190, 15, 52, 131, 239, 20, 28,
338        ]
339    }
340
341    // Circom snarkjs code:
342    // const buff = new Uint8Array(curve.G2.F.n8*2);
343    // curve.G2.toRprLEM(buff, 0, curve.G2.one);
344    // console.dir( buff, { 'maxArrayLength': null })
345    fn g2_buf() -> Vec<u8> {
346        vec![
347            38, 32, 188, 2, 209, 181, 131, 142, 114, 1, 123, 73, 53, 25, 235, 220, 223, 26, 129,
348            151, 71, 38, 184, 251, 59, 80, 150, 175, 65, 56, 87, 25, 64, 97, 76, 168, 125, 115,
349            180, 175, 196, 216, 2, 88, 90, 221, 67, 96, 134, 47, 160, 82, 252, 80, 233, 9, 107,
350            123, 234, 58, 131, 240, 254, 20, 246, 233, 107, 136, 157, 250, 157, 97, 120, 155, 158,
351            245, 151, 210, 127, 254, 254, 125, 27, 35, 98, 26, 158, 255, 6, 66, 158, 174, 235, 126,
352            253, 40, 238, 86, 24, 199, 86, 91, 9, 100, 187, 60, 125, 50, 34, 249, 87, 220, 118, 16,
353            53, 51, 190, 53, 249, 85, 130, 100, 253, 147, 230, 160, 164, 13,
354        ]
355    }
356
357    // Circom logs in Projective coordinates: console.log(curve.G1.one)
358    fn g1_one() -> G1Affine {
359        let x = Fq::one();
360        let y = Fq::one() + Fq::one();
361        let z = Fq::one();
362        G1Affine::from(G1Projective::new(x, y, z))
363    }
364
365    // Circom logs in Projective coordinates: console.log(curve.G2.one)
366    fn g2_one() -> G2Affine {
367        let x = Fq2::new(
368            fq_from_str(
369                "10857046999023057135944570762232829481370756359578518086990519993285655852781",
370            ),
371            fq_from_str(
372                "11559732032986387107991004021392285783925812861821192530917403151452391805634",
373            ),
374        );
375
376        let y = Fq2::new(
377            fq_from_str(
378                "8495653923123431417604973247489272438418190587263600148770280649306958101930",
379            ),
380            fq_from_str(
381                "4082367875863433681332203403145435568316851327593401208105741076214120093531",
382            ),
383        );
384        let z = Fq2::new(Fq::one(), Fq::zero());
385        G2Affine::from(G2Projective::new(x, y, z))
386    }
387
388    #[test]
389    fn can_deser_fq() {
390        let buf = fq_buf();
391        let fq = deserialize_field(&mut &buf[..]).unwrap();
392        assert_eq!(fq, Fq::one());
393    }
394
395    #[test]
396    fn can_deser_g1() {
397        let buf = g1_buf();
398        assert_eq!(buf.len(), 64);
399        let g1 = deserialize_g1(&mut &buf[..]).unwrap();
400        let expected = g1_one();
401        assert_eq!(g1, expected);
402    }
403
404    #[test]
405    fn can_deser_g1_vec() {
406        let n_vars = 10;
407        let buf = vec![g1_buf(); n_vars]
408            .iter()
409            .cloned()
410            .flatten()
411            .collect::<Vec<_>>();
412        let expected = vec![g1_one(); n_vars];
413
414        let de = deserialize_g1_vec(&mut &buf[..], n_vars as u32).unwrap();
415        assert_eq!(expected, de);
416    }
417
418    #[test]
419    fn can_deser_g2() {
420        let buf = g2_buf();
421        assert_eq!(buf.len(), 128);
422        let g2 = deserialize_g2(&mut &buf[..]).unwrap();
423
424        let expected = g2_one();
425        assert_eq!(g2, expected);
426    }
427
428    #[test]
429    fn can_deser_g2_vec() {
430        let n_vars = 10;
431        let buf = vec![g2_buf(); n_vars]
432            .iter()
433            .cloned()
434            .flatten()
435            .collect::<Vec<_>>();
436        let expected = vec![g2_one(); n_vars];
437
438        let de = deserialize_g2_vec(&mut &buf[..], n_vars as u32).unwrap();
439        assert_eq!(expected, de);
440    }
441
442    #[test]
443    fn header() {
444        // `circom --r1cs` using the below file:
445        //
446        //  template Multiplier() {
447        //     signal private input a;
448        //     signal private input b;
449        //     signal output c;
450        //
451        //     c <== a*b;
452        // }
453        //
454        // component main = Multiplier();
455        //
456        // Then:
457        // `snarkjs zkey new circuit.r1cs powersOfTau28_hez_final_10.ptau test.zkey`
458        let path = "./test-vectors/test.zkey";
459        let mut file = File::open(path).unwrap();
460        let mut binfile = BinFile::new(&mut file).unwrap();
461        let header = binfile.groth_header().unwrap();
462        assert_eq!(header.n_vars, 4);
463        assert_eq!(header.n_public, 1);
464        assert_eq!(header.domain_size, 4);
465        assert_eq!(header.power, 2);
466    }
467
468    #[test]
469    fn deser_key() {
470        let path = "./test-vectors/test.zkey";
471        let mut file = File::open(path).unwrap();
472        let params = read_zkey(&mut file).unwrap();
473
474        // Check IC
475        let expected = vec![
476            deserialize_g1(
477                &mut &[
478                    11, 205, 205, 176, 2, 105, 129, 243, 153, 58, 137, 89, 61, 95, 99, 161, 133,
479                    201, 153, 192, 119, 19, 113, 136, 43, 105, 47, 206, 166, 55, 81, 22, 154, 77,
480                    58, 119, 28, 230, 160, 206, 134, 98, 4, 115, 112, 184, 46, 117, 61, 180, 103,
481                    138, 141, 202, 110, 252, 199, 252, 141, 211, 5, 46, 244, 10,
482                ][..],
483            )
484            .unwrap(),
485            deserialize_g1(
486                &mut &[
487                    118, 135, 198, 156, 63, 190, 210, 98, 194, 59, 169, 168, 204, 168, 76, 208,
488                    109, 170, 24, 193, 57, 31, 184, 88, 234, 218, 118, 58, 107, 129, 90, 36, 230,
489                    98, 62, 243, 3, 55, 68, 227, 117, 64, 188, 81, 81, 247, 161, 68, 68, 210, 142,
490                    191, 174, 43, 110, 194, 253, 128, 217, 4, 54, 196, 111, 43,
491                ][..],
492            )
493            .unwrap(),
494        ];
495        assert_eq!(expected, params.vk.gamma_abc_g1);
496
497        // Check A Query
498        let expected = vec![
499            deserialize_g1(
500                &mut &[
501                    240, 165, 110, 187, 72, 39, 218, 59, 128, 85, 50, 174, 229, 1, 86, 58, 125,
502                    244, 145, 205, 248, 253, 120, 2, 165, 140, 154, 55, 220, 253, 14, 19, 212, 106,
503                    59, 19, 125, 198, 202, 4, 59, 74, 14, 62, 20, 248, 219, 47, 234, 205, 54, 183,
504                    33, 119, 165, 84, 46, 75, 39, 17, 229, 42, 192, 2,
505                ][..],
506            )
507            .unwrap(),
508            deserialize_g1(
509                &mut &[
510                    93, 53, 177, 82, 50, 5, 123, 116, 91, 35, 14, 196, 43, 180, 54, 15, 88, 144,
511                    197, 105, 57, 167, 54, 5, 188, 109, 17, 89, 9, 223, 80, 1, 39, 193, 211, 168,
512                    203, 119, 169, 105, 17, 156, 53, 106, 11, 102, 44, 92, 123, 220, 158, 240, 97,
513                    253, 30, 121, 4, 236, 171, 23, 100, 34, 133, 11,
514                ][..],
515            )
516            .unwrap(),
517            deserialize_g1(
518                &mut &[
519                    177, 47, 21, 237, 244, 73, 76, 98, 80, 10, 10, 142, 80, 145, 40, 254, 100, 214,
520                    103, 33, 38, 84, 238, 248, 252, 181, 75, 32, 109, 16, 93, 23, 135, 157, 206,
521                    122, 107, 105, 202, 164, 197, 124, 242, 100, 70, 108, 9, 180, 224, 102, 250,
522                    149, 130, 14, 133, 185, 132, 189, 193, 230, 180, 143, 156, 30,
523                ][..],
524            )
525            .unwrap(),
526            deserialize_g1(
527                &mut &[
528                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
529                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
530                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
531                ][..],
532            )
533            .unwrap(),
534        ];
535        assert_eq!(expected, params.a_query);
536
537        // B G1 Query
538        let expected = vec![
539            deserialize_g1(
540                &mut &[
541                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
542                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
543                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
544                ][..],
545            )
546            .unwrap(),
547            deserialize_g1(
548                &mut &[
549                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
550                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
551                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
552                ][..],
553            )
554            .unwrap(),
555            deserialize_g1(
556                &mut &[
557                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
558                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
559                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
560                ][..],
561            )
562            .unwrap(),
563            deserialize_g1(
564                &mut &[
565                    177, 47, 21, 237, 244, 73, 76, 98, 80, 10, 10, 142, 80, 145, 40, 254, 100, 214,
566                    103, 33, 38, 84, 238, 248, 252, 181, 75, 32, 109, 16, 93, 23, 192, 95, 174, 93,
567                    171, 34, 86, 151, 199, 77, 127, 3, 75, 254, 119, 227, 124, 241, 134, 235, 51,
568                    55, 203, 254, 164, 226, 111, 250, 189, 190, 199, 17,
569                ][..],
570            )
571            .unwrap(),
572        ];
573        assert_eq!(expected, params.b_g1_query);
574
575        // B G2 Query
576        let expected = vec![
577            deserialize_g2(
578                &mut &[
579                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
580                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
581                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
582                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
583                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
584                ][..],
585            )
586            .unwrap(),
587            deserialize_g2(
588                &mut &[
589                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
590                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
591                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
592                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
593                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
594                ][..],
595            )
596            .unwrap(),
597            deserialize_g2(
598                &mut &[
599                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
600                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
601                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
602                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
603                    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604                ][..],
605            )
606            .unwrap(),
607            deserialize_g2(
608                &mut &[
609                    240, 25, 157, 232, 164, 49, 152, 204, 244, 190, 178, 178, 29, 133, 205, 175,
610                    172, 28, 12, 123, 139, 202, 196, 13, 67, 165, 204, 42, 74, 40, 6, 36, 112, 104,
611                    61, 67, 107, 112, 72, 41, 213, 210, 249, 75, 89, 144, 144, 34, 177, 228, 18,
612                    70, 80, 195, 124, 82, 40, 122, 91, 21, 198, 100, 154, 1, 16, 235, 41, 4, 176,
613                    106, 9, 113, 141, 251, 100, 233, 188, 128, 194, 173, 0, 100, 206, 110, 53, 223,
614                    163, 47, 166, 235, 25, 12, 151, 238, 45, 0, 78, 210, 56, 53, 57, 212, 67, 189,
615                    253, 132, 62, 62, 116, 20, 235, 15, 245, 113, 30, 182, 33, 127, 203, 231, 124,
616                    149, 74, 223, 39, 190, 217, 41,
617                ][..],
618            )
619            .unwrap(),
620        ];
621        assert_eq!(expected, params.b_g2_query);
622
623        // Check L Query
624        let expected = vec![
625            deserialize_g1(
626                &mut &[
627                    146, 142, 29, 235, 9, 162, 84, 255, 6, 119, 86, 214, 154, 18, 12, 190, 202, 19,
628                    168, 45, 29, 76, 174, 130, 6, 59, 146, 15, 229, 82, 81, 40, 50, 25, 124, 247,
629                    129, 12, 147, 35, 108, 119, 178, 116, 238, 145, 33, 184, 74, 201, 128, 41, 151,
630                    6, 60, 84, 156, 225, 200, 14, 240, 171, 128, 20,
631                ][..],
632            )
633            .unwrap(),
634            deserialize_g1(
635                &mut &[
636                    26, 32, 112, 226, 161, 84, 188, 236, 141, 226, 119, 169, 235, 218, 253, 176,
637                    157, 184, 108, 243, 73, 122, 239, 217, 39, 190, 239, 105, 147, 190, 80, 47,
638                    211, 68, 155, 212, 139, 173, 229, 160, 123, 117, 243, 110, 162, 188, 217, 206,
639                    102, 19, 36, 189, 87, 183, 113, 8, 164, 133, 43, 142, 138, 109, 66, 33,
640                ][..],
641            )
642            .unwrap(),
643        ];
644        assert_eq!(expected, params.l_query);
645
646        // Check H Query
647        let expected = vec![
648            deserialize_g1(
649                &mut &[
650                    21, 76, 104, 34, 28, 236, 135, 204, 218, 16, 160, 115, 185, 44, 19, 62, 43, 24,
651                    57, 99, 207, 105, 10, 139, 195, 60, 17, 57, 85, 244, 167, 10, 166, 166, 165,
652                    55, 38, 75, 116, 116, 182, 87, 217, 112, 28, 237, 239, 123, 231, 180, 122, 109,
653                    77, 116, 88, 67, 102, 48, 80, 214, 137, 47, 94, 30,
654                ][..],
655            )
656            .unwrap(),
657            deserialize_g1(
658                &mut &[
659                    144, 175, 205, 119, 119, 192, 11, 10, 148, 224, 87, 161, 157, 231, 101, 208,
660                    55, 15, 13, 16, 24, 59, 9, 22, 63, 215, 255, 30, 77, 188, 71, 37, 84, 227, 59,
661                    29, 159, 116, 101, 93, 212, 220, 159, 141, 204, 107, 131, 87, 174, 149, 175,
662                    72, 199, 109, 64, 109, 180, 150, 160, 249, 246, 33, 212, 29,
663                ][..],
664            )
665            .unwrap(),
666            deserialize_g1(
667                &mut &[
668                    129, 169, 52, 179, 66, 88, 123, 199, 222, 69, 24, 17, 219, 235, 118, 195, 156,
669                    210, 14, 21, 76, 155, 178, 210, 223, 4, 233, 5, 8, 18, 156, 24, 82, 68, 183,
670                    186, 7, 126, 2, 201, 207, 207, 74, 45, 44, 199, 16, 165, 25, 65, 157, 199, 90,
671                    159, 12, 150, 250, 17, 177, 193, 244, 93, 230, 41,
672                ][..],
673            )
674            .unwrap(),
675            deserialize_g1(
676                &mut &[
677                    207, 61, 229, 214, 21, 61, 103, 165, 93, 145, 54, 138, 143, 214, 5, 83, 183,
678                    22, 174, 87, 108, 59, 99, 96, 19, 20, 25, 139, 114, 238, 198, 40, 182, 88, 1,
679                    255, 206, 132, 156, 165, 178, 171, 0, 226, 179, 30, 192, 4, 79, 198, 69, 43,
680                    145, 133, 116, 86, 36, 144, 190, 119, 79, 241, 76, 16,
681                ][..],
682            )
683            .unwrap(),
684        ];
685        assert_eq!(expected, params.h_query);
686    }
687
688    #[test]
689    fn deser_vk() {
690        let path = "./test-vectors/test.zkey";
691        let mut file = File::open(path).unwrap();
692        let params = read_zkey(&mut file).unwrap();
693
694        let json = std::fs::read_to_string("./test-vectors/verification_key.json").unwrap();
695        let json: Value = serde_json::from_str(&json).unwrap();
696
697        assert_eq!(json_to_g1(&json, "vk_alpha_1"), params.vk.alpha_g1);
698        assert_eq!(json_to_g2(&json, "vk_beta_2"), params.vk.beta_g2);
699        assert_eq!(json_to_g2(&json, "vk_gamma_2"), params.vk.gamma_g2);
700        assert_eq!(json_to_g2(&json, "vk_delta_2"), params.vk.delta_g2);
701        assert_eq!(json_to_g1_vec(&json, "IC"), params.vk.gamma_abc_g1);
702    }
703
704    fn json_to_g1(json: &Value, key: &str) -> G1Affine {
705        let els: Vec<String> = json
706            .get(key)
707            .unwrap()
708            .as_array()
709            .unwrap()
710            .iter()
711            .map(|i| i.as_str().unwrap().to_string())
712            .collect();
713        G1Affine::from(G1Projective::new(
714            fq_from_str(&els[0]),
715            fq_from_str(&els[1]),
716            fq_from_str(&els[2]),
717        ))
718    }
719
720    fn json_to_g1_vec(json: &Value, key: &str) -> Vec<G1Affine> {
721        let els: Vec<Vec<String>> = json
722            .get(key)
723            .unwrap()
724            .as_array()
725            .unwrap()
726            .iter()
727            .map(|i| {
728                i.as_array()
729                    .unwrap()
730                    .iter()
731                    .map(|x| x.as_str().unwrap().to_string())
732                    .collect::<Vec<String>>()
733            })
734            .collect();
735
736        els.iter()
737            .map(|coords| {
738                G1Affine::from(G1Projective::new(
739                    fq_from_str(&coords[0]),
740                    fq_from_str(&coords[1]),
741                    fq_from_str(&coords[2]),
742                ))
743            })
744            .collect()
745    }
746
747    fn json_to_g2(json: &Value, key: &str) -> G2Affine {
748        let els: Vec<Vec<String>> = json
749            .get(key)
750            .unwrap()
751            .as_array()
752            .unwrap()
753            .iter()
754            .map(|i| {
755                i.as_array()
756                    .unwrap()
757                    .iter()
758                    .map(|x| x.as_str().unwrap().to_string())
759                    .collect::<Vec<String>>()
760            })
761            .collect();
762
763        let x = Fq2::new(fq_from_str(&els[0][0]), fq_from_str(&els[0][1]));
764        let y = Fq2::new(fq_from_str(&els[1][0]), fq_from_str(&els[1][1]));
765        let z = Fq2::new(fq_from_str(&els[2][0]), fq_from_str(&els[2][1]));
766        G2Affine::from(G2Projective::new(x, y, z))
767    }
768
769    #[test]
770    fn verify_proof_with_zkey() {
771        let path = "./test-vectors/test.zkey";
772        let mut file = File::open(path).unwrap();
773        let params = read_zkey(&mut file).unwrap(); // binfile.proving_key().unwrap();
774
775        let cfg = CircomConfig::<Bn254>::new(
776            "./test-vectors/mycircuit.wasm",
777            "./test-vectors/mycircuit.r1cs",
778        )
779        .unwrap();
780        let mut builder = CircomBuilder::new(cfg);
781        builder.push_input("a", 3);
782        builder.push_input("b", 11);
783
784        let circom = builder.build().unwrap();
785
786        let inputs = circom.get_public_inputs().unwrap();
787
788        let mut rng = thread_rng();
789        let proof = prove::<_, _, _, CircomReduction>(circom, &params, &mut rng).unwrap();
790
791        let pvk = prepare_verifying_key(&params.vk);
792
793        let verified = verify_proof(&pvk, &proof, &inputs).unwrap();
794
795        assert!(verified);
796    }
797}