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