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