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