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