From 4ab9cdb1b048494e8afc61974dec66829be41a94 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 19 Sep 2022 18:37:25 +0200 Subject: [PATCH 01/94] implement better check, add test --- Cargo.lock | 9 +- zokrates_core/Cargo.toml | 1 - .../boolean_array_comparator.rs | 320 ++++++++++++++++++ zokrates_core/src/static_analysis/mod.rs | 7 + .../tests/arrays/boolean_array_equality.json | 7 + .../tests/arrays/boolean_array_equality.zok | 8 + zokrates_field/src/dummy_curve.rs | 253 ++++++++++++++ zokrates_field/src/lib.rs | 2 + 8 files changed, 598 insertions(+), 9 deletions(-) create mode 100644 zokrates_core/src/static_analysis/boolean_array_comparator.rs create mode 100644 zokrates_core_test/tests/tests/arrays/boolean_array_equality.json create mode 100644 zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok create mode 100644 zokrates_field/src/dummy_curve.rs diff --git a/Cargo.lock b/Cargo.lock index 7e67221af..1a74be51e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2109,12 +2109,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "reduce" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d2dc47b68ac15ea328cd7ebe01d7d512ed29787f7d534ad2a3c341328b35d7" - [[package]] name = "regex" version = "0.2.11" @@ -3127,7 +3121,6 @@ dependencies = [ "num 0.1.42", "num-bigint 0.2.6", "pretty_assertions 0.6.1", - "reduce", "serde", "serde_json", "typed-arena", @@ -3215,7 +3208,7 @@ dependencies = [ [[package]] name = "zokrates_js" -version = "1.1.2" +version = "1.1.3" dependencies = [ "console_error_panic_hook", "indexmap", diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index c1f316f2f..744b685f6 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -18,7 +18,6 @@ num = { version = "0.1.36", default-features = false } num-bigint = { version = "0.2", default-features = false } lazy_static = "1.4" typed-arena = "1.4.1" -reduce = "0.1.1" # serialization and deserialization serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1.0", features = ["preserve_order"] } diff --git a/zokrates_core/src/static_analysis/boolean_array_comparator.rs b/zokrates_core/src/static_analysis/boolean_array_comparator.rs new file mode 100644 index 000000000..90b83f286 --- /dev/null +++ b/zokrates_core/src/static_analysis/boolean_array_comparator.rs @@ -0,0 +1,320 @@ +use zokrates_ast::typed::{ + folder::*, ArrayExpressionInner, ArrayValue, BooleanExpression, ConditionalExpression, + ConditionalKind, EqExpression, FieldElementExpression, SelectExpression, Type, TypedExpression, + TypedProgram, UExpressionInner, +}; +use zokrates_field::Field; + +#[derive(Default)] +pub struct BooleanArrayComparator; + +impl BooleanArrayComparator { + pub fn simplify(p: TypedProgram) -> TypedProgram { + Self::default().fold_program(p) + } +} + +impl<'ast, T: Field> Folder<'ast, T> for BooleanArrayComparator { + fn fold_boolean_expression( + &mut self, + e: BooleanExpression<'ast, T>, + ) -> BooleanExpression<'ast, T> { + match e { + BooleanExpression::ArrayEq(e) => match e.left.inner_type() { + Type::Boolean => { + let len = e.left.size(); + let len = match len.as_inner() { + UExpressionInner::Value(v) => *v as usize, + _ => unreachable!("array size should be known"), + }; + + let chunk_size = T::get_required_bits() as usize - 1; + + let left_elements: Vec<_> = (0..len) + .map(|i| { + BooleanExpression::Select(SelectExpression::new( + *e.left.clone(), + (i as u32).into(), + )) + }) + .collect(); + let right_elements: Vec<_> = (0..len) + .map(|i| { + BooleanExpression::Select(SelectExpression::new( + *e.right.clone(), + (i as u32).into(), + )) + }) + .collect(); + + let process = |elements: &[BooleanExpression<'ast, T>]| { + elements + .chunks(chunk_size) + .map(|chunk| { + TypedExpression::from( + chunk + .iter() + .rev() + .enumerate() + .rev() + .map(|(index, c)| { + FieldElementExpression::Conditional( + ConditionalExpression::new( + c.clone(), + FieldElementExpression::Pow( + box FieldElementExpression::Number( + T::from(2), + ), + box (index as u32).into(), + ), + T::zero().into(), + ConditionalKind::Ternary, + ), + ) + }) + .fold(None, |acc, e| match acc { + Some(acc) => { + Some(FieldElementExpression::Add(box acc, box e)) + } + None => Some(e), + }) + .unwrap_or_else(|| { + FieldElementExpression::Number(T::zero()) + }), + ) + .into() + }) + .collect() + }; + + let left: Vec<_> = process(&left_elements); + + let right: Vec<_> = process(&right_elements); + + let chunk_count = left.len(); + + BooleanExpression::ArrayEq(EqExpression::new( + ArrayExpressionInner::Value(ArrayValue(left)) + .annotate(Type::FieldElement, chunk_count as u32), + ArrayExpressionInner::Value(ArrayValue(right)) + .annotate(Type::FieldElement, chunk_count as u32), + )) + } + _ => fold_boolean_expression(self, BooleanExpression::ArrayEq(e)), + }, + e => fold_boolean_expression(self, e), + } + } +} + +#[cfg(test)] +mod tests { + use num::Zero; + use zokrates_ast::typed::{ + ArrayExpressionInner, ArrayValue, BooleanExpression, ConditionalExpression, + ConditionalKind, EqExpression, FieldElementExpression, SelectExpression, Type, + TypedExpression, UBitwidth, UExpressionInner, + }; + use zokrates_field::DummyCurveField; + + use super::*; + + #[test] + fn simplify_short_array_eq() { + // x == y // type bool[2] + // should become + // [x[0] ? 2**1 : 0 + x[1] ? 2**0 : 0] == [y[0] ? 2**1 : 0 + y[1] ? 2**0 : 0] + // a single field is sufficient, as the prime we're working with is 3 bits long, so we can pack up to 2 bits + + let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new( + ArrayExpressionInner::Identifier("x".into()).annotate(Type::Boolean, 2u32), + ArrayExpressionInner::Identifier("y".into()).annotate(Type::Boolean, 2u32), + )); + + let expected = BooleanExpression::ArrayEq(EqExpression::new( + ArrayExpressionInner::Value(ArrayValue(vec![TypedExpression::from( + FieldElementExpression::Add( + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("x".into()) + .annotate(Type::Boolean, 2u32), + UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(1).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("x".into()) + .annotate(Type::Boolean, 2u32), + UExpressionInner::Value(1).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + ), + ) + .into()])) + .annotate(Type::FieldElement, 1u32), + ArrayExpressionInner::Value(ArrayValue(vec![TypedExpression::from( + FieldElementExpression::Add( + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("y".into()) + .annotate(Type::Boolean, 2u32), + UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(1).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("y".into()) + .annotate(Type::Boolean, 2u32), + UExpressionInner::Value(1).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + ), + ) + .into()])) + .annotate(Type::FieldElement, 1u32), + )); + + let res = BooleanArrayComparator::default().fold_boolean_expression(e); + + assert_eq!(res, expected); + } + + #[test] + fn simplify_long_array_eq() { + // x == y // type bool[3] + // should become + // [x[0] ? 2**2 : 0 + x[1] ? 2**1 : 0, x[2] ? 2**0 : 0] == [y[0] ? 2**2 : 0 + y[1] ? 2**1 : 0 y[2] ? 2**0 : 0] + + let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new( + ArrayExpressionInner::Identifier("x".into()).annotate(Type::Boolean, 3u32), + ArrayExpressionInner::Identifier("y".into()).annotate(Type::Boolean, 3u32), + )); + + let expected = BooleanExpression::ArrayEq(EqExpression::new( + ArrayExpressionInner::Value(ArrayValue(vec![ + TypedExpression::from(FieldElementExpression::Add( + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("x".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(1).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("x".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(1).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + )) + .into(), + TypedExpression::from(FieldElementExpression::Conditional( + ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("x".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(2).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + ), + )) + .into(), + ])) + .annotate(Type::FieldElement, 2u32), + ArrayExpressionInner::Value(ArrayValue(vec![ + TypedExpression::from(FieldElementExpression::Add( + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("y".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(1).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + box FieldElementExpression::Conditional(ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("y".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(1).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + )), + )) + .into(), + TypedExpression::from(FieldElementExpression::Conditional( + ConditionalExpression::new( + BooleanExpression::Select(SelectExpression::new( + ArrayExpressionInner::Identifier("y".into()) + .annotate(Type::Boolean, 3u32), + UExpressionInner::Value(2).annotate(UBitwidth::B32), + )), + FieldElementExpression::Pow( + box FieldElementExpression::Number(DummyCurveField::from(2)), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + ), + FieldElementExpression::Number(DummyCurveField::zero()), + ConditionalKind::Ternary, + ), + )) + .into(), + ])) + .annotate(Type::FieldElement, 2u32), + )); + + let res = BooleanArrayComparator::default().fold_boolean_expression(e); + + assert_eq!(res, expected); + } +} diff --git a/zokrates_core/src/static_analysis/mod.rs b/zokrates_core/src/static_analysis/mod.rs index e6ed76b24..bf394dc29 100644 --- a/zokrates_core/src/static_analysis/mod.rs +++ b/zokrates_core/src/static_analysis/mod.rs @@ -4,6 +4,7 @@ //! @author Thibaut Schaeffer //! @date 2018 +mod boolean_array_comparator; mod branch_isolator; mod condition_redefiner; mod constant_argument_checker; @@ -21,6 +22,7 @@ mod uint_optimizer; mod variable_write_remover; mod zir_propagation; +use self::boolean_array_comparator::BooleanArrayComparator; use self::branch_isolator::Isolator; use self::condition_redefiner::ConditionRedefiner; use self::constant_argument_checker::ConstantArgumentChecker; @@ -146,6 +148,11 @@ pub fn analyse<'ast, T: Field>( let r = Propagator::propagate(r).map_err(Error::from)?; log::trace!("\n{}", r); + // simplify boolean array comparisons + log::debug!("Static analyser: Simplify boolean array comparisons"); + let r = BooleanArrayComparator::simplify(r); + log::trace!("\n{}", r); + // remove assignment to variable index log::debug!("Static analyser: Remove variable index"); let r = VariableWriteRemover::apply(r); diff --git a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json new file mode 100644 index 000000000..64bcaaab5 --- /dev/null +++ b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json @@ -0,0 +1,7 @@ +{ + "entry_point": "./tests/tests/arrays/boolean_array_equality.zok", + "curves": ["Bn128"], + "max_constraint_count": 1005, + "tests": [] + } + \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok new file mode 100644 index 000000000..a0a864d31 --- /dev/null +++ b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok @@ -0,0 +1,8 @@ +// this should cost 1000 for input constraint, and then 1 per chunk of 253 booleans (for bn128), so here 5 +// total 1005 + +const u32 SIZE = 1000; + +def main(bool[SIZE] a) { + assert(a == [true; SIZE]); +} \ No newline at end of file diff --git a/zokrates_field/src/dummy_curve.rs b/zokrates_field/src/dummy_curve.rs new file mode 100644 index 000000000..5d3aed4a3 --- /dev/null +++ b/zokrates_field/src/dummy_curve.rs @@ -0,0 +1,253 @@ +use crate::{Field, Pow}; +use num_bigint::BigUint; +use num_traits::{CheckedDiv, One, Zero}; +use serde_derive::{Deserialize, Serialize}; +use std::convert::{From, TryFrom}; +use std::fmt; +use std::fmt::Debug; +use std::hash::Hash; +use std::ops::{Add, Div, Mul, Sub}; + +const _PRIME: u8 = 7; + +#[derive(Default, Debug, Hash, Clone, PartialOrd, Ord, Serialize, Deserialize, PartialEq, Eq)] +pub struct FieldPrime { + v: u8, +} + +impl fmt::Display for FieldPrime { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.v) + } +} + +impl From for FieldPrime { + fn from(_: u128) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(_: u64) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(_: u32) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(_: u16) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(num: u8) -> Self { + FieldPrime { v: num } + } +} + +impl From for FieldPrime { + fn from(_: usize) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(_: bool) -> Self { + unimplemented!() + } +} + +impl From for FieldPrime { + fn from(num: i32) -> Self { + assert!(num < _PRIME as i32); + assert!(num >= 0); + Self::from(num as u8) + } +} + +impl TryFrom for FieldPrime { + type Error = (); + + fn try_from(_: BigUint) -> Result { + unimplemented!() + } +} + +impl Zero for FieldPrime { + fn zero() -> FieldPrime { + FieldPrime { v: 0 } + } + fn is_zero(&self) -> bool { + self.v.is_zero() + } +} + +impl One for FieldPrime { + fn one() -> FieldPrime { + FieldPrime { v: 1 } + } +} + +impl Add for FieldPrime { + type Output = FieldPrime; + + fn add(self, _: FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl<'a> Add<&'a FieldPrime> for FieldPrime { + type Output = FieldPrime; + + fn add(self, _: &FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl Sub for FieldPrime { + type Output = FieldPrime; + + fn sub(self, _: FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl<'a> Sub<&'a FieldPrime> for FieldPrime { + type Output = FieldPrime; + + fn sub(self, _: &FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl Mul for FieldPrime { + type Output = FieldPrime; + + fn mul(self, _: FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl<'a> Mul<&'a FieldPrime> for FieldPrime { + type Output = FieldPrime; + + fn mul(self, _: &FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl CheckedDiv for FieldPrime { + fn checked_div(&self, _: &FieldPrime) -> Option { + unimplemented!() + } +} + +impl Div for FieldPrime { + type Output = FieldPrime; + + fn div(self, _: FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl<'a> Div<&'a FieldPrime> for FieldPrime { + type Output = FieldPrime; + + fn div(self, _: &FieldPrime) -> FieldPrime { + unimplemented!() + } +} + +impl Pow for FieldPrime { + type Output = FieldPrime; + + fn pow(self, _: usize) -> FieldPrime { + unimplemented!() + } +} + +impl num_traits::CheckedAdd for FieldPrime { + fn checked_add(&self, _: &Self) -> Option { + unimplemented!() + } +} + +impl num_traits::CheckedMul for FieldPrime { + fn checked_mul(&self, _: &Self) -> Option { + unimplemented!() + } +} + +impl Field for FieldPrime { + const G2_TYPE: crate::G2Type = crate::G2Type::Fq2; + + fn to_byte_vector(&self) -> Vec { + unimplemented!() + } + + fn from_byte_vector(_: Vec) -> Self { + unimplemented!() + } + + fn to_dec_string(&self) -> String { + unimplemented!() + } + + fn inverse_mul(&self) -> Option { + unimplemented!() + } + + fn min_value() -> Self { + unimplemented!() + } + + fn max_value() -> Self { + unimplemented!() + } + + fn max_unique_value() -> Self { + unimplemented!() + } + + fn to_bits_be(&self) -> Vec { + unimplemented!() + } + + fn get_required_bits() -> usize { + 3 // ceil(log2(7)) + } + + fn try_from_dec_str(_: &str) -> Result { + unimplemented!() + } + + fn try_from_str(_: &str, _: u32) -> Result { + unimplemented!() + } + + fn to_compact_dec_string(&self) -> String { + unimplemented!() + } + + fn id() -> [u8; 4] { + unimplemented!() + } + + fn name() -> &'static str { + unimplemented!() + } + + fn bits(&self) -> u32 { + unimplemented!() + } + + fn to_biguint(&self) -> num_bigint::BigUint { + unimplemented!() + } +} diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index dc1e6b907..38f76905b 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -632,8 +632,10 @@ pub mod bls12_377; pub mod bls12_381; pub mod bn128; pub mod bw6_761; +pub mod dummy_curve; pub use bls12_377::FieldPrime as Bls12_377Field; pub use bls12_381::FieldPrime as Bls12_381Field; pub use bn128::FieldPrime as Bn128Field; pub use bw6_761::FieldPrime as Bw6_761Field; +pub use dummy_curve::FieldPrime as DummyCurveField; From 2fc54f18b26571379699e24984076a61f3abdc56 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 20 Sep 2022 15:14:38 +0200 Subject: [PATCH 02/94] changelog, prettier --- changelogs/unreleased/1228-schaeff | 1 + .../tests/tests/arrays/boolean_array_equality.json | 11 +++++------ 2 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/1228-schaeff diff --git a/changelogs/unreleased/1228-schaeff b/changelogs/unreleased/1228-schaeff new file mode 100644 index 000000000..0727702e4 --- /dev/null +++ b/changelogs/unreleased/1228-schaeff @@ -0,0 +1 @@ +Reduce cost of boolean array equality checks \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json index 64bcaaab5..cc5ab4fbb 100644 --- a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json +++ b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json @@ -1,7 +1,6 @@ { - "entry_point": "./tests/tests/arrays/boolean_array_equality.zok", - "curves": ["Bn128"], - "max_constraint_count": 1005, - "tests": [] - } - \ No newline at end of file + "entry_point": "./tests/tests/arrays/boolean_array_equality.zok", + "curves": ["Bn128"], + "max_constraint_count": 1005, + "tests": [] +} From 7f818c80bcef248d29b0d044c13684bcc8cf86d0 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 20 Sep 2022 15:18:54 +0200 Subject: [PATCH 03/94] fix expected constraint count --- .../tests/tests/arrays/boolean_array_equality.json | 2 +- .../tests/tests/arrays/boolean_array_equality.zok | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json index cc5ab4fbb..f4397c388 100644 --- a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json +++ b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.json @@ -1,6 +1,6 @@ { "entry_point": "./tests/tests/arrays/boolean_array_equality.zok", "curves": ["Bn128"], - "max_constraint_count": 1005, + "max_constraint_count": 1004, "tests": [] } diff --git a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok index a0a864d31..e2f5a669c 100644 --- a/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok +++ b/zokrates_core_test/tests/tests/arrays/boolean_array_equality.zok @@ -1,5 +1,5 @@ -// this should cost 1000 for input constraint, and then 1 per chunk of 253 booleans (for bn128), so here 5 -// total 1005 +// this should cost 1000 for input constraint, and then 1 per chunk of 253 booleans (for bn128), so here 4 +// total 1004 const u32 SIZE = 1000; From 745c495fc69967a0124e8ca0e8f88994326b3abb Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 23 Sep 2022 15:52:33 +0200 Subject: [PATCH 04/94] use helper functions for tests, wip --- zokrates_core/Cargo.toml | 2 +- zokrates_core/src/lib.rs | 1 + .../boolean_array_comparator.rs | 204 +++--------- zokrates_core/src/utils/macros.rs | 305 ++++++++++++++++++ zokrates_core/src/utils/mod.rs | 1 + 5 files changed, 344 insertions(+), 169 deletions(-) create mode 100644 zokrates_core/src/utils/macros.rs create mode 100644 zokrates_core/src/utils/mod.rs diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index 744b685f6..10fa24a1a 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "zokrates_core" version = "0.7.2" -edition = "2018" +edition = "2021" authors = ["Jacob Eberhardt ", "Dennis Kuhnert "] repository = "https://github.com/Zokrates/ZoKrates" readme = "README.md" diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index b6cebfcb6..e9e0358da 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -7,3 +7,4 @@ mod macros; mod optimizer; mod semantics; mod static_analysis; +pub mod utils; diff --git a/zokrates_core/src/static_analysis/boolean_array_comparator.rs b/zokrates_core/src/static_analysis/boolean_array_comparator.rs index 90b83f286..5456e21f1 100644 --- a/zokrates_core/src/static_analysis/boolean_array_comparator.rs +++ b/zokrates_core/src/static_analysis/boolean_array_comparator.rs @@ -117,6 +117,8 @@ mod tests { }; use zokrates_field::DummyCurveField; + use crate::utils::macros::{a, a_id, conditional, f, select, u_32}; + use super::*; #[test] @@ -126,76 +128,24 @@ mod tests { // [x[0] ? 2**1 : 0 + x[1] ? 2**0 : 0] == [y[0] ? 2**1 : 0 + y[1] ? 2**0 : 0] // a single field is sufficient, as the prime we're working with is 3 bits long, so we can pack up to 2 bits - let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new( - ArrayExpressionInner::Identifier("x".into()).annotate(Type::Boolean, 2u32), - ArrayExpressionInner::Identifier("y".into()).annotate(Type::Boolean, 2u32), - )); + let x = x.clone(); + let y = x.clone(); + + let e: BooleanExpression = + BooleanExpression::ArrayEq(EqExpression::new(x.clone(), y.clone())); let expected = BooleanExpression::ArrayEq(EqExpression::new( - ArrayExpressionInner::Value(ArrayValue(vec![TypedExpression::from( - FieldElementExpression::Add( - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("x".into()) - .annotate(Type::Boolean, 2u32), - UExpressionInner::Value(0).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(1).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("x".into()) - .annotate(Type::Boolean, 2u32), - UExpressionInner::Value(1).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - ), - ) - .into()])) - .annotate(Type::FieldElement, 1u32), - ArrayExpressionInner::Value(ArrayValue(vec![TypedExpression::from( - FieldElementExpression::Add( - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("y".into()) - .annotate(Type::Boolean, 2u32), - UExpressionInner::Value(0).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(1).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("y".into()) - .annotate(Type::Boolean, 2u32), - UExpressionInner::Value(1).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - ), - ) - .into()])) - .annotate(Type::FieldElement, 1u32), + a([ + conditional::, _>( + select::<_, BooleanExpression<_>, _, _>(x.clone(), 0u32), + f(2).pow(u_32(1)), + f(0), + ) + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + ]), + a([ + conditional(select(y.clone(), 0u32), f(2).pow(u_32(1)), f(0)) + + conditional(select(y.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + ]), )); let res = BooleanArrayComparator::default().fold_boolean_expression(e); @@ -209,108 +159,26 @@ mod tests { // should become // [x[0] ? 2**2 : 0 + x[1] ? 2**1 : 0, x[2] ? 2**0 : 0] == [y[0] ? 2**2 : 0 + y[1] ? 2**1 : 0 y[2] ? 2**0 : 0] - let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new( - ArrayExpressionInner::Identifier("x".into()).annotate(Type::Boolean, 3u32), - ArrayExpressionInner::Identifier("y".into()).annotate(Type::Boolean, 3u32), - )); + let x = a_id("x").annotate(Type::Boolean, 3u32); + let y = a_id("x").annotate(Type::Boolean, 3u32); + + let e: BooleanExpression = + BooleanExpression::ArrayEq(EqExpression::new(x.clone(), y.clone())); let expected = BooleanExpression::ArrayEq(EqExpression::new( - ArrayExpressionInner::Value(ArrayValue(vec![ - TypedExpression::from(FieldElementExpression::Add( - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("x".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(0).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(1).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("x".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(1).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - )) - .into(), - TypedExpression::from(FieldElementExpression::Conditional( - ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("x".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(2).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - ), - )) - .into(), - ])) - .annotate(Type::FieldElement, 2u32), - ArrayExpressionInner::Value(ArrayValue(vec![ - TypedExpression::from(FieldElementExpression::Add( - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("y".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(0).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(1).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - box FieldElementExpression::Conditional(ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("y".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(1).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - )), - )) - .into(), - TypedExpression::from(FieldElementExpression::Conditional( - ConditionalExpression::new( - BooleanExpression::Select(SelectExpression::new( - ArrayExpressionInner::Identifier("y".into()) - .annotate(Type::Boolean, 3u32), - UExpressionInner::Value(2).annotate(UBitwidth::B32), - )), - FieldElementExpression::Pow( - box FieldElementExpression::Number(DummyCurveField::from(2)), - box UExpressionInner::Value(0).annotate(UBitwidth::B32), - ), - FieldElementExpression::Number(DummyCurveField::zero()), - ConditionalKind::Ternary, - ), - )) - .into(), - ])) - .annotate(Type::FieldElement, 2u32), + a([ + conditional::, _>( + select::<_, BooleanExpression<_>, _, _>(x.clone(), 0u32), + f(2).pow(u_32(1)), + f(0), + ) + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + conditional(select(x.clone(), 2u32), f(2).pow(u_32(0)), f(0)), + ]), + a([ + conditional(select(y.clone(), 0u32), f(2).pow(u_32(1)), f(0)) + + conditional(select(y.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + conditional(select(y.clone(), 2u32), f(2).pow(u_32(0)), f(0)), + ]), )); let res = BooleanArrayComparator::default().fold_boolean_expression(e); diff --git a/zokrates_core/src/utils/macros.rs b/zokrates_core/src/utils/macros.rs new file mode 100644 index 000000000..ffc5f7b11 --- /dev/null +++ b/zokrates_core/src/utils/macros.rs @@ -0,0 +1,305 @@ +use std::path::PathBuf; + +use zokrates_ast::typed::{ + types::GStructMember, ArrayExpression, ArrayExpressionInner, ArrayValue, Block, + BooleanExpression, Conditional, ConditionalKind, CoreIdentifier, DeclarationFunctionKey, + DeclarationType, DefinitionRhs, Element, Expr, FieldElementExpression, FunctionCall, GVariable, + Identifier, Member, MemberId, Select, ShadowedIdentifier, StructExpression, + StructExpressionInner, StructType, TupleExpression, TupleExpressionInner, TupleType, Type, + Typed, TypedAssignee, TypedExpression, TypedExpressionOrSpread, TypedStatement, UExpression, + Variable, +}; + +pub fn f<'ast, T, U: TryInto>(v: U) -> FieldElementExpression<'ast, T> { + FieldElementExpression::Number(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn f_id<'ast, T, I: TryInto>>(v: I) -> FieldElementExpression<'ast, T> { + zokrates_ast::typed::FieldElementExpression::Identifier(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn a_id<'ast, T, I: TryInto>>(v: I) -> ArrayExpressionInner<'ast, T> { + zokrates_ast::typed::ArrayExpressionInner::Identifier(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn id<'ast>(id: &'ast str) -> Identifier<'ast> { + let mut limbs = id.split("_"); + let name = limbs.next().unwrap(); + let shadow = limbs.next().map(|n| n.parse().unwrap()).unwrap(); + let version = limbs.next().map(|n| n.parse().unwrap()).unwrap_or(0); + Identifier { + version, + id: CoreIdentifier::Source(ShadowedIdentifier { shadow, id: name }), + } +} + +fn parse_type<'ast, T>(s: &'ast str) -> Type<'ast, T> { + match s { + "field" => Type::FieldElement, + "bool" => Type::Boolean, + _ => unimplemented!(), + } +} + +fn parse_expression<'ast, T>(s: &'ast str, ty: &Type<'ast, T>) -> TypedExpression<'ast, T> { + let id = id(s); + match ty { + Type::FieldElement => f_id(id).into(), + _ => unimplemented!(), + } +} + +pub fn stat<'ast, T: Clone>(s: &'ast str) -> TypedStatement<'ast, T> { + let mut is_mutable = false; + let mut s = s.split(" "); + let mut next = s.next().unwrap(); + if next == "mut" { + is_mutable = true; + next = s.next().unwrap(); + } + let ty = parse_type(next); + let id = CoreIdentifier::try_from(s.next().unwrap()) + .map_err(|_| ()) + .unwrap(); + assert_eq!(s.next().unwrap(), "="); + let e = parse_expression(s.next().unwrap(), &ty); + TypedStatement::Definition(Variable::new(id, ty, is_mutable).into(), e.into()) +} + +pub fn f_v<'ast, S: Clone, U: TryInto>>(v: U) -> GVariable<'ast, S> { + GVariable::field_element(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn b<'ast, T>(v: bool) -> BooleanExpression<'ast, T> { + BooleanExpression::Value(v) +} + +pub fn b_id<'ast, T, U: TryInto>>(v: U) -> BooleanExpression<'ast, T> { + zokrates_ast::typed::BooleanExpression::Identifier(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn b_v<'ast, T: Clone, U: TryInto>>(v: U) -> Variable<'ast, T> { + Variable::boolean(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn u_64<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) + .annotate(zokrates_ast::typed::UBitwidth::B64) +} + +pub fn u_64_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Identifier(v.into()) + .annotate(zokrates_ast::typed::UBitwidth::B32) +} + +pub fn u_32<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) + .annotate(zokrates_ast::typed::UBitwidth::B32) +} + +pub fn u_32_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Identifier(v.into()) + .annotate(zokrates_ast::typed::UBitwidth::B32) +} + +pub fn u_16<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) + .annotate(zokrates_ast::typed::UBitwidth::B32) +} + +pub fn u_16_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Identifier(v.into()) + .annotate(zokrates_ast::typed::UBitwidth::B16) +} + +pub fn u_8<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) + .annotate(zokrates_ast::typed::UBitwidth::B8) +} + +pub fn u_8_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { + zokrates_ast::typed::UExpressionInner::Identifier(v.into()) + .annotate(zokrates_ast::typed::UBitwidth::B8) +} + +pub fn conditional<'ast, T, E: Conditional<'ast, T>, B: TryInto>>( + condition: B, + consequence: E, + alternative: E, +) -> E { + E::conditional( + condition.try_into().map_err(|_| ()).unwrap(), + consequence, + alternative, + ConditionalKind::Ternary, + ) +} + +pub fn block<'ast, T, E: Block<'ast, T>, const N: usize>( + statements: [TypedStatement<'ast, T>; N], + value: E, +) -> E { + E::block(statements.into(), value) +} + +pub fn select< + 'ast, + T, + E: Select<'ast, T>, + A: TryInto>, + I: TryInto>, +>( + array: A, + index: I, +) -> E { + E::select( + array.try_into().map_err(|_| ()).unwrap(), + index.try_into().map_err(|_| ()).unwrap(), + ) +} + +pub fn member< + 'ast, + T, + E: Member<'ast, T>, + S: TryInto>, + I: TryInto, +>( + struc: S, + id: I, +) -> E { + E::member( + struc.try_into().map_err(|_| ()).unwrap(), + id.try_into().map_err(|_| ()).unwrap(), + ) +} + +pub fn call<'ast, T, E: Expr<'ast, T> + FunctionCall<'ast, T>, const N: usize, const M: usize>( + key: DeclarationFunctionKey<'ast, T>, + generics: [Option>; N], + arguments: [TypedExpression<'ast, T>; M], +) -> E::Inner { + E::function_call( + key, + generics.into_iter().collect(), + arguments.into_iter().collect(), + ) +} + +pub fn element< + 'ast, + T, + E: Element<'ast, T>, + U: TryInto>, + I: TryInto, +>( + tuple: U, + index: I, +) -> E { + E::element( + tuple.try_into().map_err(|_| ()).unwrap(), + index.try_into().map_err(|_| ()).unwrap(), + ) +} + +// pub fn equals<'ast, T, E: Equals<'ast, T>>(left: E, right: E) -> BooleanExpression<'ast, T> { +// left.equals(right) +// } + +// pub fn define_no_inference< +// 'ast, +// T, +// A: TryInto>, +// E: TryInto>, +// >( +// a: A, +// e: E, +// ) -> TypedStatement<'ast, T> { +// TypedStatement::Definition( +// a.try_into().map_err(|_| ()).unwrap(), +// DefinitionRhs::Expression(e.try_into().map_err(|_| ()).unwrap()), +// ) +// } + +// pub fn define< +// 'ast, +// T: Clone, +// A: TryInto>, +// E: Typed<'ast, T> + Expr<'ast, T> + TryInto>, +// >( +// a: A, +// e: E, +// ) -> TypedStatement<'ast, T> { +// let ty = e.get_type().clone(); + +// TypedStatement::Definition( +// Variable::new(a.try_into().map_err(|_| ()).unwrap(), ty, false).into(), +// DefinitionRhs::Expression(e.try_into().map_err(|_| ()).unwrap()), +// ) +// } + +// pub fn pop_call<'ast, T>() -> TypedStatement<'ast, T> { +// TypedStatement::PopCallLog +// } + +// pub fn push_call<'ast, T>() -> TypedStatement<'ast, T> { +// TypedStatement::PushCallLog +// } + +// pub fn ret<'ast, T, E: Typed<'ast, T> + Expr<'ast, T> + TryInto>>( +// e: E, +// ) -> TypedStatement<'ast, T> { +// TypedStatement::Return(e.try_into().map_err(|_| ()).unwrap()) +// } + +pub fn condition_id<'ast>(i: usize) -> CoreIdentifier<'ast> { + CoreIdentifier::Condition(i) +} + +pub fn a< + 'ast, + T, + E: Typed<'ast, T> + Expr<'ast, T> + Into>, + const N: usize, +>( + values: [E; N], +) -> ArrayExpression<'ast, T> { + let ty = values[0].get_type(); + ArrayExpressionInner::Value(ArrayValue( + values + .into_iter() + .map(|e| TypedExpressionOrSpread::Expression(e.into())) + .collect(), + )) + .annotate(ty, N as u32) +} + +pub fn s<'ast, T: Clone, M: TryInto, I: TryInto, const N: usize>( + name: M, + members: [(I, TypedExpression<'ast, T>); N], +) -> StructExpression<'ast, T> { + let members: Vec<_> = members + .into_iter() + .map(|(id, e)| (id.try_into().map_err(|_| ()).unwrap(), e)) + .collect(); + + let ty = StructType::new( + PathBuf::default(), + name.try_into().map_err(|_| ()).unwrap(), + vec![], + members + .iter() + .map(|(id, e)| GStructMember::new(id.clone(), e.get_type().clone())) + .collect(), + ); + + StructExpressionInner::Value(members.into_iter().map(|(_, e)| e).collect()).annotate(ty) +} + +pub fn t<'ast, T: Clone, const N: usize>( + elements: [TypedExpression<'ast, T>; N], +) -> TupleExpression<'ast, T> { + let ty = TupleType::new(elements.iter().map(|e| e.get_type().clone()).collect()); + + TupleExpressionInner::Value(elements.into_iter().collect()).annotate(ty) +} diff --git a/zokrates_core/src/utils/mod.rs b/zokrates_core/src/utils/mod.rs new file mode 100644 index 000000000..eda363d60 --- /dev/null +++ b/zokrates_core/src/utils/mod.rs @@ -0,0 +1 @@ +pub mod macros; From baf8b57804f56b9e27c922953e1e6040cc711d0d Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 26 Sep 2022 13:42:44 +0200 Subject: [PATCH 05/94] fix whitespace definition in pest --- zokrates_parser/src/zokrates.pest | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/zokrates_parser/src/zokrates.pest b/zokrates_parser/src/zokrates.pest index 67ab2ec2e..4b393fc24 100644 --- a/zokrates_parser/src/zokrates.pest +++ b/zokrates_parser/src/zokrates.pest @@ -1,4 +1,4 @@ -file = { SOI ~ NEWLINE* ~ pragma? ~ NEWLINE* ~ symbol_declaration* ~ EOI } +file = { SOI ~ pragma? ~ symbol_declaration* ~ EOI } pragma = { "#pragma" ~ "curve" ~ curve } curve = @{ (ASCII_ALPHANUMERIC | "_") * } @@ -6,7 +6,7 @@ string = @{(!"\"" ~ ANY)*} semicolon = _{";"} quoted_string = _{ "\"" ~ string ~ "\"" } -symbol_declaration = { (((import_directive | const_definition | type_definition) ~ semicolon) | (ty_struct_definition | function_definition)) ~ NEWLINE* } +symbol_declaration = { (((import_directive | const_definition | type_definition) ~ semicolon) | (ty_struct_definition | function_definition)) } import_directive = { main_import_directive | from_import_directive } from_import_directive = { "from" ~ quoted_string ~ "import" ~ import_symbol_list } @@ -41,8 +41,8 @@ ty_tuple_multiple_inner = _{ ty ~ ("," ~ ty)+ ~ ","? } // structs ty_struct = { identifier ~ explicit_generics? } // type definitions -ty_struct_definition = { "struct" ~ identifier ~ constant_generics_declaration? ~ "{" ~ NEWLINE* ~ struct_field_list ~ NEWLINE* ~ "}" ~ NEWLINE* } -struct_field_list = _{ (struct_field ~ semicolon ~ NEWLINE*)* } +ty_struct_definition = { "struct" ~ identifier ~ constant_generics_declaration? ~ "{" ~ struct_field_list ~ "}" } +struct_field_list = _{ (struct_field ~ semicolon)* } struct_field = { typed_identifier } vis_private = {"private"} @@ -57,10 +57,10 @@ statement = { (iteration_statement // does not require semicolon |return_statement | definition_statement | assertion_statement - ) ~ semicolon)) ~ NEWLINE* } + ) ~ semicolon)) } log_statement = { "log" ~ "(" ~ quoted_string ~ "," ~ expression_list ~ ")"} -block_statement = _{ "{" ~ NEWLINE* ~ statement* ~ NEWLINE* ~ "}" } +block_statement = _{ "{" ~ statement* ~ "}" } iteration_statement = { "for" ~ typed_identifier ~ "in" ~ expression ~ ".." ~ expression ~ block_statement } return_statement = { "return" ~ expression? } definition_statement = { typed_identifier_or_assignee ~ "=" ~ expression } @@ -86,7 +86,7 @@ inline_tuple_empty_expression_inner = _{ "" } inline_tuple_single_expression_inner = _{ expression ~ "," } inline_tuple_multiple_expression_inner = _{ expression ~ ("," ~ expression)+ ~ ","? } -block_expression = _{ "{" ~ NEWLINE* ~ statement* ~ expression ~ NEWLINE* ~ "}" } +block_expression = _{ "{" ~ statement* ~ expression ~ "}" } if_else_expression = { "if" ~ expression ~ block_expression ~ "else" ~ block_expression } access = { array_access | call_access | dot_access } @@ -102,12 +102,12 @@ identifier_or_decimal = { identifier | decimal_number } primary_expression = { identifier | literal } -inline_struct_expression = { identifier ~ "{" ~ NEWLINE* ~ inline_struct_member_list ~ NEWLINE* ~ "}" } -inline_struct_member_list = _{(inline_struct_member ~ ("," ~ NEWLINE* ~ inline_struct_member)*)? ~ ","? } +inline_struct_expression = { identifier ~ "{" ~ inline_struct_member_list ~ "}" } +inline_struct_member_list = _{(inline_struct_member ~ ("," ~ inline_struct_member)*)? ~ ","? } inline_struct_member = { identifier ~ ":" ~ expression } -inline_array_expression = { "[" ~ NEWLINE* ~ inline_array_inner ~ NEWLINE* ~ "]" } -inline_array_inner = _{(spread_or_expression ~ ("," ~ NEWLINE* ~ spread_or_expression)*)?} +inline_array_expression = { "[" ~ inline_array_inner ~ "]" } +inline_array_inner = _{(spread_or_expression ~ ("," ~ spread_or_expression)*)?} spread_or_expression = { spread | expression } range_or_expression = { range | expression } @@ -174,7 +174,7 @@ op_ternary = {"?" ~ expression ~ ":"} op_binary = _ { op_or | op_and | op_bit_xor | op_bit_and | op_bit_or | op_left_shift | op_right_shift | op_equal | op_not_equal | op_lte | op_lt | op_gte | op_gt | op_add | op_sub | op_mul | op_div | op_rem | op_ternary } op_unary = { op_pos | op_neg | op_not } -WHITESPACE = _{ " " | "\t" | "\\" ~ COMMENT? ~ NEWLINE} +WHITESPACE = _{ " " | "\t" | "\\" | COMMENT | NEWLINE } COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) } // the ordering of reserved keywords matters: if "as" is before "assert", then "assert" gets parsed as (as)(sert) and incorrectly From 4937c176bb60f05f297e83e7c80cd8d08a08e23b Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 26 Sep 2022 14:41:17 +0200 Subject: [PATCH 06/94] fix string parsing --- zokrates_ast/src/untyped/from_ast.rs | 8 ++--- zokrates_parser/src/zokrates.pest | 4 +-- zokrates_pest_ast/src/lib.rs | 47 +++++++++++++++++++--------- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/zokrates_ast/src/untyped/from_ast.rs b/zokrates_ast/src/untyped/from_ast.rs index 6526e7c65..9dce23390 100644 --- a/zokrates_ast/src/untyped/from_ast.rs +++ b/zokrates_ast/src/untyped/from_ast.rs @@ -23,7 +23,7 @@ fn import_directive_to_symbol_vec( match import { pest::ImportDirective::Main(import) => { let span = import.span; - let source = Path::new(import.source.span.as_str()); + let source = Path::new(import.source.raw.span.as_str()); let id = "main"; let alias = import.alias.map(|a| a.span.as_str()); @@ -41,7 +41,7 @@ fn import_directive_to_symbol_vec( } pest::ImportDirective::From(import) => { let span = import.span; - let source = Path::new(import.source.span.as_str()); + let source = Path::new(import.source.raw.span.as_str()); import .symbols .into_iter() @@ -251,7 +251,7 @@ impl<'ast> From> for untyped::StatementNode<'ast> { .map(untyped::ExpressionNode::from) .collect(); - untyped::Statement::Log(statement.format_string.span.as_str(), expressions) + untyped::Statement::Log(statement.format_string.raw.span.as_str(), expressions) .span(statement.span) } } @@ -321,7 +321,7 @@ impl<'ast> From> for untyped::StatementNode<'ast> untyped::Statement::Assertion( untyped::ExpressionNode::from(statement.expression), - statement.message.map(|m| m.value), + statement.message.map(|m| m.raw.value), ) .span(statement.span) } diff --git a/zokrates_parser/src/zokrates.pest b/zokrates_parser/src/zokrates.pest index 4b393fc24..1d5fa9a88 100644 --- a/zokrates_parser/src/zokrates.pest +++ b/zokrates_parser/src/zokrates.pest @@ -2,9 +2,9 @@ file = { SOI ~ pragma? ~ symbol_declaration* ~ EOI } pragma = { "#pragma" ~ "curve" ~ curve } curve = @{ (ASCII_ALPHANUMERIC | "_") * } -string = @{(!"\"" ~ ANY)*} +raw_string = @{(!"\"" ~ ANY)*} +quoted_string = ${ "\"" ~ raw_string ~ "\"" } semicolon = _{";"} -quoted_string = _{ "\"" ~ string ~ "\"" } symbol_declaration = { (((import_directive | const_definition | type_definition) ~ semicolon) | (ty_struct_definition | function_definition)) } diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 0564e13bb..5a7dffb42 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -211,7 +211,7 @@ mod ast { #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::main_import_directive))] pub struct MainImportDirective<'ast> { - pub source: AnyString<'ast>, + pub source: QString<'ast>, pub alias: Option>, #[pest_ast(outer())] pub span: Span<'ast>, @@ -229,7 +229,7 @@ mod ast { #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::from_import_directive))] pub struct FromImportDirective<'ast> { - pub source: AnyString<'ast>, + pub source: QString<'ast>, pub symbols: Vec>, #[pest_ast(outer())] pub span: Span<'ast>, @@ -371,7 +371,7 @@ mod ast { #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::log_statement))] pub struct LogStatement<'ast> { - pub format_string: AnyString<'ast>, + pub format_string: QString<'ast>, pub expressions: Vec>, #[pest_ast(outer())] pub span: Span<'ast>, @@ -387,19 +387,27 @@ mod ast { } #[derive(Debug, FromPest, PartialEq, Eq, Clone)] - #[pest_ast(rule(Rule::string))] - pub struct AnyString<'ast> { + #[pest_ast(rule(Rule::raw_string))] + pub struct RawString<'ast> { #[pest_ast(outer(with(span_into_str)))] pub value: String, #[pest_ast(outer())] pub span: Span<'ast>, } + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] + #[pest_ast(rule(Rule::quoted_string))] + pub struct QString<'ast> { + pub raw: RawString<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, + } + #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::assertion_statement))] pub struct AssertionStatement<'ast> { pub expression: Expression<'ast>, - pub message: Option>, + pub message: Option>, #[pest_ast(outer())] pub span: Span<'ast>, } @@ -1178,9 +1186,12 @@ mod tests { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { - source: AnyString { - value: String::from("foo"), - span: Span::new(source, 17, 20).unwrap() + source: QString { + raw: RawString { + value: String::from("foo"), + span: Span::new(source, 17, 20).unwrap() + }, + span: Span::new(source, 16, 21).unwrap() }, alias: None, span: Span::new(source, 9, 21).unwrap() @@ -1243,9 +1254,12 @@ mod tests { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { - source: AnyString { - value: String::from("foo"), - span: Span::new(source, 17, 20).unwrap() + source: QString { + raw: RawString { + value: String::from("foo"), + span: Span::new(source, 17, 20).unwrap() + }, + span: Span::new(source, 16, 21).unwrap() }, alias: None, span: Span::new(source, 9, 21).unwrap() @@ -1332,9 +1346,12 @@ mod tests { pragma: None, declarations: vec![ SymbolDeclaration::Import(ImportDirective::Main(MainImportDirective { - source: AnyString { - value: String::from("foo"), - span: Span::new(source, 17, 20).unwrap() + source: QString { + raw: RawString { + value: String::from("foo"), + span: Span::new(source, 17, 20).unwrap() + }, + span: Span::new(source, 16, 21).unwrap() }, alias: None, span: Span::new(source, 9, 21).unwrap() From 955d6bae5d02a90ab85ff5aac72ee47ba24ab4c4 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 26 Sep 2022 15:08:41 +0200 Subject: [PATCH 07/94] clean --- zokrates_ast/src/typed/mod.rs | 1 + zokrates_ast/src/typed/utils/mod.rs | 45 +++ zokrates_core/src/lib.rs | 1 - .../boolean_array_comparator.rs | 27 +- .../src/static_analysis/reducer/inline.rs | 2 - .../static_analysis/variable_write_remover.rs | 2 - zokrates_core/src/utils/macros.rs | 305 ------------------ zokrates_core/src/utils/mod.rs | 1 - 8 files changed, 54 insertions(+), 330 deletions(-) create mode 100644 zokrates_ast/src/typed/utils/mod.rs delete mode 100644 zokrates_core/src/utils/macros.rs delete mode 100644 zokrates_core/src/utils/mod.rs diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index a43f59bdb..0ea0870e8 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -14,6 +14,7 @@ mod integer; mod parameter; pub mod types; mod uint; +pub mod utils; pub mod variable; pub use self::identifier::{CoreIdentifier, ShadowedIdentifier, SourceIdentifier}; diff --git a/zokrates_ast/src/typed/utils/mod.rs b/zokrates_ast/src/typed/utils/mod.rs new file mode 100644 index 000000000..1603d043a --- /dev/null +++ b/zokrates_ast/src/typed/utils/mod.rs @@ -0,0 +1,45 @@ +use super::{ + ArrayExpression, ArrayExpressionInner, BooleanExpression, Conditional, ConditionalKind, + FieldElementExpression, Identifier, Select, UBitwidth, UExpression, UExpressionInner, +}; + +pub fn f<'ast, T, U: TryInto>(v: U) -> FieldElementExpression<'ast, T> { + FieldElementExpression::Number(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn a_id<'ast, T, I: TryInto>>(v: I) -> ArrayExpressionInner<'ast, T> { + ArrayExpressionInner::Identifier(v.try_into().map_err(|_| ()).unwrap()) +} + +pub fn u_32<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { + UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128).annotate(UBitwidth::B32) +} + +pub fn conditional<'ast, T, E: Conditional<'ast, T>>( + condition: BooleanExpression<'ast, T>, + consequence: E, + alternative: E, +) -> E { + E::conditional( + condition, + consequence, + alternative, + ConditionalKind::Ternary, + ) +} + +pub fn select< + 'ast, + T, + E: Select<'ast, T>, + A: TryInto>, + I: TryInto>, +>( + array: A, + index: I, +) -> E { + E::select( + array.try_into().map_err(|_| ()).unwrap(), + index.try_into().map_err(|_| ()).unwrap(), + ) +} diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index e9e0358da..b6cebfcb6 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -7,4 +7,3 @@ mod macros; mod optimizer; mod semantics; mod static_analysis; -pub mod utils; diff --git a/zokrates_core/src/static_analysis/boolean_array_comparator.rs b/zokrates_core/src/static_analysis/boolean_array_comparator.rs index 5456e21f1..b3530b501 100644 --- a/zokrates_core/src/static_analysis/boolean_array_comparator.rs +++ b/zokrates_core/src/static_analysis/boolean_array_comparator.rs @@ -109,15 +109,10 @@ impl<'ast, T: Field> Folder<'ast, T> for BooleanArrayComparator { #[cfg(test)] mod tests { - use num::Zero; - use zokrates_ast::typed::{ - ArrayExpressionInner, ArrayValue, BooleanExpression, ConditionalExpression, - ConditionalKind, EqExpression, FieldElementExpression, SelectExpression, Type, - TypedExpression, UBitwidth, UExpressionInner, - }; + use zokrates_ast::typed::{BooleanExpression, EqExpression, FieldElementExpression, Type}; use zokrates_field::DummyCurveField; - use crate::utils::macros::{a, a_id, conditional, f, select, u_32}; + use zokrates_ast::typed::utils::{a, a_id, conditional, f, select, u_32}; use super::*; @@ -128,19 +123,16 @@ mod tests { // [x[0] ? 2**1 : 0 + x[1] ? 2**0 : 0] == [y[0] ? 2**1 : 0 + y[1] ? 2**0 : 0] // a single field is sufficient, as the prime we're working with is 3 bits long, so we can pack up to 2 bits - let x = x.clone(); - let y = x.clone(); + let x = a_id("x").annotate(Type::Boolean, 2u32); + let y = a_id("x").annotate(Type::Boolean, 2u32); let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new(x.clone(), y.clone())); let expected = BooleanExpression::ArrayEq(EqExpression::new( a([ - conditional::, _>( - select::<_, BooleanExpression<_>, _, _>(x.clone(), 0u32), - f(2).pow(u_32(1)), - f(0), - ) + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + conditional(select(x.clone(), 0u32), f(2).pow(u_32(1)), f(0)) + + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), ]), a([ conditional(select(y.clone(), 0u32), f(2).pow(u_32(1)), f(0)) @@ -167,11 +159,8 @@ mod tests { let expected = BooleanExpression::ArrayEq(EqExpression::new( a([ - conditional::, _>( - select::<_, BooleanExpression<_>, _, _>(x.clone(), 0u32), - f(2).pow(u_32(1)), - f(0), - ) + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), + conditional(select(x.clone(), 0u32), f(2).pow(u_32(1)), f(0)) + + conditional(select(x.clone(), 1u32), f(2).pow(u_32(0)), f(0)), conditional(select(x.clone(), 2u32), f(2).pow(u_32(0)), f(0)), ]), a([ diff --git a/zokrates_core/src/static_analysis/reducer/inline.rs b/zokrates_core/src/static_analysis/reducer/inline.rs index b2c12962a..09aa6c932 100644 --- a/zokrates_core/src/static_analysis/reducer/inline.rs +++ b/zokrates_core/src/static_analysis/reducer/inline.rs @@ -88,8 +88,6 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>( program: &TypedProgram<'ast, T>, versions: &'a mut Versions<'ast>, ) -> InlineResult<'ast, T> { - use std::convert::TryFrom; - use zokrates_ast::typed::Typed; let output_type = output.clone().into_type(); diff --git a/zokrates_core/src/static_analysis/variable_write_remover.rs b/zokrates_core/src/static_analysis/variable_write_remover.rs index ce80c9607..ea1c72dab 100644 --- a/zokrates_core/src/static_analysis/variable_write_remover.rs +++ b/zokrates_core/src/static_analysis/variable_write_remover.rs @@ -37,8 +37,6 @@ impl<'ast> VariableWriteRemover { let inner_ty = base.inner_type(); let size = base.size(); - use std::convert::TryInto; - let size: u32 = size.try_into().unwrap(); let head = indices.remove(0); diff --git a/zokrates_core/src/utils/macros.rs b/zokrates_core/src/utils/macros.rs deleted file mode 100644 index ffc5f7b11..000000000 --- a/zokrates_core/src/utils/macros.rs +++ /dev/null @@ -1,305 +0,0 @@ -use std::path::PathBuf; - -use zokrates_ast::typed::{ - types::GStructMember, ArrayExpression, ArrayExpressionInner, ArrayValue, Block, - BooleanExpression, Conditional, ConditionalKind, CoreIdentifier, DeclarationFunctionKey, - DeclarationType, DefinitionRhs, Element, Expr, FieldElementExpression, FunctionCall, GVariable, - Identifier, Member, MemberId, Select, ShadowedIdentifier, StructExpression, - StructExpressionInner, StructType, TupleExpression, TupleExpressionInner, TupleType, Type, - Typed, TypedAssignee, TypedExpression, TypedExpressionOrSpread, TypedStatement, UExpression, - Variable, -}; - -pub fn f<'ast, T, U: TryInto>(v: U) -> FieldElementExpression<'ast, T> { - FieldElementExpression::Number(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn f_id<'ast, T, I: TryInto>>(v: I) -> FieldElementExpression<'ast, T> { - zokrates_ast::typed::FieldElementExpression::Identifier(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn a_id<'ast, T, I: TryInto>>(v: I) -> ArrayExpressionInner<'ast, T> { - zokrates_ast::typed::ArrayExpressionInner::Identifier(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn id<'ast>(id: &'ast str) -> Identifier<'ast> { - let mut limbs = id.split("_"); - let name = limbs.next().unwrap(); - let shadow = limbs.next().map(|n| n.parse().unwrap()).unwrap(); - let version = limbs.next().map(|n| n.parse().unwrap()).unwrap_or(0); - Identifier { - version, - id: CoreIdentifier::Source(ShadowedIdentifier { shadow, id: name }), - } -} - -fn parse_type<'ast, T>(s: &'ast str) -> Type<'ast, T> { - match s { - "field" => Type::FieldElement, - "bool" => Type::Boolean, - _ => unimplemented!(), - } -} - -fn parse_expression<'ast, T>(s: &'ast str, ty: &Type<'ast, T>) -> TypedExpression<'ast, T> { - let id = id(s); - match ty { - Type::FieldElement => f_id(id).into(), - _ => unimplemented!(), - } -} - -pub fn stat<'ast, T: Clone>(s: &'ast str) -> TypedStatement<'ast, T> { - let mut is_mutable = false; - let mut s = s.split(" "); - let mut next = s.next().unwrap(); - if next == "mut" { - is_mutable = true; - next = s.next().unwrap(); - } - let ty = parse_type(next); - let id = CoreIdentifier::try_from(s.next().unwrap()) - .map_err(|_| ()) - .unwrap(); - assert_eq!(s.next().unwrap(), "="); - let e = parse_expression(s.next().unwrap(), &ty); - TypedStatement::Definition(Variable::new(id, ty, is_mutable).into(), e.into()) -} - -pub fn f_v<'ast, S: Clone, U: TryInto>>(v: U) -> GVariable<'ast, S> { - GVariable::field_element(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn b<'ast, T>(v: bool) -> BooleanExpression<'ast, T> { - BooleanExpression::Value(v) -} - -pub fn b_id<'ast, T, U: TryInto>>(v: U) -> BooleanExpression<'ast, T> { - zokrates_ast::typed::BooleanExpression::Identifier(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn b_v<'ast, T: Clone, U: TryInto>>(v: U) -> Variable<'ast, T> { - Variable::boolean(v.try_into().map_err(|_| ()).unwrap()) -} - -pub fn u_64<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) - .annotate(zokrates_ast::typed::UBitwidth::B64) -} - -pub fn u_64_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Identifier(v.into()) - .annotate(zokrates_ast::typed::UBitwidth::B32) -} - -pub fn u_32<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) - .annotate(zokrates_ast::typed::UBitwidth::B32) -} - -pub fn u_32_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Identifier(v.into()) - .annotate(zokrates_ast::typed::UBitwidth::B32) -} - -pub fn u_16<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) - .annotate(zokrates_ast::typed::UBitwidth::B32) -} - -pub fn u_16_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Identifier(v.into()) - .annotate(zokrates_ast::typed::UBitwidth::B16) -} - -pub fn u_8<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128) - .annotate(zokrates_ast::typed::UBitwidth::B8) -} - -pub fn u_8_id<'ast, T>(v: &'ast str) -> UExpression<'ast, T> { - zokrates_ast::typed::UExpressionInner::Identifier(v.into()) - .annotate(zokrates_ast::typed::UBitwidth::B8) -} - -pub fn conditional<'ast, T, E: Conditional<'ast, T>, B: TryInto>>( - condition: B, - consequence: E, - alternative: E, -) -> E { - E::conditional( - condition.try_into().map_err(|_| ()).unwrap(), - consequence, - alternative, - ConditionalKind::Ternary, - ) -} - -pub fn block<'ast, T, E: Block<'ast, T>, const N: usize>( - statements: [TypedStatement<'ast, T>; N], - value: E, -) -> E { - E::block(statements.into(), value) -} - -pub fn select< - 'ast, - T, - E: Select<'ast, T>, - A: TryInto>, - I: TryInto>, ->( - array: A, - index: I, -) -> E { - E::select( - array.try_into().map_err(|_| ()).unwrap(), - index.try_into().map_err(|_| ()).unwrap(), - ) -} - -pub fn member< - 'ast, - T, - E: Member<'ast, T>, - S: TryInto>, - I: TryInto, ->( - struc: S, - id: I, -) -> E { - E::member( - struc.try_into().map_err(|_| ()).unwrap(), - id.try_into().map_err(|_| ()).unwrap(), - ) -} - -pub fn call<'ast, T, E: Expr<'ast, T> + FunctionCall<'ast, T>, const N: usize, const M: usize>( - key: DeclarationFunctionKey<'ast, T>, - generics: [Option>; N], - arguments: [TypedExpression<'ast, T>; M], -) -> E::Inner { - E::function_call( - key, - generics.into_iter().collect(), - arguments.into_iter().collect(), - ) -} - -pub fn element< - 'ast, - T, - E: Element<'ast, T>, - U: TryInto>, - I: TryInto, ->( - tuple: U, - index: I, -) -> E { - E::element( - tuple.try_into().map_err(|_| ()).unwrap(), - index.try_into().map_err(|_| ()).unwrap(), - ) -} - -// pub fn equals<'ast, T, E: Equals<'ast, T>>(left: E, right: E) -> BooleanExpression<'ast, T> { -// left.equals(right) -// } - -// pub fn define_no_inference< -// 'ast, -// T, -// A: TryInto>, -// E: TryInto>, -// >( -// a: A, -// e: E, -// ) -> TypedStatement<'ast, T> { -// TypedStatement::Definition( -// a.try_into().map_err(|_| ()).unwrap(), -// DefinitionRhs::Expression(e.try_into().map_err(|_| ()).unwrap()), -// ) -// } - -// pub fn define< -// 'ast, -// T: Clone, -// A: TryInto>, -// E: Typed<'ast, T> + Expr<'ast, T> + TryInto>, -// >( -// a: A, -// e: E, -// ) -> TypedStatement<'ast, T> { -// let ty = e.get_type().clone(); - -// TypedStatement::Definition( -// Variable::new(a.try_into().map_err(|_| ()).unwrap(), ty, false).into(), -// DefinitionRhs::Expression(e.try_into().map_err(|_| ()).unwrap()), -// ) -// } - -// pub fn pop_call<'ast, T>() -> TypedStatement<'ast, T> { -// TypedStatement::PopCallLog -// } - -// pub fn push_call<'ast, T>() -> TypedStatement<'ast, T> { -// TypedStatement::PushCallLog -// } - -// pub fn ret<'ast, T, E: Typed<'ast, T> + Expr<'ast, T> + TryInto>>( -// e: E, -// ) -> TypedStatement<'ast, T> { -// TypedStatement::Return(e.try_into().map_err(|_| ()).unwrap()) -// } - -pub fn condition_id<'ast>(i: usize) -> CoreIdentifier<'ast> { - CoreIdentifier::Condition(i) -} - -pub fn a< - 'ast, - T, - E: Typed<'ast, T> + Expr<'ast, T> + Into>, - const N: usize, ->( - values: [E; N], -) -> ArrayExpression<'ast, T> { - let ty = values[0].get_type(); - ArrayExpressionInner::Value(ArrayValue( - values - .into_iter() - .map(|e| TypedExpressionOrSpread::Expression(e.into())) - .collect(), - )) - .annotate(ty, N as u32) -} - -pub fn s<'ast, T: Clone, M: TryInto, I: TryInto, const N: usize>( - name: M, - members: [(I, TypedExpression<'ast, T>); N], -) -> StructExpression<'ast, T> { - let members: Vec<_> = members - .into_iter() - .map(|(id, e)| (id.try_into().map_err(|_| ()).unwrap(), e)) - .collect(); - - let ty = StructType::new( - PathBuf::default(), - name.try_into().map_err(|_| ()).unwrap(), - vec![], - members - .iter() - .map(|(id, e)| GStructMember::new(id.clone(), e.get_type().clone())) - .collect(), - ); - - StructExpressionInner::Value(members.into_iter().map(|(_, e)| e).collect()).annotate(ty) -} - -pub fn t<'ast, T: Clone, const N: usize>( - elements: [TypedExpression<'ast, T>; N], -) -> TupleExpression<'ast, T> { - let ty = TupleType::new(elements.iter().map(|e| e.get_type().clone()).collect()); - - TupleExpressionInner::Value(elements.into_iter().collect()).annotate(ty) -} diff --git a/zokrates_core/src/utils/mod.rs b/zokrates_core/src/utils/mod.rs deleted file mode 100644 index eda363d60..000000000 --- a/zokrates_core/src/utils/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod macros; From 230e8f0e84f7b123c91b53382aaa00089033552d Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 26 Sep 2022 15:22:13 +0200 Subject: [PATCH 08/94] fix utils --- zokrates_ast/src/typed/utils/mod.rs | 23 +++++++++++++++++-- .../boolean_array_comparator.rs | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/zokrates_ast/src/typed/utils/mod.rs b/zokrates_ast/src/typed/utils/mod.rs index 1603d043a..3720113cb 100644 --- a/zokrates_ast/src/typed/utils/mod.rs +++ b/zokrates_ast/src/typed/utils/mod.rs @@ -1,6 +1,7 @@ use super::{ - ArrayExpression, ArrayExpressionInner, BooleanExpression, Conditional, ConditionalKind, - FieldElementExpression, Identifier, Select, UBitwidth, UExpression, UExpressionInner, + ArrayExpression, ArrayExpressionInner, ArrayValue, BooleanExpression, Conditional, + ConditionalKind, Expr, FieldElementExpression, Identifier, Select, Typed, TypedExpression, + TypedExpressionOrSpread, UBitwidth, UExpression, UExpressionInner, }; pub fn f<'ast, T, U: TryInto>(v: U) -> FieldElementExpression<'ast, T> { @@ -11,6 +12,24 @@ pub fn a_id<'ast, T, I: TryInto>>(v: I) -> ArrayExpressionInner ArrayExpressionInner::Identifier(v.try_into().map_err(|_| ()).unwrap()) } +pub fn a< + 'ast, + T, + E: Typed<'ast, T> + Expr<'ast, T> + Into>, + const N: usize, +>( + values: [E; N], +) -> ArrayExpression<'ast, T> { + let ty = values[0].get_type(); + ArrayExpressionInner::Value(ArrayValue( + values + .into_iter() + .map(|e| TypedExpressionOrSpread::Expression(e.into())) + .collect(), + )) + .annotate(ty, N as u32) +} + pub fn u_32<'ast, T, U: TryInto>(v: U) -> UExpression<'ast, T> { UExpressionInner::Value(v.try_into().map_err(|_| ()).unwrap() as u128).annotate(UBitwidth::B32) } diff --git a/zokrates_core/src/static_analysis/boolean_array_comparator.rs b/zokrates_core/src/static_analysis/boolean_array_comparator.rs index b3530b501..f33d07b4f 100644 --- a/zokrates_core/src/static_analysis/boolean_array_comparator.rs +++ b/zokrates_core/src/static_analysis/boolean_array_comparator.rs @@ -109,7 +109,7 @@ impl<'ast, T: Field> Folder<'ast, T> for BooleanArrayComparator { #[cfg(test)] mod tests { - use zokrates_ast::typed::{BooleanExpression, EqExpression, FieldElementExpression, Type}; + use zokrates_ast::typed::{BooleanExpression, EqExpression, Type}; use zokrates_field::DummyCurveField; use zokrates_ast::typed::utils::{a, a_id, conditional, f, select, u_32}; From c2f5e1a91f0c2e795e7bef091cfad2cbd33ab334 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 5 Oct 2022 14:37:05 +0200 Subject: [PATCH 09/94] fix error following merge --- zokrates_ast/src/typed/utils/mod.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/zokrates_ast/src/typed/utils/mod.rs b/zokrates_ast/src/typed/utils/mod.rs index 3720113cb..6ec6885c2 100644 --- a/zokrates_ast/src/typed/utils/mod.rs +++ b/zokrates_ast/src/typed/utils/mod.rs @@ -1,15 +1,17 @@ use super::{ ArrayExpression, ArrayExpressionInner, ArrayValue, BooleanExpression, Conditional, - ConditionalKind, Expr, FieldElementExpression, Identifier, Select, Typed, TypedExpression, + ConditionalKind, Expr, FieldElementExpression, Id, Identifier, Select, Typed, TypedExpression, TypedExpressionOrSpread, UBitwidth, UExpression, UExpressionInner, }; +use zokrates_field::Field; + pub fn f<'ast, T, U: TryInto>(v: U) -> FieldElementExpression<'ast, T> { FieldElementExpression::Number(v.try_into().map_err(|_| ()).unwrap()) } -pub fn a_id<'ast, T, I: TryInto>>(v: I) -> ArrayExpressionInner<'ast, T> { - ArrayExpressionInner::Identifier(v.try_into().map_err(|_| ()).unwrap()) +pub fn a_id<'ast, T: Field, I: TryInto>>(v: I) -> ArrayExpressionInner<'ast, T> { + ArrayExpression::identifier(v.try_into().map_err(|_| ()).unwrap()) } pub fn a< From c8696497454b036366433ed54e0a0aa2e2eb1915 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 5 Oct 2022 15:27:45 +0200 Subject: [PATCH 10/94] wip --- zokrates_ark/src/gm17.rs | 8 +- zokrates_ark/src/groth16.rs | 8 +- zokrates_ark/src/lib.rs | 18 +-- zokrates_ark/src/marlin.rs | 8 +- zokrates_ast/src/common/embed.rs | 15 +- zokrates_ast/src/common/error.rs | 2 + zokrates_ast/src/common/solvers.rs | 17 ++- zokrates_ast/src/flat/folder.rs | 30 ++-- zokrates_ast/src/flat/mod.rs | 34 ++--- zokrates_ast/src/ir/check.rs | 8 +- zokrates_ast/src/ir/folder.rs | 34 +++-- zokrates_ast/src/ir/from_flat.rs | 14 +- zokrates_ast/src/ir/mod.rs | 34 +++-- zokrates_ast/src/ir/serialize.rs | 52 +++---- zokrates_ast/src/ir/smtlib2.rs | 10 +- zokrates_ast/src/typed/folder.rs | 28 ++++ zokrates_ast/src/typed/identifier.rs | 14 +- zokrates_ast/src/typed/mod.rs | 108 +++++++++++++++ zokrates_ast/src/typed/result_folder.rs | 28 ++++ zokrates_ast/src/typed/types.rs | 5 +- zokrates_ast/src/untyped/from_ast.rs | 27 ++++ zokrates_ast/src/untyped/mod.rs | 37 ++++- zokrates_ast/src/untyped/node.rs | 1 + zokrates_ast/src/zir/folder.rs | 31 +++++ zokrates_ast/src/zir/identifier.rs | 7 +- zokrates_ast/src/zir/mod.rs | 129 +++++++++++++++--- zokrates_ast/src/zir/parameter.rs | 4 +- zokrates_ast/src/zir/result_folder.rs | 34 +++++ zokrates_ast/src/zir/uint.rs | 11 +- zokrates_ast/src/zir/variable.rs | 4 +- zokrates_bellman/src/groth16.rs | 16 +-- zokrates_bellman/src/lib.rs | 18 +-- zokrates_cli/src/ops/compute_witness.rs | 4 +- zokrates_cli/src/ops/generate_proof.rs | 5 +- zokrates_cli/src/ops/generate_smtlib2.rs | 4 +- zokrates_cli/src/ops/inspect.rs | 4 +- zokrates_cli/src/ops/mpc/init.rs | 5 +- zokrates_cli/src/ops/mpc/verify.rs | 5 +- zokrates_cli/src/ops/setup.rs | 10 +- zokrates_core/src/compile.rs | 18 +-- zokrates_core/src/flatten/mod.rs | 113 +++++++++------ zokrates_core/src/optimizer/canonicalizer.rs | 2 +- zokrates_core/src/optimizer/directive.rs | 8 +- zokrates_core/src/optimizer/duplicate.rs | 6 +- zokrates_core/src/optimizer/mod.rs | 6 +- zokrates_core/src/optimizer/redefinition.rs | 8 +- zokrates_core/src/optimizer/tautology.rs | 4 +- zokrates_core/src/semantics.rs | 121 ++++++++++++++-- .../src/static_analysis/flat_propagation.rs | 4 +- .../static_analysis/flatten_complex_types.rs | 101 +++++++++++++- .../src/static_analysis/propagation.rs | 32 +++++ .../src/static_analysis/zir_propagation.rs | 23 +++- zokrates_interpreter/src/lib.rs | 22 ++- zokrates_js/src/lib.rs | 5 +- zokrates_parser/src/zokrates.pest | 11 +- zokrates_pest_ast/src/lib.rs | 78 ++++++++++- zokrates_proof_systems/src/lib.rs | 22 +-- 57 files changed, 1112 insertions(+), 303 deletions(-) diff --git a/zokrates_ark/src/gm17.rs b/zokrates_ark/src/gm17.rs index 209a1abdd..0e119eee8 100644 --- a/zokrates_ark/src/gm17.rs +++ b/zokrates_ark/src/gm17.rs @@ -16,8 +16,8 @@ use zokrates_proof_systems::Scheme; use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair}; impl NonUniversalBackend for Ark { - fn setup>>( - program: ProgIterator, + fn setup<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, ) -> SetupKeypair { let computation = Computation::without_witness(program); @@ -41,8 +41,8 @@ impl NonUniversalBackend for Ark { } impl Backend for Ark { - fn generate_proof>>( - program: ProgIterator, + fn generate_proof<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, witness: Witness, proving_key: Vec, ) -> Proof { diff --git a/zokrates_ark/src/groth16.rs b/zokrates_ark/src/groth16.rs index 617d34ede..0de188453 100644 --- a/zokrates_ark/src/groth16.rs +++ b/zokrates_ark/src/groth16.rs @@ -19,8 +19,8 @@ use zokrates_proof_systems::Scheme; const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications."; impl Backend for Ark { - fn generate_proof>>( - program: ProgIterator, + fn generate_proof<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, witness: Witness, proving_key: Vec, ) -> Proof { @@ -86,8 +86,8 @@ impl Backend for Ark { } impl NonUniversalBackend for Ark { - fn setup>>( - program: ProgIterator, + fn setup<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, ) -> SetupKeypair { println!("{}", G16_WARNING); diff --git a/zokrates_ark/src/lib.rs b/zokrates_ark/src/lib.rs index f5c3b320b..425be3a8d 100644 --- a/zokrates_ark/src/lib.rs +++ b/zokrates_ark/src/lib.rs @@ -17,20 +17,20 @@ pub use self::parse::*; pub struct Ark; #[derive(Clone)] -pub struct Computation>> { - program: ProgIterator, +pub struct Computation<'a, T, I: IntoIterator>> { + program: ProgIterator<'a, T, I>, witness: Option>, } -impl>> Computation { - pub fn with_witness(program: ProgIterator, witness: Witness) -> Self { +impl<'a, T, I: IntoIterator>> Computation<'a, T, I> { + pub fn with_witness(program: ProgIterator<'a, T, I>, witness: Witness) -> Self { Computation { program, witness: Some(witness), } } - pub fn without_witness(program: ProgIterator) -> Self { + pub fn without_witness(program: ProgIterator<'a, T, I>) -> Self { Computation { program, witness: None, @@ -72,9 +72,9 @@ fn ark_combination( .fold(LinearCombination::zero(), |acc, e| acc + e) } -impl>> +impl<'a, T: Field + ArkFieldExtensions, I: IntoIterator>> ConstraintSynthesizer<<::ArkEngine as PairingEngine>::Fr> - for Computation + for Computation<'a, T, I> { fn generate_constraints( self, @@ -143,7 +143,9 @@ impl>> } } -impl>> Computation { +impl<'a, T: Field + ArkFieldExtensions, I: IntoIterator>> + Computation<'a, T, I> +{ pub fn public_inputs_values(&self) -> Vec<::Fr> { self.program .public_inputs_values(self.witness.as_ref().unwrap()) diff --git a/zokrates_ark/src/marlin.rs b/zokrates_ark/src/marlin.rs index cc85f6a24..24204a6cd 100644 --- a/zokrates_ark/src/marlin.rs +++ b/zokrates_ark/src/marlin.rs @@ -134,9 +134,9 @@ impl UniversalBackend for Ark res } - fn setup>>( + fn setup<'a, I: IntoIterator>>( srs: Vec, - program: ProgIterator, + program: ProgIterator<'a, T, I>, ) -> Result, String> { let program = program.collect(); @@ -210,8 +210,8 @@ impl UniversalBackend for Ark } impl Backend for Ark { - fn generate_proof>>( - program: ProgIterator, + fn generate_proof<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, witness: Witness, proving_key: Vec, ) -> Proof { diff --git a/zokrates_ast/src/common/embed.rs b/zokrates_ast/src/common/embed.rs index 4133c5c8a..0e8361d93 100644 --- a/zokrates_ast/src/common/embed.rs +++ b/zokrates_ast/src/common/embed.rs @@ -9,6 +9,7 @@ use crate::untyped::{ types::{UnresolvedSignature, UnresolvedType}, ConstantGenericNode, Expression, }; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use zokrates_field::Field; @@ -28,7 +29,7 @@ cfg_if::cfg_if! { /// A low level function that contains non-deterministic introduction of variables. It is carried out as is until /// the flattening step when it can be inlined. -#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Serialize, Deserialize)] pub enum FlatEmbed { BitArrayLe, Unpack, @@ -317,8 +318,8 @@ impl FlatEmbed { /// - constraint system variables /// - arguments #[cfg(feature = "bellman")] -pub fn sha256_round( -) -> FlatFunctionIterator>> { +pub fn sha256_round<'ast, T: Field>( +) -> FlatFunctionIterator<'ast, T, impl IntoIterator>> { use zokrates_field::Bn128Field; assert_eq!(T::id(), Bn128Field::id()); @@ -420,9 +421,9 @@ pub fn sha256_round( } #[cfg(feature = "ark")] -pub fn snark_verify_bls12_377( +pub fn snark_verify_bls12_377<'ast, T: Field>( n: usize, -) -> FlatFunctionIterator>> { +) -> FlatFunctionIterator<'ast, T, impl IntoIterator>> { use zokrates_field::Bw6_761Field; assert_eq!(T::id(), Bw6_761Field::id()); @@ -546,9 +547,9 @@ fn use_variable( /// # Remarks /// * the return value of the `FlatFunction` is not deterministic if `bit_width >= T::get_required_bits()` /// as some elements can have multiple representations: For example, `unpack(0)` is `[0, ..., 0]` but also `unpack(p)` -pub fn unpack_to_bitwidth( +pub fn unpack_to_bitwidth<'ast, T: Field>( bit_width: usize, -) -> FlatFunctionIterator>> { +) -> FlatFunctionIterator<'ast, T, impl IntoIterator>> { let mut counter = 0; let mut layout = HashMap::new(); diff --git a/zokrates_ast/src/common/error.rs b/zokrates_ast/src/common/error.rs index 45ef04223..b5ea381b4 100644 --- a/zokrates_ast/src/common/error.rs +++ b/zokrates_ast/src/common/error.rs @@ -3,6 +3,7 @@ use std::fmt; #[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)] pub enum RuntimeError { + UnsatisfiedConstraint, BellmanConstraint, BellmanOneBinding, BellmanInputBinding, @@ -63,6 +64,7 @@ impl fmt::Display for RuntimeError { use RuntimeError::*; let msg = match self { + UnsatisfiedConstraint => "Constraint is unsatisfied", BellmanConstraint => "Bellman constraint is unsatisfied", BellmanOneBinding => "Bellman ~one binding is unsatisfied", BellmanInputBinding => "Bellman input binding is unsatisfied", diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index d8387f26d..c3e4fe770 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -1,8 +1,9 @@ +use crate::zir::ZirFunction; use serde::{Deserialize, Serialize}; use std::fmt; #[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)] -pub enum Solver { +pub enum Solver<'ast, T> { ConditionEq, Bits(usize), Div, @@ -11,19 +12,24 @@ pub enum Solver { ShaAndXorAndXorAnd, ShaCh, EuclideanDiv, + #[serde(borrow)] + Zir(ZirFunction<'ast, T>), #[cfg(feature = "bellman")] Sha256Round, #[cfg(feature = "ark")] SnarkVerifyBls12377(usize), } -impl fmt::Display for Solver { +impl<'ast, T: fmt::Debug + fmt::Display> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) + match self { + Solver::Zir(func) => write!(f, "Zir({})", func), + _ => write!(f, "{:?}", self) + } } } -impl Solver { +impl<'ast, T> Solver<'ast, T> { pub fn get_signature(&self) -> (usize, usize) { match self { Solver::ConditionEq => (1, 2), @@ -34,6 +40,7 @@ impl Solver { Solver::ShaAndXorAndXorAnd => (3, 1), Solver::ShaCh => (3, 1), Solver::EuclideanDiv => (2, 2), + Solver::Zir(f) => (f.arguments.len(), 1), #[cfg(feature = "bellman")] Solver::Sha256Round => (768, 26935), #[cfg(feature = "ark")] @@ -42,7 +49,7 @@ impl Solver { } } -impl Solver { +impl<'ast, T> Solver<'ast, T> { pub fn bits(width: usize) -> Self { Solver::Bits(width) } diff --git a/zokrates_ast/src/flat/folder.rs b/zokrates_ast/src/flat/folder.rs index 4c9baeb00..5f8b4e394 100644 --- a/zokrates_ast/src/flat/folder.rs +++ b/zokrates_ast/src/flat/folder.rs @@ -4,8 +4,8 @@ use super::*; use crate::common::Variable; use zokrates_field::Field; -pub trait Folder: Sized { - fn fold_program(&mut self, p: FlatProg) -> FlatProg { +pub trait Folder<'ast, T: Field>: Sized { + fn fold_program(&mut self, p: FlatProg<'ast, T>) -> FlatProg<'ast, T> { fold_program(self, p) } @@ -17,7 +17,7 @@ pub trait Folder: Sized { fold_variable(self, v) } - fn fold_statement(&mut self, s: FlatStatement) -> Vec> { + fn fold_statement(&mut self, s: FlatStatement<'ast, T>) -> Vec> { fold_statement(self, s) } @@ -25,12 +25,15 @@ pub trait Folder: Sized { fold_expression(self, e) } - fn fold_directive(&mut self, d: FlatDirective) -> FlatDirective { + fn fold_directive(&mut self, d: FlatDirective<'ast, T>) -> FlatDirective<'ast, T> { fold_directive(self, d) } } -pub fn fold_program>(f: &mut F, p: FlatProg) -> FlatProg { +pub fn fold_program<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + p: FlatProg<'ast, T>, +) -> FlatProg<'ast, T> { FlatProg { arguments: p .arguments @@ -46,10 +49,10 @@ pub fn fold_program>(f: &mut F, p: FlatProg) -> FlatPr } } -pub fn fold_statement>( +pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, - s: FlatStatement, -) -> Vec> { + s: FlatStatement<'ast, T>, +) -> Vec> { match s { FlatStatement::Condition(left, right, error) => vec![FlatStatement::Condition( f.fold_expression(left), @@ -70,7 +73,7 @@ pub fn fold_statement>( } } -pub fn fold_expression>( +pub fn fold_expression<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, e: FlatExpression, ) -> FlatExpression { @@ -89,7 +92,10 @@ pub fn fold_expression>( } } -pub fn fold_directive>(f: &mut F, ds: FlatDirective) -> FlatDirective { +pub fn fold_directive<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + ds: FlatDirective<'ast, T>, +) -> FlatDirective<'ast, T> { FlatDirective { inputs: ds .inputs @@ -101,13 +107,13 @@ pub fn fold_directive>(f: &mut F, ds: FlatDirective) - } } -pub fn fold_argument>(f: &mut F, a: Parameter) -> Parameter { +pub fn fold_argument<'ast, T: Field, F: Folder<'ast, T>>(f: &mut F, a: Parameter) -> Parameter { Parameter { id: f.fold_variable(a.id), private: a.private, } } -pub fn fold_variable>(_f: &mut F, v: Variable) -> Variable { +pub fn fold_variable<'ast, T: Field, F: Folder<'ast, T>>(_f: &mut F, v: Variable) -> Variable { v } diff --git a/zokrates_ast/src/flat/mod.rs b/zokrates_ast/src/flat/mod.rs index 903fff2c4..cf38e5537 100644 --- a/zokrates_ast/src/flat/mod.rs +++ b/zokrates_ast/src/flat/mod.rs @@ -24,14 +24,14 @@ use std::collections::HashMap; use std::fmt; use zokrates_field::Field; -pub type FlatProg = FlatFunction; +pub type FlatProg<'ast, T> = FlatFunction<'ast, T>; -pub type FlatFunction = FlatFunctionIterator>>; +pub type FlatFunction<'ast, T> = FlatFunctionIterator<'ast, T, Vec>>; -pub type FlatProgIterator = FlatFunctionIterator; +pub type FlatProgIterator<'ast, T, I> = FlatFunctionIterator<'ast, T, I>; #[derive(Clone, PartialEq, Eq, Debug)] -pub struct FlatFunctionIterator>> { +pub struct FlatFunctionIterator<'ast, T, I: IntoIterator>> { /// Arguments of the function pub arguments: Vec, /// Vector of statements that are executed when running the function @@ -40,8 +40,8 @@ pub struct FlatFunctionIterator>> { pub return_count: usize, } -impl>> FlatFunctionIterator { - pub fn collect(self) -> FlatFunction { +impl<'ast, T, I: IntoIterator>> FlatFunctionIterator<'ast, T, I> { + pub fn collect(self) -> FlatFunction<'ast, T> { FlatFunction { statements: self.statements.into_iter().collect(), arguments: self.arguments, @@ -50,7 +50,7 @@ impl>> FlatFunctionIterator { } } -impl fmt::Display for FlatFunction { +impl<'ast, T: Field> fmt::Display for FlatFunction<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, @@ -81,14 +81,14 @@ impl fmt::Display for FlatFunction { /// * r1cs - R1CS in standard JSON data format #[derive(Clone, PartialEq, Eq, Debug)] -pub enum FlatStatement { +pub enum FlatStatement<'ast, T> { Condition(FlatExpression, FlatExpression, RuntimeError), Definition(Variable, FlatExpression), - Directive(FlatDirective), + Directive(FlatDirective<'ast, T>), Log(FormatString, Vec<(ConcreteType, Vec>)>), } -impl fmt::Display for FlatStatement { +impl<'ast, T: Field> fmt::Display for FlatStatement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { FlatStatement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs), @@ -116,10 +116,10 @@ impl fmt::Display for FlatStatement { } } -impl FlatStatement { +impl<'ast, T: Field> FlatStatement<'ast, T> { pub fn apply_substitution( self, - substitution: &HashMap, + substitution: &'ast HashMap, ) -> FlatStatement { match self { FlatStatement::Definition(id, x) => FlatStatement::Definition( @@ -167,16 +167,16 @@ impl FlatStatement { } #[derive(Clone, Hash, Debug, PartialEq, Eq)] -pub struct FlatDirective { +pub struct FlatDirective<'ast, T> { pub inputs: Vec>, pub outputs: Vec, - pub solver: Solver, + pub solver: Solver<'ast, T>, } -impl FlatDirective { +impl<'ast, T> FlatDirective<'ast, T> { pub fn new>>( outputs: Vec, - solver: Solver, + solver: Solver<'ast, T>, inputs: Vec, ) -> Self { let (in_len, out_len) = solver.get_signature(); @@ -190,7 +190,7 @@ impl FlatDirective { } } -impl fmt::Display for FlatDirective { +impl<'ast, T: Field> fmt::Display for FlatDirective<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, diff --git a/zokrates_ast/src/ir/check.rs b/zokrates_ast/src/ir/check.rs index 11c5fd841..41cac7b0d 100644 --- a/zokrates_ast/src/ir/check.rs +++ b/zokrates_ast/src/ir/check.rs @@ -13,7 +13,9 @@ pub struct UnconstrainedVariableDetector { } impl UnconstrainedVariableDetector { - pub fn new>>(p: &ProgIterator) -> Self { + pub fn new<'ast, T: Field, I: IntoIterator>>( + p: &ProgIterator<'ast, T, I>, + ) -> Self { UnconstrainedVariableDetector { variables: p .arguments @@ -32,7 +34,7 @@ impl UnconstrainedVariableDetector { } } -impl Folder for UnconstrainedVariableDetector { +impl<'ast, T: Field> Folder<'ast, T> for UnconstrainedVariableDetector { fn fold_argument(&mut self, p: Parameter) -> Parameter { p } @@ -40,7 +42,7 @@ impl Folder for UnconstrainedVariableDetector { self.variables.remove(&v); v } - fn fold_directive(&mut self, d: Directive) -> Directive { + fn fold_directive(&mut self, d: Directive<'ast, T>) -> Directive<'ast, T> { self.variables.extend(d.outputs.iter()); d } diff --git a/zokrates_ast/src/ir/folder.rs b/zokrates_ast/src/ir/folder.rs index 22245252b..6d1c20b9d 100644 --- a/zokrates_ast/src/ir/folder.rs +++ b/zokrates_ast/src/ir/folder.rs @@ -4,8 +4,8 @@ use super::*; use crate::common::Variable; use zokrates_field::Field; -pub trait Folder: Sized { - fn fold_program(&mut self, p: Prog) -> Prog { +pub trait Folder<'ast, T: Field>: Sized { + fn fold_program(&mut self, p: Prog<'ast, T>) -> Prog<'ast, T> { fold_program(self, p) } @@ -17,7 +17,7 @@ pub trait Folder: Sized { fold_variable(self, v) } - fn fold_statement(&mut self, s: Statement) -> Vec> { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { fold_statement(self, s) } @@ -29,12 +29,15 @@ pub trait Folder: Sized { fold_quadratic_combination(self, es) } - fn fold_directive(&mut self, d: Directive) -> Directive { + fn fold_directive(&mut self, d: Directive<'ast, T>) -> Directive<'ast, T> { fold_directive(self, d) } } -pub fn fold_program>(f: &mut F, p: Prog) -> Prog { +pub fn fold_program<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + p: Prog<'ast, T>, +) -> Prog<'ast, T> { Prog { arguments: p .arguments @@ -50,7 +53,10 @@ pub fn fold_program>(f: &mut F, p: Prog) -> Prog { } } -pub fn fold_statement>(f: &mut F, s: Statement) -> Vec> { +pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + s: Statement<'ast, T>, +) -> Vec> { match s { Statement::Constraint(quad, lin, message) => vec![Statement::Constraint( f.fold_quadratic_combination(quad), @@ -74,7 +80,10 @@ pub fn fold_statement>(f: &mut F, s: Statement) -> Vec } } -pub fn fold_linear_combination>(f: &mut F, e: LinComb) -> LinComb { +pub fn fold_linear_combination<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + e: LinComb, +) -> LinComb { LinComb( e.0.into_iter() .map(|(variable, coefficient)| (f.fold_variable(variable), coefficient)) @@ -82,7 +91,7 @@ pub fn fold_linear_combination>(f: &mut F, e: LinComb) ) } -pub fn fold_quadratic_combination>( +pub fn fold_quadratic_combination<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, e: QuadComb, ) -> QuadComb { @@ -92,7 +101,10 @@ pub fn fold_quadratic_combination>( } } -pub fn fold_directive>(f: &mut F, ds: Directive) -> Directive { +pub fn fold_directive<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + ds: Directive<'ast, T>, +) -> Directive<'ast, T> { Directive { inputs: ds .inputs @@ -104,13 +116,13 @@ pub fn fold_directive>(f: &mut F, ds: Directive) -> Di } } -pub fn fold_argument>(f: &mut F, a: Parameter) -> Parameter { +pub fn fold_argument<'ast, T: Field, F: Folder<'ast, T>>(f: &mut F, a: Parameter) -> Parameter { Parameter { id: f.fold_variable(a.id), private: a.private, } } -pub fn fold_variable>(_f: &mut F, v: Variable) -> Variable { +pub fn fold_variable<'ast, T: Field, F: Folder<'ast, T>>(_f: &mut F, v: Variable) -> Variable { v } diff --git a/zokrates_ast/src/ir/from_flat.rs b/zokrates_ast/src/ir/from_flat.rs index e5e3cb733..35acad348 100644 --- a/zokrates_ast/src/ir/from_flat.rs +++ b/zokrates_ast/src/ir/from_flat.rs @@ -17,9 +17,9 @@ impl QuadComb { } } -pub fn from_flat>>( - flat_prog_iterator: FlatProgIterator, -) -> ProgIterator>> { +pub fn from_flat<'ast, T: Field, I: IntoIterator>>( + flat_prog_iterator: FlatProgIterator<'ast, T, I>, +) -> ProgIterator>> { ProgIterator { statements: flat_prog_iterator.statements.into_iter().map(Into::into), arguments: flat_prog_iterator.arguments, @@ -52,8 +52,8 @@ impl From> for LinComb { } } -impl From> for Statement { - fn from(flat_statement: FlatStatement) -> Statement { +impl<'ast, T: Field> From> for Statement<'ast, T> { + fn from(flat_statement: FlatStatement<'ast, T>) -> Statement<'ast, T> { match flat_statement { FlatStatement::Condition(linear, quadratic, message) => match quadratic { FlatExpression::Mult(box lhs, box rhs) => Statement::Constraint( @@ -83,8 +83,8 @@ impl From> for Statement { } } -impl From> for Directive { - fn from(ds: FlatDirective) -> Directive { +impl<'ast, T: Field> From> for Directive<'ast, T> { + fn from(ds: FlatDirective<'ast, T>) -> Directive { Directive { inputs: ds .inputs diff --git a/zokrates_ast/src/ir/mod.rs b/zokrates_ast/src/ir/mod.rs index bd068b891..9e852bfc4 100644 --- a/zokrates_ast/src/ir/mod.rs +++ b/zokrates_ast/src/ir/mod.rs @@ -26,15 +26,16 @@ pub use crate::common::Variable; pub use self::witness::Witness; #[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)] -pub enum Statement { +pub enum Statement<'ast, T> { Constraint(QuadComb, LinComb, Option), - Directive(Directive), + #[serde(borrow)] + Directive(Directive<'ast, T>), Log(FormatString, Vec<(ConcreteType, Vec>)>), } pub type PublicInputs = BTreeSet; -impl Statement { +impl<'ast, T: Field> Statement<'ast, T> { pub fn definition>>(v: Variable, e: U) -> Self { Statement::Constraint(e.into(), v.into(), None) } @@ -45,13 +46,14 @@ impl Statement { } #[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)] -pub struct Directive { +pub struct Directive<'ast, T> { pub inputs: Vec>, pub outputs: Vec, - pub solver: Solver, + #[serde(borrow)] + pub solver: Solver<'ast, T>, } -impl fmt::Display for Directive { +impl<'ast, T: Field> fmt::Display for Directive<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, @@ -71,7 +73,7 @@ impl fmt::Display for Directive { } } -impl fmt::Display for Statement { +impl<'ast, T: Field> fmt::Display for Statement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Statement::Constraint(ref quad, ref lin, _) => write!(f, "{} == {}", quad, lin), @@ -96,16 +98,16 @@ impl fmt::Display for Statement { } } -pub type Prog = ProgIterator>>; +pub type Prog<'ast, T> = ProgIterator<'ast, T, Vec>>; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Default)] -pub struct ProgIterator>> { +pub struct ProgIterator<'ast, T, I: IntoIterator>> { pub arguments: Vec, pub return_count: usize, pub statements: I, } -impl>> ProgIterator { +impl<'ast, T, I: IntoIterator>> ProgIterator<'ast, T, I> { pub fn new(arguments: Vec, statements: I, return_count: usize) -> Self { Self { arguments, @@ -114,7 +116,7 @@ impl>> ProgIterator { } } - pub fn collect(self) -> ProgIterator>> { + pub fn collect(self) -> ProgIterator<'ast, T, Vec>> { ProgIterator { statements: self.statements.into_iter().collect::>(), arguments: self.arguments, @@ -139,7 +141,7 @@ impl>> ProgIterator { } } -impl>> ProgIterator { +impl<'ast, T: Field, I: IntoIterator>> ProgIterator<'ast, T, I> { pub fn public_inputs_values(&self, witness: &Witness) -> Vec { self.arguments .iter() @@ -150,7 +152,7 @@ impl>> ProgIterator { } } -impl Prog { +impl<'ast, T> Prog<'ast, T> { pub fn constraint_count(&self) -> usize { self.statements .iter() @@ -158,7 +160,9 @@ impl Prog { .count() } - pub fn into_prog_iter(self) -> ProgIterator>> { + pub fn into_prog_iter( + self, + ) -> ProgIterator<'ast, T, impl IntoIterator>> { ProgIterator { statements: self.statements.into_iter(), arguments: self.arguments, @@ -167,7 +171,7 @@ impl Prog { } } -impl fmt::Display for Prog { +impl<'ast, T: Field> fmt::Display for Prog<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let returns = (0..self.return_count) .map(Variable::public) diff --git a/zokrates_ast/src/ir/serialize.rs b/zokrates_ast/src/ir/serialize.rs index 39c746368..09d003900 100644 --- a/zokrates_ast/src/ir/serialize.rs +++ b/zokrates_ast/src/ir/serialize.rs @@ -12,32 +12,35 @@ const ZOKRATES_VERSION_2: &[u8; 4] = &[0, 0, 0, 2]; #[derive(PartialEq, Eq, Debug)] pub enum ProgEnum< - Bls12_381I: IntoIterator>, - Bn128I: IntoIterator>, - Bls12_377I: IntoIterator>, - Bw6_761I: IntoIterator>, + 'ast, + Bls12_381I: IntoIterator>, + Bn128I: IntoIterator>, + Bls12_377I: IntoIterator>, + Bw6_761I: IntoIterator>, > { - Bls12_381Program(ProgIterator), - Bn128Program(ProgIterator), - Bls12_377Program(ProgIterator), - Bw6_761Program(ProgIterator), + Bls12_381Program(ProgIterator<'ast, Bls12_381Field, Bls12_381I>), + Bn128Program(ProgIterator<'ast, Bn128Field, Bn128I>), + Bls12_377Program(ProgIterator<'ast, Bls12_377Field, Bls12_377I>), + Bw6_761Program(ProgIterator<'ast, Bw6_761Field, Bw6_761I>), } -type MemoryProgEnum = ProgEnum< - Vec>, - Vec>, - Vec>, - Vec>, +type MemoryProgEnum<'ast> = ProgEnum< + 'ast, + Vec>, + Vec>, + Vec>, + Vec>, >; impl< - Bls12_381I: IntoIterator>, - Bn128I: IntoIterator>, - Bls12_377I: IntoIterator>, - Bw6_761I: IntoIterator>, - > ProgEnum + 'ast, + Bls12_381I: IntoIterator>, + Bn128I: IntoIterator>, + Bls12_377I: IntoIterator>, + Bw6_761I: IntoIterator>, + > ProgEnum<'ast, Bls12_381I, Bn128I, Bls12_377I, Bw6_761I> { - pub fn collect(self) -> MemoryProgEnum { + pub fn collect(self) -> MemoryProgEnum<'ast> { match self { ProgEnum::Bls12_381Program(p) => ProgEnum::Bls12_381Program(p.collect()), ProgEnum::Bn128Program(p) => ProgEnum::Bn128Program(p.collect()), @@ -55,7 +58,7 @@ impl< } } -impl>> ProgIterator { +impl<'ast, T: Field, I: IntoIterator>> ProgIterator<'ast, T, I> { /// serialize a program iterator, returning the number of constraints serialized /// Note that we only return constraints, not other statements such as directives pub fn serialize(self, mut w: W) -> Result { @@ -106,10 +109,11 @@ impl<'de, R: serde_cbor::de::Read<'de>, T: serde::Deserialize<'de>> Iterator impl<'de, R: Read> ProgEnum< - UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement>, - UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement>, - UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement>, - UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement>, + 'de, + UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement<'de, Bls12_381Field>>, + UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement<'de, Bn128Field>>, + UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement<'de, Bls12_377Field>>, + UnwrappedStreamDeserializer<'de, serde_cbor::de::IoRead, Statement<'de, Bw6_761Field>>, > { pub fn deserialize(mut r: R) -> Result { diff --git a/zokrates_ast/src/ir/smtlib2.rs b/zokrates_ast/src/ir/smtlib2.rs index 8bdd04d37..1a80c8749 100644 --- a/zokrates_ast/src/ir/smtlib2.rs +++ b/zokrates_ast/src/ir/smtlib2.rs @@ -12,9 +12,9 @@ pub trait SMTLib2 { fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result; } -pub struct SMTLib2Display<'a, T>(pub &'a Prog); +pub struct SMTLib2Display<'a, 'ast, T>(pub &'a Prog<'ast, T>); -impl fmt::Display for SMTLib2Display<'_, T> { +impl<'ast, T: Field> fmt::Display for SMTLib2Display<'_, 'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.to_smtlib2(f) } @@ -30,7 +30,7 @@ impl Visitor for VariableCollector { } } -impl SMTLib2 for Prog { +impl<'ast, T: Field> SMTLib2 for Prog<'ast, T> { fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut collector = VariableCollector { variables: BTreeSet::::new(), @@ -75,7 +75,7 @@ fn format_prefix_op_smtlib2( write!(f, ")") } -impl SMTLib2 for Statement { +impl<'ast, T: Field> SMTLib2 for Statement<'ast, T> { fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Statement::Constraint(ref quad, ref lin, _) => { @@ -91,7 +91,7 @@ impl SMTLib2 for Statement { } } -impl SMTLib2 for Directive { +impl<'ast, T: Field> SMTLib2 for Directive<'ast, T> { fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "") } diff --git a/zokrates_ast/src/typed/folder.rs b/zokrates_ast/src/typed/folder.rs index e1e6d971e..c0f6daf66 100644 --- a/zokrates_ast/src/typed/folder.rs +++ b/zokrates_ast/src/typed/folder.rs @@ -260,6 +260,13 @@ pub trait Folder<'ast, T: Field>: Sized { fold_assignee(self, a) } + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> TypedAssemblyStatement<'ast, T> { + fold_assembly_statement(self, s) + } + fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec> { fold_statement(self, s) } @@ -505,6 +512,21 @@ pub fn fold_definition_rhs<'ast, T: Field, F: Folder<'ast, T>>( } } +pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + s: TypedAssemblyStatement<'ast, T>, +) -> TypedAssemblyStatement<'ast, T> { + match s { + TypedAssemblyStatement::Assignment(a, e) => { + TypedAssemblyStatement::Assignment(f.fold_assignee(a), f.fold_field_expression(e)) + } + TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( + f.fold_field_expression(lhs), + f.fold_field_expression(rhs), + ), + } +} + pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, s: TypedStatement<'ast, T>, @@ -529,6 +551,12 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( TypedStatement::Log(s, e) => { TypedStatement::Log(s, e.into_iter().map(|e| f.fold_expression(e)).collect()) } + TypedStatement::Assembly(statements) => TypedStatement::Assembly( + statements + .into_iter() + .map(|s| f.fold_assembly_statement(s)) + .collect(), + ), s => s, }; vec![res] diff --git a/zokrates_ast/src/typed/identifier.rs b/zokrates_ast/src/typed/identifier.rs index abcd2f400..772eb2bf2 100644 --- a/zokrates_ast/src/typed/identifier.rs +++ b/zokrates_ast/src/typed/identifier.rs @@ -1,10 +1,12 @@ use crate::typed::CanonicalConstantIdentifier; +use serde::{Deserialize, Serialize}; use std::fmt; -pub type SourceIdentifier<'ast> = &'ast str; +pub type SourceIdentifier<'ast> = std::borrow::Cow<'ast, str>; -#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum CoreIdentifier<'ast> { + #[serde(borrow)] Source(ShadowedIdentifier<'ast>), Call(usize), Constant(CanonicalConstantIdentifier<'ast>), @@ -29,16 +31,18 @@ impl<'ast> From> for CoreIdentifier<'ast> { } /// A identifier for a variable -#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Identifier<'ast> { /// the id of the variable + #[serde(borrow)] pub id: CoreIdentifier<'ast>, /// the version of the variable, used after SSA transformation pub version: usize, } -#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Clone, Hash, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct ShadowedIdentifier<'ast> { + #[serde(borrow)] pub id: SourceIdentifier<'ast>, pub shadow: usize, } @@ -97,7 +101,7 @@ impl<'ast> Identifier<'ast> { // these two From implementations are only used in tests but somehow cfg(test) doesn't work impl<'ast> From<&'ast str> for CoreIdentifier<'ast> { fn from(s: &str) -> CoreIdentifier { - CoreIdentifier::Source(ShadowedIdentifier::shadow(s, 0)) + CoreIdentifier::Source(ShadowedIdentifier::shadow(std::borrow::Cow::Borrowed(s), 0)) } } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index a43f59bdb..c8c8c1c6a 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -675,6 +675,28 @@ impl<'ast, T: fmt::Display> fmt::Display for DefinitionRhs<'ast, T> { } } +#[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)] +pub enum TypedAssemblyStatement<'ast, T> { + Assignment(TypedAssignee<'ast, T>, FieldElementExpression<'ast, T>), + Constraint( + FieldElementExpression<'ast, T>, + FieldElementExpression<'ast, T>, + ), +} + +impl<'ast, T: fmt::Display> fmt::Display for TypedAssemblyStatement<'ast, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + TypedAssemblyStatement::Assignment(ref lhs, ref rhs) => { + write!(f, "{} <-- {}", lhs, rhs) + } + TypedAssemblyStatement::Constraint(ref lhs, ref rhs) => { + write!(f, "{} === {}", lhs, rhs) + } + } + } +} + /// A statement in a `TypedFunction` #[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)] @@ -695,6 +717,7 @@ pub enum TypedStatement<'ast, T> { ConcreteGenericsAssignment<'ast>, ), PopCallLog, + Assembly(Vec>), } impl<'ast, T> TypedStatement<'ast, T> { @@ -719,6 +742,14 @@ impl<'ast, T: fmt::Display> TypedStatement<'ast, T> { } write!(f, "{}}}", "\t".repeat(depth)) } + TypedStatement::Assembly(statements) => { + write!(f, "{}", "\t".repeat(depth))?; + writeln!(f, "asm {{")?; + for s in statements { + writeln!(f, "{}{}", "\t".repeat(depth + 1), s)?; + } + write!(f, "{}}}", "\t".repeat(depth)) + } s => write!(f, "{}{}", "\t".repeat(depth), s), } } @@ -766,6 +797,13 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedStatement<'ast, T> { generics, ), TypedStatement::PopCallLog => write!(f, "// POP CALL",), + TypedStatement::Assembly(ref statements) => { + writeln!(f, "asm {{")?; + for s in statements { + writeln!(f, "\t\t{}", s)?; + } + write!(f, "\t}}") + } } } } @@ -1173,6 +1211,73 @@ pub enum FieldElementExpression<'ast, T> { Select(SelectExpression<'ast, T, Self>), Element(ElementExpression<'ast, T, Self>), } + +impl<'ast, T: Clone> From> for TupleExpression<'ast, T> { + fn from(assignee: TypedAssignee<'ast, T>) -> Self { + match assignee { + TypedAssignee::Identifier(v) => { + let inner = TupleExpressionInner::Identifier(v.id); + match v._type { + GType::Tuple(tuple_ty) => inner.annotate(tuple_ty), + _ => unreachable!(), + } + } + TypedAssignee::Select(box a, box index) => TupleExpression::select(a.into(), index), + TypedAssignee::Member(box a, id) => TupleExpression::member(a.into(), id), + TypedAssignee::Element(box a, index) => TupleExpression::element(a.into(), index), + } + } +} + +impl<'ast, T: Clone> From> for StructExpression<'ast, T> { + fn from(assignee: TypedAssignee<'ast, T>) -> Self { + match assignee { + TypedAssignee::Identifier(v) => { + let inner = StructExpressionInner::Identifier(v.id); + match v._type { + GType::Struct(struct_ty) => inner.annotate(struct_ty), + _ => unreachable!(), + } + } + TypedAssignee::Select(box a, box index) => StructExpression::select(a.into(), index), + TypedAssignee::Member(box a, id) => StructExpression::member(a.into(), id), + TypedAssignee::Element(box a, index) => StructExpression::element(a.into(), index), + } + } +} + +impl<'ast, T: Clone> From> for ArrayExpression<'ast, T> { + fn from(assignee: TypedAssignee<'ast, T>) -> Self { + match assignee { + TypedAssignee::Identifier(v) => { + let inner = ArrayExpressionInner::Identifier(v.id); + match v._type { + GType::Array(array_ty) => inner.annotate(*array_ty.ty, *array_ty.size), + _ => unreachable!(), + } + } + TypedAssignee::Select(box a, box index) => ArrayExpression::select(a.into(), index), + TypedAssignee::Member(box a, id) => ArrayExpression::member(a.into(), id), + TypedAssignee::Element(box a, index) => ArrayExpression::element(a.into(), index), + } + } +} + +impl<'ast, T: Clone> From> for FieldElementExpression<'ast, T> { + fn from(assignee: TypedAssignee<'ast, T>) -> Self { + match assignee { + TypedAssignee::Identifier(v) => FieldElementExpression::Identifier(v.id), + TypedAssignee::Element(box a, index) => { + FieldElementExpression::element(a.into(), index) + } + TypedAssignee::Member(box a, id) => FieldElementExpression::member(a.into(), id), + TypedAssignee::Select(box a, box index) => { + FieldElementExpression::select(a.into(), index) + } + } + } +} + impl<'ast, T> Add for FieldElementExpression<'ast, T> { type Output = Self; @@ -1209,6 +1314,9 @@ impl<'ast, T> FieldElementExpression<'ast, T> { pub fn pow(self, other: UExpression<'ast, T>) -> Self { FieldElementExpression::Pow(box self, box other) } + pub fn is_quadratic(&self) -> bool { + true // TODO: implement + } } impl<'ast, T> From for FieldElementExpression<'ast, T> { diff --git a/zokrates_ast/src/typed/result_folder.rs b/zokrates_ast/src/typed/result_folder.rs index fe6cd1577..7732bc391 100644 --- a/zokrates_ast/src/typed/result_folder.rs +++ b/zokrates_ast/src/typed/result_folder.rs @@ -378,6 +378,13 @@ pub trait ResultFolder<'ast, T: Field>: Sized { fold_assignee(self, a) } + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + fold_assembly_statement(self, s) + } + fn fold_statement( &mut self, s: TypedStatement<'ast, T>, @@ -508,6 +515,21 @@ pub trait ResultFolder<'ast, T: Field>: Sized { } } +pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( + f: &mut F, + s: TypedAssemblyStatement<'ast, T>, +) -> Result, F::Error> { + Ok(match s { + TypedAssemblyStatement::Assignment(a, e) => { + TypedAssemblyStatement::Assignment(f.fold_assignee(a)?, f.fold_field_expression(e)?) + } + TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( + f.fold_field_expression(lhs)?, + f.fold_field_expression(rhs)?, + ), + }) +} + pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( f: &mut F, s: TypedStatement<'ast, T>, @@ -538,6 +560,12 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( .map(|e| f.fold_expression(e)) .collect::, _>>()?, ), + TypedStatement::Assembly(statements) => TypedStatement::Assembly( + statements + .into_iter() + .map(|s| f.fold_assembly_statement(s)) + .collect::, _>>()?, + ), s => s, }; Ok(vec![res]) diff --git a/zokrates_ast/src/typed/types.rs b/zokrates_ast/src/typed/types.rs index 6d29da5cb..8bd863f9a 100644 --- a/zokrates_ast/src/typed/types.rs +++ b/zokrates_ast/src/typed/types.rs @@ -51,7 +51,7 @@ pub struct GenericIdentifier<'ast> { impl<'ast> From> for CoreIdentifier<'ast> { fn from(g: GenericIdentifier<'ast>) -> CoreIdentifier<'ast> { // generic identifiers are always declared in the function scope, which is shadow 0 - CoreIdentifier::Source(ShadowedIdentifier::shadow(g.name(), 0)) + CoreIdentifier::Source(ShadowedIdentifier::shadow(std::borrow::Cow::Borrowed(g.name()), 0)) } } @@ -119,9 +119,10 @@ pub struct SpecializationError; pub type ConstantIdentifier<'ast> = &'ast str; -#[derive(Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Debug, Hash, PartialOrd, Ord, Serialize, Deserialize)] pub struct CanonicalConstantIdentifier<'ast> { pub module: OwnedTypedModuleId, + #[serde(borrow)] pub id: ConstantIdentifier<'ast>, } diff --git a/zokrates_ast/src/untyped/from_ast.rs b/zokrates_ast/src/untyped/from_ast.rs index 349a03dc4..b37af590a 100644 --- a/zokrates_ast/src/untyped/from_ast.rs +++ b/zokrates_ast/src/untyped/from_ast.rs @@ -280,6 +280,7 @@ impl<'ast> From> for untyped::StatementNode<'ast> { pest::Statement::Assertion(s) => untyped::StatementNode::from(s), pest::Statement::Return(s) => untyped::StatementNode::from(s), pest::Statement::Log(s) => untyped::StatementNode::from(s), + pest::Statement::Assembly(s) => untyped::StatementNode::from(s), } } } @@ -343,6 +344,32 @@ impl<'ast> From> for untyped::StatementNode<'ast> } } +impl<'ast> From> for untyped::StatementNode<'ast> { + fn from(statement: pest::AssemblyStatement<'ast>) -> untyped::StatementNode<'ast> { + use crate::untyped::NodeValue; + + let statements = statement + .inner + .into_iter() + .map(|s| match s { + pest::AssemblyStatementInner::Assignment(a) => { + untyped::AssemblyStatement::Assignment( + a.assignee.into(), + a.expression.into(), + matches!(a.operator, pest::AssignmentOperator::AssignConstrain), + ) + .span(a.span) + } + pest::AssemblyStatementInner::Constraint(c) => { + untyped::AssemblyStatement::Constraint(c.lhs.into(), c.rhs.into()).span(c.span) + } + }) + .collect(); + + untyped::Statement::Assembly(statements).span(statement.span) + } +} + impl<'ast> From> for untyped::ExpressionNode<'ast> { fn from(expression: pest::Expression<'ast>) -> untyped::ExpressionNode<'ast> { match expression { diff --git a/zokrates_ast/src/untyped/mod.rs b/zokrates_ast/src/untyped/mod.rs index 8fabc2ec5..07541edec 100644 --- a/zokrates_ast/src/untyped/mod.rs +++ b/zokrates_ast/src/untyped/mod.rs @@ -382,6 +382,33 @@ impl<'ast> fmt::Display for Assignee<'ast> { } } +#[derive(Debug, Clone, PartialEq)] +pub enum AssemblyStatement<'ast> { + Assignment(AssigneeNode<'ast>, ExpressionNode<'ast>, bool), + Constraint(ExpressionNode<'ast>, ExpressionNode<'ast>), +} + +pub type AssemblyStatementNode<'ast> = Node>; + +impl<'ast> fmt::Display for AssemblyStatement<'ast> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + AssemblyStatement::Assignment(ref lhs, ref rhs, ref constrained) => { + write!( + f, + "{} <{} {}", + lhs, + if *constrained { "==" } else { "--" }, + rhs + ) + } + AssemblyStatement::Constraint(ref lhs, ref rhs) => { + write!(f, "{} === {}", lhs, rhs) + } + } + } +} + /// A statement in a `Function` #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, PartialEq)] @@ -397,6 +424,7 @@ pub enum Statement<'ast> { Vec>, ), Log(&'ast str, Vec>), + Assembly(Vec>), } pub type StatementNode<'ast> = Node>; @@ -431,7 +459,7 @@ impl<'ast> fmt::Display for Statement<'ast> { } Statement::Log(ref l, ref expressions) => write!( f, - "log({}, {})", + "log({}, {});", l, expressions .iter() @@ -439,6 +467,13 @@ impl<'ast> fmt::Display for Statement<'ast> { .collect::>() .join(", ") ), + Statement::Assembly(ref statements) => { + writeln!(f, "asm {{")?; + for s in statements { + writeln!(f, "\t\t{};", s)?; + } + write!(f, "\t}}") + } } } } diff --git a/zokrates_ast/src/untyped/node.rs b/zokrates_ast/src/untyped/node.rs index 44cda49f9..62ef299df 100644 --- a/zokrates_ast/src/untyped/node.rs +++ b/zokrates_ast/src/untyped/node.rs @@ -84,6 +84,7 @@ use super::*; impl<'ast> NodeValue for Expression<'ast> {} impl<'ast> NodeValue for Assignee<'ast> {} impl<'ast> NodeValue for Statement<'ast> {} +impl<'ast> NodeValue for AssemblyStatement<'ast> {} impl<'ast> NodeValue for SymbolDeclaration<'ast> {} impl<'ast> NodeValue for UnresolvedType<'ast> {} impl<'ast> NodeValue for StructDefinition<'ast> {} diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index f934ed3c7..6523e2f8d 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -56,6 +56,13 @@ pub trait Folder<'ast, T: Field>: Sized { self.fold_variable(a) } + fn fold_assembly_statement( + &mut self, + s: ZirAssemblyStatement<'ast, T>, + ) -> ZirAssemblyStatement<'ast, T> { + fold_assembly_statement(self, s) + } + fn fold_statement(&mut self, s: ZirStatement<'ast, T>) -> Vec> { fold_statement(self, s) } @@ -127,6 +134,24 @@ pub trait Folder<'ast, T: Field>: Sized { } } +pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( + f: &mut F, + s: ZirAssemblyStatement<'ast, T>, +) -> ZirAssemblyStatement<'ast, T> { + match s { + ZirAssemblyStatement::Assignment(assignees, function) => { + let assignees = assignees.into_iter().map(|a| f.fold_assignee(a)).collect(); + let function = f.fold_function(function); + ZirAssemblyStatement::Assignment(assignees, function) + } + ZirAssemblyStatement::Constraint(lhs, rhs) => { + let lhs = f.fold_field_expression(lhs); + let rhs = f.fold_field_expression(rhs); + ZirAssemblyStatement::Constraint(lhs, rhs) + } + } +} + pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, s: ZirStatement<'ast, T>, @@ -165,6 +190,12 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( .map(|(t, e)| (t, e.into_iter().map(|e| f.fold_expression(e)).collect())) .collect(), ), + ZirStatement::Assembly(statements) => ZirStatement::Assembly( + statements + .into_iter() + .map(|s| f.fold_assembly_statement(s)) + .collect(), + ), }; vec![res] } diff --git a/zokrates_ast/src/zir/identifier.rs b/zokrates_ast/src/zir/identifier.rs index aae839d30..249b2630e 100644 --- a/zokrates_ast/src/zir/identifier.rs +++ b/zokrates_ast/src/zir/identifier.rs @@ -1,15 +1,18 @@ use crate::zir::types::MemberId; +use serde::{Deserialize, Serialize}; use std::fmt; use crate::typed::Identifier as CoreIdentifier; -#[derive(Debug, PartialEq, Clone, Hash, Eq)] +#[derive(Debug, PartialEq, Clone, Hash, Eq, Serialize, Deserialize)] pub enum Identifier<'ast> { + #[serde(borrow)] Source(SourceIdentifier<'ast>), } -#[derive(Debug, PartialEq, Clone, Hash, Eq)] +#[derive(Debug, PartialEq, Clone, Hash, Eq, Serialize, Deserialize)] pub enum SourceIdentifier<'ast> { + #[serde(borrow)] Basic(CoreIdentifier<'ast>), Select(Box>, u32), Member(Box>, MemberId), diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index d2cbf6330..c1752b526 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -21,6 +21,7 @@ use zokrates_field::Field; pub use self::folder::Folder; pub use self::identifier::{Identifier, SourceIdentifier}; +use serde::{Deserialize, Serialize}; /// A typed program as a collection of modules, one of them being the main #[derive(PartialEq, Eq, Debug, Clone)] @@ -34,11 +35,13 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirProgram<'ast, T> { } } /// A typed function -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub struct ZirFunction<'ast, T> { /// Arguments of the function + #[serde(borrow)] pub arguments: Vec>, /// Vector of statements that are executed when running the function + #[serde(borrow)] pub statements: Vec>, /// function signature pub signature: Signature, @@ -88,7 +91,7 @@ impl<'ast, T: fmt::Debug> fmt::Debug for ZirFunction<'ast, T> { pub type ZirAssignee<'ast> = Variable<'ast>; -#[derive(Debug, Clone, PartialEq, Hash, Eq)] +#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub enum RuntimeError { SourceAssertion(String), SelectRangeCheck, @@ -113,8 +116,70 @@ impl RuntimeError { } } +// #[derive(Clone, PartialEq, Hash, Eq, Debug)] +// pub struct ZirBlock<'ast, T> { +// pub statements: Vec>, +// pub value: FieldElementExpression<'ast, T>, +// } +// +// impl<'ast, T> ZirBlock<'ast, T> { +// pub fn new( +// statements: Vec>, +// value: FieldElementExpression<'ast, T>, +// ) -> Self { +// Self { statements, value } +// } +// } +// impl<'ast, T: fmt::Display> fmt::Display for ZirBlock<'ast, T> { +// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +// write!( +// f, +// "{{\n{}\n}}", +// self.statements +// .iter() +// .map(|s| s.to_string()) +// .chain(std::iter::once(self.value.to_string())) +// .collect::>() +// .join("\n") +// ) +// } +// } + +#[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] +pub enum ZirAssemblyStatement<'ast, T> { + Assignment( + #[serde(borrow)] Vec>, + ZirFunction<'ast, T>, + ), + Constraint( + FieldElementExpression<'ast, T>, + FieldElementExpression<'ast, T>, + ), +} + +impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ZirAssemblyStatement::Assignment(ref lhs, ref rhs) => { + write!( + f, + "{} <-- {}", + lhs.iter() + .map(|a| a.id.to_string()) + .collect::>() + .join(", "), + rhs + ) + } + ZirAssemblyStatement::Constraint(ref lhs, ref rhs) => { + write!(f, "{} === {}", lhs, rhs) + } + } + } +} + /// A statement in a `ZirFunction` -#[derive(Clone, PartialEq, Hash, Eq, Debug)] +#[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum ZirStatement<'ast, T> { Return(Vec>), Definition(ZirAssignee<'ast>, ZirExpression<'ast, T>), @@ -129,6 +194,7 @@ pub enum ZirStatement<'ast, T> { FormatString, Vec<(ConcreteType, Vec>)>, ), + Assembly(#[serde(borrow)] Vec>), } impl<'ast, T: fmt::Display> fmt::Display for ZirStatement<'ast, T> { @@ -142,15 +208,19 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> { write!(f, "{}", "\t".repeat(depth))?; match self { ZirStatement::Return(ref exprs) => { - write!( - f, - "return {};", - exprs - .iter() - .map(|e| e.to_string()) - .collect::>() - .join(", ") - ) + write!(f, "return")?; + if exprs.len() > 0 { + write!( + f, + " {}", + exprs + .iter() + .map(|e| e.to_string()) + .collect::>() + .join(", ") + )?; + } + write!(f, ";") } ZirStatement::Definition(ref lhs, ref rhs) => { write!(f, "{} = {};", lhs, rhs) @@ -166,7 +236,7 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> { s.fmt_indented(f, depth + 1)?; writeln!(f)?; } - write!(f, "{}}};", "\t".repeat(depth)) + write!(f, "{}}}", "\t".repeat(depth)) } ZirStatement::Assertion(ref e, ref error) => { write!(f, "assert({}", e)?; @@ -200,6 +270,13 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> { .collect::>() .join(", ") ), + ZirStatement::Assembly(statements) => { + writeln!(f, "asm {{")?; + for s in statements { + writeln!(f, "{}{}", "\t".repeat(depth + 1), s)?; + } + write!(f, "{}}}", "\t".repeat(depth)) + } } } } @@ -208,8 +285,9 @@ pub trait Typed { fn get_type(&self) -> Type; } -#[derive(Debug, Clone, PartialEq, Hash, Eq)] +#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub struct ConditionalExpression<'ast, T, E> { + #[serde(borrow)] pub condition: Box>, pub consequence: Box, pub alternative: Box, @@ -235,9 +313,10 @@ impl<'ast, T: fmt::Display, E: fmt::Display> fmt::Display for ConditionalExpress } } -#[derive(Debug, Clone, PartialEq, Hash, Eq)] +#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub struct SelectExpression<'ast, T, E> { pub array: Vec, + #[serde(borrow)] pub index: Box>, } @@ -266,11 +345,11 @@ impl<'ast, T: fmt::Display, E: fmt::Display> fmt::Display for SelectExpression<' } /// A typed expression -#[derive(Clone, PartialEq, Hash, Eq)] +#[derive(Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub enum ZirExpression<'ast, T> { Boolean(BooleanExpression<'ast, T>), FieldElement(FieldElementExpression<'ast, T>), - Uint(UExpression<'ast, T>), + Uint(#[serde(borrow)] UExpression<'ast, T>), } impl<'ast, T: Field> From> for ZirExpression<'ast, T> { @@ -343,15 +422,20 @@ pub trait MultiTyped { fn get_types(&self) -> &Vec; } -#[derive(Clone, PartialEq, Hash, Eq)] +#[derive(Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub enum ZirExpressionList<'ast, T> { - EmbedCall(FlatEmbed, Vec, Vec>), + EmbedCall( + FlatEmbed, + Vec, + #[serde(borrow)] Vec>, + ), } /// An expression of type `field` -#[derive(Clone, PartialEq, Hash, Eq, Debug)] +#[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum FieldElementExpression<'ast, T> { Number(T), + #[serde(borrow)] Identifier(Identifier<'ast>), Select(SelectExpression<'ast, T, Self>), Add( @@ -372,15 +456,16 @@ pub enum FieldElementExpression<'ast, T> { ), Pow( Box>, - Box>, + #[serde(borrow)] Box>, ), Conditional(ConditionalExpression<'ast, T, FieldElementExpression<'ast, T>>), } /// An expression of type `bool` -#[derive(Clone, PartialEq, Hash, Eq, Debug)] +#[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum BooleanExpression<'ast, T> { Value(bool), + #[serde(borrow)] Identifier(Identifier<'ast>), Select(SelectExpression<'ast, T, Self>), FieldLt( diff --git a/zokrates_ast/src/zir/parameter.rs b/zokrates_ast/src/zir/parameter.rs index 08d26c935..203a291a7 100644 --- a/zokrates_ast/src/zir/parameter.rs +++ b/zokrates_ast/src/zir/parameter.rs @@ -1,8 +1,10 @@ use crate::zir::Variable; +use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub struct Parameter<'ast> { + #[serde(borrow)] pub id: Variable<'ast>, pub private: bool, } diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 6b172ff84..16f78f019 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -61,6 +61,13 @@ pub trait ResultFolder<'ast, T: Field>: Sized { self.fold_variable(a) } + fn fold_assembly_statement( + &mut self, + s: ZirAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + fold_assembly_statement(self, s) + } + fn fold_statement( &mut self, s: ZirStatement<'ast, T>, @@ -144,6 +151,26 @@ pub trait ResultFolder<'ast, T: Field>: Sized { fold_uint_expression_inner(self, bitwidth, e) } } +pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( + f: &mut F, + s: ZirAssemblyStatement<'ast, T>, +) -> Result, F::Error> { + Ok(match s { + ZirAssemblyStatement::Assignment(assignees, function) => { + let assignees = assignees + .into_iter() + .map(|a| f.fold_assignee(a)) + .collect::, _>>()?; + let function = f.fold_function(function)?; + ZirAssemblyStatement::Assignment(assignees, function) + } + ZirAssemblyStatement::Constraint(lhs, rhs) => { + let lhs = f.fold_field_expression(lhs)?; + let rhs = f.fold_field_expression(rhs)?; + ZirAssemblyStatement::Constraint(lhs, rhs) + } + }) +} pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( f: &mut F, @@ -199,6 +226,13 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( ZirStatement::Log(l, e) } + ZirStatement::Assembly(statements) => { + let statements = statements + .into_iter() + .map(|s| f.fold_assembly_statement(s)) + .collect::, _>>()?; + ZirStatement::Assembly(statements) + } }; Ok(vec![res]) } diff --git a/zokrates_ast/src/zir/uint.rs b/zokrates_ast/src/zir/uint.rs index 5d09b4285..12619b5c4 100644 --- a/zokrates_ast/src/zir/uint.rs +++ b/zokrates_ast/src/zir/uint.rs @@ -1,5 +1,6 @@ use crate::zir::identifier::Identifier; use crate::zir::types::UBitwidth; +use serde::{Deserialize, Serialize}; use zokrates_field::Field; use super::{ConditionalExpression, SelectExpression}; @@ -91,7 +92,7 @@ impl<'ast, T> From for UExpression<'ast, T> { } } -#[derive(Debug, PartialEq, Eq, Clone, Hash)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] pub enum ShouldReduce { Unknown, True, @@ -135,7 +136,7 @@ impl ShouldReduce { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct UMetadata { pub max: T, pub should_reduce: ShouldReduce, @@ -162,16 +163,18 @@ impl UMetadata { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct UExpression<'ast, T> { pub bitwidth: UBitwidth, pub metadata: Option>, + #[serde(borrow)] pub inner: UExpressionInner<'ast, T>, } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum UExpressionInner<'ast, T> { Value(u128), + #[serde(borrow)] Identifier(Identifier<'ast>), Select(SelectExpression<'ast, T, UExpression<'ast, T>>), Add(Box>, Box>), diff --git a/zokrates_ast/src/zir/variable.rs b/zokrates_ast/src/zir/variable.rs index 91fda8c72..14d329727 100644 --- a/zokrates_ast/src/zir/variable.rs +++ b/zokrates_ast/src/zir/variable.rs @@ -1,9 +1,11 @@ use crate::zir::types::{Type, UBitwidth}; use crate::zir::Identifier; +use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Hash, Eq)] +#[derive(Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub struct Variable<'ast> { + #[serde(borrow)] pub id: Identifier<'ast>, pub _type: Type, } diff --git a/zokrates_bellman/src/groth16.rs b/zokrates_bellman/src/groth16.rs index c918ccf5d..79d699ee4 100644 --- a/zokrates_bellman/src/groth16.rs +++ b/zokrates_bellman/src/groth16.rs @@ -21,8 +21,8 @@ use zokrates_proof_systems::Scheme; const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications."; impl Backend for Bellman { - fn generate_proof>>( - program: ProgIterator, + fn generate_proof<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, witness: Witness, proving_key: Vec, ) -> Proof { @@ -84,8 +84,8 @@ impl Backend for Bellman { } impl NonUniversalBackend for Bellman { - fn setup>>( - program: ProgIterator, + fn setup<'a, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, ) -> SetupKeypair { println!("{}", G16_WARNING); @@ -99,8 +99,8 @@ impl NonUniversalBackend for Bellman } impl MpcBackend for Bellman { - fn initialize>>( - program: ProgIterator, + fn initialize<'a, R: Read, W: Write, I: IntoIterator>>( + program: ProgIterator<'a, T, I>, phase1_radix: &mut R, output: &mut W, ) -> Result<(), String> { @@ -124,9 +124,9 @@ impl MpcBackend for Bellman { Ok(hash) } - fn verify>>( + fn verify<'a, P: Read, R: Read, I: IntoIterator>>( params: &mut P, - program: ProgIterator, + program: ProgIterator<'a, T, I>, phase1_radix: &mut R, ) -> Result, String> { let params = diff --git a/zokrates_bellman/src/lib.rs b/zokrates_bellman/src/lib.rs index 4bf396245..26bcf392e 100644 --- a/zokrates_bellman/src/lib.rs +++ b/zokrates_bellman/src/lib.rs @@ -22,20 +22,20 @@ pub use self::parse::*; pub struct Bellman; #[derive(Clone)] -pub struct Computation>> { - program: ProgIterator, +pub struct Computation<'a, T, I: IntoIterator>> { + program: ProgIterator<'a, T, I>, witness: Option>, } -impl>> Computation { - pub fn with_witness(program: ProgIterator, witness: Witness) -> Self { +impl<'a, T: Field, I: IntoIterator>> Computation<'a, T, I> { + pub fn with_witness(program: ProgIterator<'a, T, I>, witness: Witness) -> Self { Computation { program, witness: Some(witness), } } - pub fn without_witness(program: ProgIterator) -> Self { + pub fn without_witness(program: ProgIterator<'a, T, I>) -> Self { Computation { program, witness: None, @@ -83,8 +83,8 @@ fn bellman_combination>> - Circuit for Computation +impl<'a, T: BellmanFieldExtensions + Field, I: IntoIterator>> + Circuit for Computation<'a, T, I> { fn synthesize>( self, @@ -148,7 +148,9 @@ impl>> } } -impl>> Computation { +impl<'a, T: BellmanFieldExtensions + Field, I: IntoIterator>> + Computation<'a, T, I> +{ fn get_random_seed(&self) -> Result<[u32; 8], getrandom::Error> { let mut seed = [0u8; 32]; getrandom::getrandom(&mut seed)?; diff --git a/zokrates_cli/src/ops/compute_witness.rs b/zokrates_cli/src/ops/compute_witness.rs index 865f3c9b4..ab2a959bd 100644 --- a/zokrates_cli/src/ops/compute_witness.rs +++ b/zokrates_cli/src/ops/compute_witness.rs @@ -85,8 +85,8 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } } -fn cli_compute>>( - ir_prog: ir::ProgIterator, +fn cli_compute<'a, T: Field, I: Iterator>>( + ir_prog: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Computing witness..."); diff --git a/zokrates_cli/src/ops/generate_proof.rs b/zokrates_cli/src/ops/generate_proof.rs index 2a62042a4..319cf561c 100644 --- a/zokrates_cli/src/ops/generate_proof.rs +++ b/zokrates_cli/src/ops/generate_proof.rs @@ -136,12 +136,13 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } fn cli_generate_proof< + 'a, T: Field, - I: Iterator>, + I: Iterator>, S: Scheme, B: Backend, >( - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Generating proof..."); diff --git a/zokrates_cli/src/ops/generate_smtlib2.rs b/zokrates_cli/src/ops/generate_smtlib2.rs index b1bf6f6a8..ac58f8e56 100644 --- a/zokrates_cli/src/ops/generate_smtlib2.rs +++ b/zokrates_cli/src/ops/generate_smtlib2.rs @@ -47,8 +47,8 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } } -fn cli_smtlib2>>( - ir_prog: ir::ProgIterator, +fn cli_smtlib2<'a, T: Field, I: Iterator>>( + ir_prog: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Generating SMTLib2..."); diff --git a/zokrates_cli/src/ops/inspect.rs b/zokrates_cli/src/ops/inspect.rs index 523d664a4..338c01c41 100644 --- a/zokrates_cli/src/ops/inspect.rs +++ b/zokrates_cli/src/ops/inspect.rs @@ -43,8 +43,8 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } } -fn cli_inspect>>( - ir_prog: ir::ProgIterator, +fn cli_inspect<'a, T: Field, I: Iterator>>( + ir_prog: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { let ir_prog: ir::Prog = ir_prog.collect(); diff --git a/zokrates_cli/src/ops/mpc/init.rs b/zokrates_cli/src/ops/mpc/init.rs index 71136366c..eb7ba16e4 100644 --- a/zokrates_cli/src/ops/mpc/init.rs +++ b/zokrates_cli/src/ops/mpc/init.rs @@ -58,12 +58,13 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } fn cli_mpc_init< + 'a, T: Field + BellmanFieldExtensions, - I: Iterator>, + I: Iterator>, S: MpcScheme, B: MpcBackend, >( - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Initializing MPC..."); diff --git a/zokrates_cli/src/ops/mpc/verify.rs b/zokrates_cli/src/ops/mpc/verify.rs index 6beca03db..fa014bd06 100644 --- a/zokrates_cli/src/ops/mpc/verify.rs +++ b/zokrates_cli/src/ops/mpc/verify.rs @@ -58,12 +58,13 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } fn cli_mpc_verify< + 'a, T: Field + BellmanFieldExtensions, - I: Iterator>, + I: Iterator>, S: MpcScheme, B: MpcBackend, >( - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Verifying contributions..."); diff --git a/zokrates_cli/src/ops/setup.rs b/zokrates_cli/src/ops/setup.rs index e9e8a2166..0fc569538 100644 --- a/zokrates_cli/src/ops/setup.rs +++ b/zokrates_cli/src/ops/setup.rs @@ -167,12 +167,13 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { } fn cli_setup_non_universal< + 'a, T: Field, - I: Iterator>, + I: Iterator>, S: NonUniversalScheme, B: NonUniversalBackend, >( - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, sub_matches: &ArgMatches, ) -> Result<(), String> { println!("Performing setup..."); @@ -211,12 +212,13 @@ fn cli_setup_non_universal< } fn cli_setup_universal< + 'a, T: Field, - I: Iterator>, + I: Iterator>, S: UniversalScheme, B: UniversalBackend, >( - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, srs: Vec, sub_matches: &ArgMatches, ) -> Result<(), String> { diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index 68f35560d..a50b57b39 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -25,13 +25,13 @@ use zokrates_field::Field; use zokrates_pest_ast as pest; #[derive(Debug)] -pub struct CompilationArtifacts>> { - prog: ir::ProgIterator, +pub struct CompilationArtifacts<'ast, T, I: IntoIterator>> { + prog: ir::ProgIterator<'ast, T, I>, abi: Abi, } -impl>> CompilationArtifacts { - pub fn prog(self) -> ir::ProgIterator { +impl<'ast, T, I: IntoIterator>> CompilationArtifacts<'ast, T, I> { + pub fn prog(self) -> ir::ProgIterator<'ast, T, I> { self.prog } @@ -39,11 +39,11 @@ impl>> CompilationArtifacts { &self.abi } - pub fn into_inner(self) -> (ir::ProgIterator, Abi) { + pub fn into_inner(self) -> (ir::ProgIterator<'ast, T, I>, Abi) { (self.prog, self.abi) } - pub fn collect(self) -> CompilationArtifacts>> { + pub fn collect(self) -> CompilationArtifacts<'ast, T, Vec>> { CompilationArtifacts { prog: self.prog.collect(), abi: self.abi, @@ -201,8 +201,10 @@ pub fn compile<'ast, T: Field, E: Into>( resolver: Option<&dyn Resolver>, config: CompileConfig, arena: &'ast Arena, -) -> Result> + 'ast>, CompileErrors> -{ +) -> Result< + CompilationArtifacts<'ast, T, impl IntoIterator> + 'ast>, + CompileErrors, +> { let (typed_ast, abi): (zokrates_ast::zir::ZirProgram<'_, T>, _) = check_with_arena(source, location, resolver, &config, arena)?; diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index cd2e455c6..8168aee65 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -9,7 +9,8 @@ mod utils; use self::utils::flat_expression_from_bits; use zokrates_ast::zir::{ - ConditionalExpression, SelectExpression, ShouldReduce, UMetadata, ZirExpressionList, + ConditionalExpression, SelectExpression, ShouldReduce, UMetadata, ZirAssemblyStatement, + ZirExpressionList, }; use zokrates_interpreter::Interpreter; @@ -32,7 +33,7 @@ use zokrates_ast::zir::{ }; use zokrates_field::Field; -type FlatStatements = VecDeque>; +type FlatStatements<'ast, T> = VecDeque>; /// Flattens a function /// @@ -64,14 +65,14 @@ pub fn from_function_and_config( pub struct FlattenerIteratorInner<'ast, T> { pub statements: VecDeque>, - pub statements_flattened: FlatStatements, + pub statements_flattened: FlatStatements<'ast, T>, pub flattener: Flattener<'ast, T>, } -pub type FlattenerIterator<'ast, T> = FlatProgIterator>; +pub type FlattenerIterator<'ast, T> = FlatProgIterator<'ast, T, FlattenerIteratorInner<'ast, T>>; impl<'ast, T: Field> Iterator for FlattenerIteratorInner<'ast, T> { - type Item = FlatStatement; + type Item = FlatStatement<'ast, T>; fn next(&mut self) -> Option { while self.statements_flattened.is_empty() { @@ -127,7 +128,7 @@ trait Flatten<'ast, T: Field>: fn flatten( self, flattener: &mut Flattener<'ast, T>, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Self::Output; } @@ -137,7 +138,7 @@ impl<'ast, T: Field> Flatten<'ast, T> for FieldElementExpression<'ast, T> { fn flatten( self, flattener: &mut Flattener<'ast, T>, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Self::Output { flattener.flatten_field_expression(statements_flattened, self) } @@ -149,7 +150,7 @@ impl<'ast, T: Field> Flatten<'ast, T> for UExpression<'ast, T> { fn flatten( self, flattener: &mut Flattener<'ast, T>, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Self::Output { flattener.flatten_uint_expression(statements_flattened, self) } @@ -161,7 +162,7 @@ impl<'ast, T: Field> Flatten<'ast, T> for BooleanExpression<'ast, T> { fn flatten( self, flattener: &mut Flattener<'ast, T>, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Self::Output { flattener.flatten_boolean_expression(statements_flattened, self) } @@ -227,7 +228,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn define( &mut self, e: FlatExpression, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Variable { match e { FlatExpression::Identifier(id) => id, @@ -276,7 +277,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { #[must_use] fn constant_le_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, a: &[FlatExpression], b: &[bool], ) -> Vec> { @@ -381,7 +382,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * A FlatExpression which evaluates to `1` if `left == right`, `0` otherwise fn eq_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, left: FlatExpression, right: FlatExpression, ) -> FlatExpression { @@ -434,7 +435,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `b` - the big-endian bit decomposition of the upper bound of the range fn enforce_constant_le_check_bits( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, a: &[FlatExpression], c: &[bool], error: RuntimeError, @@ -464,7 +465,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `c` - the constant upper bound of the range fn enforce_constant_le_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: FlatExpression, c: T, error: RuntimeError, @@ -500,7 +501,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `c` - the constant upper bound of the range fn enforce_constant_lt_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: FlatExpression, c: T, error: RuntimeError, @@ -519,9 +520,9 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn make_conditional( &mut self, - statements: FlatStatements, + statements: FlatStatements<'ast, T>, condition: FlatExpression, - ) -> FlatStatements { + ) -> FlatStatements<'ast, T> { statements .into_iter() .flat_map(|s| match s { @@ -582,7 +583,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * U is the type of the expression fn flatten_conditional_expression>( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: ConditionalExpression<'ast, T, U>, ) -> FlatUExpression { let condition = *e.condition; @@ -680,7 +681,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * a `FlatExpression` which evaluates to `1` if `0 <= e < c`, and to `0` otherwise fn constant_lt_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: FlatExpression, c: T, ) -> FlatExpression { @@ -704,7 +705,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * a `FlatExpression` which evaluates to `1` if `0 <= e <= c`, and to `0` otherwise fn constant_field_le_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: FlatExpression, c: T, ) -> FlatExpression { @@ -745,7 +746,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { #[must_use] fn le_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, lhs_flattened: FlatExpression, rhs_flattened: FlatExpression, bit_width: usize, @@ -768,7 +769,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { #[must_use] fn lt_check( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, lhs_flattened: FlatExpression, rhs_flattened: FlatExpression, bit_width: usize, @@ -827,7 +828,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * in order to preserve composability. fn flatten_boolean_expression( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, expression: BooleanExpression<'ast, T>, ) -> FlatExpression { match expression { @@ -1033,7 +1034,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `param_expressions` - Arguments of this call fn flatten_embed_call( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, embed: FlatEmbed, generics: Vec, param_expressions: Vec>, @@ -1134,9 +1135,9 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn flatten_embed_call_aux( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, params: Vec>, - funct: FlatFunctionIterator>>, + funct: FlatFunctionIterator<'ast, T, impl IntoIterator>>, ) -> Vec> { let mut replacement_map = HashMap::new(); @@ -1219,7 +1220,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `expr` - `ZirExpression` that will be flattened. fn flatten_expression( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, expr: ZirExpression<'ast, T>, ) -> FlatUExpression { match expr { @@ -1235,7 +1236,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn default_xor( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, left: UExpression<'ast, T>, right: UExpression<'ast, T>, ) -> FlatUExpression { @@ -1296,7 +1297,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn euclidean_division( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, target_bitwidth: UBitwidth, left: UExpression<'ast, T>, right: UExpression<'ast, T>, @@ -1382,7 +1383,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `expr` - `UExpression` that will be flattened. fn flatten_uint_expression( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, expr: UExpression<'ast, T>, ) -> FlatUExpression { // the bitwidth for this type of uint (8, 16 or 32) @@ -1875,7 +1876,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { e: &FlatUExpression, from: usize, to: usize, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, error: RuntimeError, ) -> Vec> { assert!(from <= T::get_required_bits()); @@ -1969,7 +1970,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn flatten_select_expression>( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, e: SelectExpression<'ast, T, U>, ) -> FlatUExpression { let array = e.array; @@ -2033,7 +2034,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `expr` - `FieldElementExpression` that will be flattened. fn flatten_field_expression( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, expr: FieldElementExpression<'ast, T>, ) -> FlatExpression { match expr { @@ -2221,6 +2222,35 @@ impl<'ast, T: Field> Flattener<'ast, T> { } } + fn flatten_assembly_statement( + &mut self, + statements_flattened: &mut FlatStatements<'ast, T>, + stat: ZirAssemblyStatement<'ast, T>, + ) { + match stat { + ZirAssemblyStatement::Assignment(assignees, function) => { + let outputs: Vec = assignees + .iter() + .map(|a| self.use_variable(a)) /*self.layout.get(&a.id).cloned().unwrap()*/ + .collect(); + let inputs: Vec> = function + .arguments + .iter() + .cloned() + .map(|p| self.layout.get(&p.id.id).cloned().unwrap().into()) + .collect(); + let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs); + statements_flattened.push_back(FlatStatement::Directive(directive)); + } + ZirAssemblyStatement::Constraint(lhs, rhs) => { + let lhs = self.flatten_field_expression(statements_flattened, lhs); + let rhs = self.flatten_field_expression(statements_flattened, rhs); + + self.flatten_equality_assertion(statements_flattened, lhs, rhs, RuntimeError::UnsatisfiedConstraint) + } + } + } + /// Flattens a statement /// /// # Arguments @@ -2229,10 +2259,15 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// * `stat` - `ZirStatement` that will be flattened. fn flatten_statement( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, stat: ZirStatement<'ast, T>, ) { match stat { + ZirStatement::Assembly(statements) => { + for s in statements { + self.flatten_assembly_statement(statements_flattened, s); + } + } ZirStatement::Return(exprs) => { #[allow(clippy::needless_collect)] // clippy suggests to not collect here, but `statements_flattened` is borrowed in the iterator, @@ -2633,12 +2668,12 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// /// # Arguments /// - /// * `statements_flattened` - `FlatStatements` Vector where new flattened statements can be added. + /// * `statements_flattened` - `FlatStatements<'ast, T>` Vector where new flattened statements can be added. /// * `lhs` - `FlatExpression` Left-hand side of the equality expression. /// * `rhs` - `FlatExpression` Right-hand side of the equality expression. fn flatten_equality_assertion( &mut self, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, lhs: FlatExpression, rhs: FlatExpression, error: RuntimeError, @@ -2667,11 +2702,11 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// # Arguments /// /// * `e` - `FlatExpression` Expression to be assigned to an identifier. - /// * `statements_flattened` - `FlatStatements` Vector where new flattened statements can be added. + /// * `statements_flattened` - `FlatStatements<'ast, T>` Vector where new flattened statements can be added. fn identify_expression( &mut self, e: FlatExpression, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> FlatExpression { match e.is_linear() { true => e, @@ -2710,7 +2745,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { fn use_parameter( &mut self, parameter: &ZirParameter<'ast>, - statements_flattened: &mut FlatStatements, + statements_flattened: &mut FlatStatements<'ast, T>, ) -> Parameter { let variable = self.use_variable(¶meter.id); diff --git a/zokrates_core/src/optimizer/canonicalizer.rs b/zokrates_core/src/optimizer/canonicalizer.rs index 4a65bc85f..57810aedd 100644 --- a/zokrates_core/src/optimizer/canonicalizer.rs +++ b/zokrates_core/src/optimizer/canonicalizer.rs @@ -4,7 +4,7 @@ use zokrates_field::Field; #[derive(Default)] pub struct Canonicalizer; -impl Folder for Canonicalizer { +impl<'ast, T: Field> Folder<'ast, T> for Canonicalizer { fn fold_linear_combination(&mut self, l: LinComb) -> LinComb { l.into_canonical().into() } diff --git a/zokrates_core/src/optimizer/directive.rs b/zokrates_core/src/optimizer/directive.rs index afabc87bd..b216bef67 100644 --- a/zokrates_core/src/optimizer/directive.rs +++ b/zokrates_core/src/optimizer/directive.rs @@ -15,18 +15,18 @@ use zokrates_ast::ir::*; use zokrates_field::Field; #[derive(Debug, Default)] -pub struct DirectiveOptimizer { - calls: HashMap<(Solver, Vec>), Vec>, +pub struct DirectiveOptimizer<'ast, T> { + calls: HashMap<(Solver<'ast, T>, Vec>), Vec>, /// Map of renamings for reassigned variables while processing the program. substitution: HashMap, } -impl Folder for DirectiveOptimizer { +impl<'ast, T: Field> Folder<'ast, T> for DirectiveOptimizer<'ast, T> { fn fold_variable(&mut self, v: Variable) -> Variable { *self.substitution.get(&v).unwrap_or(&v) } - fn fold_statement(&mut self, s: Statement) -> Vec> { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { match s { Statement::Directive(d) => { let d = self.fold_directive(d); diff --git a/zokrates_core/src/optimizer/duplicate.rs b/zokrates_core/src/optimizer/duplicate.rs index 68c954096..664cfc2db 100644 --- a/zokrates_core/src/optimizer/duplicate.rs +++ b/zokrates_core/src/optimizer/duplicate.rs @@ -21,8 +21,8 @@ pub struct DuplicateOptimizer { seen: HashSet, } -impl Folder for DuplicateOptimizer { - fn fold_program(&mut self, p: Prog) -> Prog { +impl<'ast, T: Field> Folder<'ast, T> for DuplicateOptimizer { + fn fold_program(&mut self, p: Prog<'ast, T>) -> Prog<'ast, T> { // in order to correctly identify duplicates, we need to first canonicalize the statements let mut canonicalizer = Canonicalizer; @@ -38,7 +38,7 @@ impl Folder for DuplicateOptimizer { fold_program(self, p) } - fn fold_statement(&mut self, s: Statement) -> Vec> { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { let hashed = hash(&s); let result = match self.seen.get(&hashed) { Some(_) => vec![], diff --git a/zokrates_core/src/optimizer/mod.rs b/zokrates_core/src/optimizer/mod.rs index cecee2e3f..1f94740a9 100644 --- a/zokrates_core/src/optimizer/mod.rs +++ b/zokrates_core/src/optimizer/mod.rs @@ -19,9 +19,9 @@ use self::tautology::TautologyOptimizer; use zokrates_ast::ir::{ProgIterator, Statement}; use zokrates_field::Field; -pub fn optimize>>( - p: ProgIterator, -) -> ProgIterator>> { +pub fn optimize<'ast, T: Field, I: IntoIterator>>( + p: ProgIterator<'ast, T, I>, +) -> ProgIterator<'ast, T, impl IntoIterator>> { // remove redefinitions log::debug!("Optimizer: Remove redefinitions and tautologies and directives and duplicates"); diff --git a/zokrates_core/src/optimizer/redefinition.rs b/zokrates_core/src/optimizer/redefinition.rs index e853be115..8f0e24474 100644 --- a/zokrates_core/src/optimizer/redefinition.rs +++ b/zokrates_core/src/optimizer/redefinition.rs @@ -53,7 +53,9 @@ pub struct RedefinitionOptimizer { } impl RedefinitionOptimizer { - pub fn init>>(p: &ProgIterator) -> Self { + pub fn init<'ast, I: IntoIterator>>( + p: &ProgIterator<'ast, T, I>, + ) -> Self { RedefinitionOptimizer { substitution: HashMap::new(), ignore: vec![Variable::one()] @@ -66,8 +68,8 @@ impl RedefinitionOptimizer { } } -impl Folder for RedefinitionOptimizer { - fn fold_statement(&mut self, s: Statement) -> Vec> { +impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { match s { Statement::Constraint(quad, lin, message) => { let quad = self.fold_quadratic_combination(quad); diff --git a/zokrates_core/src/optimizer/tautology.rs b/zokrates_core/src/optimizer/tautology.rs index 4a9ce8472..855efa11d 100644 --- a/zokrates_core/src/optimizer/tautology.rs +++ b/zokrates_core/src/optimizer/tautology.rs @@ -13,8 +13,8 @@ use zokrates_field::Field; #[derive(Default)] pub struct TautologyOptimizer; -impl Folder for TautologyOptimizer { - fn fold_statement(&mut self, s: Statement) -> Vec> { +impl<'ast, T: Field> Folder<'ast, T> for TautologyOptimizer { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { match s { Statement::Constraint(quad, lin, message) => match quad.try_linear() { Ok(l) => { diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 8e27f27fd..baba3ab2a 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -699,7 +699,7 @@ impl<'ast, T: Field> Checker<'ast, T> { is_mutable: false, }; assert_eq!(self.scope.level, 0); - assert!(!self.scope.insert(id, info)); + assert!(!self.scope.insert(id.into(), info)); assert!(state .constants .entry(module_id.to_path_buf()) @@ -895,7 +895,7 @@ impl<'ast, T: Field> Checker<'ast, T> { is_mutable: false, }; assert_eq!(self.scope.level, 0); - assert!(!self.scope.insert(id, info)); + assert!(!self.scope.insert(id.into(), info)); state .constants @@ -1130,12 +1130,12 @@ impl<'ast, T: Field> Checker<'ast, T> { // for declaration signatures, generics cannot be ignored generics.0.insert( generic.clone(), - UExpressionInner::Identifier(self.id_in_this_scope(generic.name()).into()) + UExpressionInner::Identifier(self.id_in_this_scope(generic.name().into()).into()) .annotate(UBitwidth::B32), ); //we don't have to check for conflicts here, because this was done when checking the signature - self.insert_into_scope(generic.name(), Type::Uint(UBitwidth::B32), false); + self.insert_into_scope(generic.name().into(), Type::Uint(UBitwidth::B32), false); } for (arg, decl_ty) in funct.arguments.into_iter().zip(s.inputs.iter()) { @@ -1144,7 +1144,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let arg = arg.value; let decl_v = DeclarationVariable::new( - self.id_in_this_scope(arg.id.value.id), + self.id_in_this_scope(arg.id.value.id.into()), decl_ty.clone(), arg.id.value.is_mutable, ); @@ -1161,7 +1161,7 @@ impl<'ast, T: Field> Checker<'ast, T> { ty, is_mutable, }; - match self.scope.insert(id, info) { + match self.scope.insert(id.into(), info) { false => {} true => { errors.push(ErrorInner { @@ -1651,10 +1651,10 @@ impl<'ast, T: Field> Checker<'ast, T> { .map_err(|e| vec![e])?; // insert into the scope and ignore whether shadowing happened - self.insert_into_scope(v.value.id, ty.clone(), v.value.is_mutable); + self.insert_into_scope(v.value.id.into(), ty.clone(), v.value.is_mutable); Ok(Variable::new( - self.id_in_this_scope(v.value.id), + self.id_in_this_scope(v.value.id.into()), ty, v.value.is_mutable, )) @@ -1770,6 +1770,87 @@ impl<'ast, T: Field> Checker<'ast, T> { } } + fn check_assembly_statement( + &mut self, + stat: AssemblyStatementNode<'ast>, + module_id: &ModuleId, + types: &TypeMap<'ast, T>, + ) -> Result>, ErrorInner> { + let pos = stat.pos(); + + match stat.value { + AssemblyStatement::Assignment(assignee, expression, constrained) => { + let assignee = self.check_assignee(assignee, module_id, types)?; + let checked_e = self.check_expression(expression, module_id, types)?; + + let e = match checked_e { + TypedExpression::FieldElement(e) => Ok(e), + TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), // todo: handle properly + _ => Err(ErrorInner { + pos: Some(pos), + message: "Only field element expressions are allowed in the assembly" + .to_string(), + }), + }?; + + let e = FieldElementExpression::block(vec![], e); + match constrained { + true => { + if !e.is_quadratic() { + return Err(ErrorInner { + pos: Some(pos), + message: "Non quadratic constraints are not allowed".to_string(), + }); + } + match assignee.get_type() { + Type::FieldElement => Ok(vec![ + TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()), + TypedAssemblyStatement::Constraint(assignee.into(), e), + ]), + _ => Err(ErrorInner { + pos: Some(pos), + message: "Assignee must be of type `field`".to_string(), + }), + } + } + false => Ok(vec![TypedAssemblyStatement::Assignment(assignee, e)]), + } + } + AssemblyStatement::Constraint(lhs, rhs) => { + let lhs = self.check_expression(lhs, module_id, types)?; + let rhs = self.check_expression(rhs, module_id, types)?; + match (lhs, rhs) { + (TypedExpression::FieldElement(lhs), TypedExpression::FieldElement(rhs)) => { + Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)]) + } + (TypedExpression::FieldElement(lhs), TypedExpression::Int(rhs)) => { + Ok(vec![TypedAssemblyStatement::Constraint( + lhs, + FieldElementExpression::try_from_int(rhs).unwrap(), + )]) + } + (TypedExpression::Int(lhs), TypedExpression::FieldElement(rhs)) => { + Ok(vec![TypedAssemblyStatement::Constraint( + FieldElementExpression::try_from_int(lhs).unwrap(), + rhs, + )]) + } + (TypedExpression::Int(lhs), TypedExpression::Int(rhs)) => { + Ok(vec![TypedAssemblyStatement::Constraint( + FieldElementExpression::try_from_int(lhs).unwrap(), + FieldElementExpression::try_from_int(rhs).unwrap(), + )]) + } + _ => Err(ErrorInner { + pos: Some(pos), + message: "Only field element expressions are allowed in the assembly" + .to_string(), + }), + } + } + } + } + fn check_statement( &mut self, stat: StatementNode<'ast>, @@ -1779,6 +1860,18 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = stat.pos(); match stat.value { + Statement::Assembly(statements) => { + let mut checked_statements = vec![]; + for s in statements { + checked_statements.push( + self.check_assembly_statement(s, module_id, types) + .map_err(|e| vec![e])?, + ); + } + Ok(TypedStatement::Assembly( + checked_statements.into_iter().flatten().collect(), + )) + } Statement::Log(l, expressions) => { let l = FormatString::from(l); @@ -1901,10 +1994,10 @@ impl<'ast, T: Field> Checker<'ast, T> { .map_err(|e| vec![e])?; // insert the lhs into the scope and ignore whether shadowing happened - self.insert_into_scope(var.value.id, var_ty.clone(), var.value.is_mutable); + self.insert_into_scope(var.value.id.into(), var_ty.clone(), var.value.is_mutable); let var = Variable::new( - self.id_in_this_scope(var.value.id), + self.id_in_this_scope(var.value.id.into()), var_ty.clone(), var.value.is_mutable, ); @@ -2037,7 +2130,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = assignee.pos(); // check that the assignee is declared match assignee.value { - Assignee::Identifier(variable_name) => match self.scope.get(&variable_name) { + Assignee::Identifier(variable_name) => match self.scope.get(&variable_name.into()) { Some(info) => match info.is_mutable { false => Err(ErrorInner { pos: Some(assignee.pos()), @@ -2346,7 +2439,7 @@ impl<'ast, T: Field> Checker<'ast, T> { Expression::BooleanConstant(b) => Ok(BooleanExpression::Value(b).into()), Expression::Identifier(name) => { // check that `id` is defined in the scope - match self.scope.get(&name) { + match self.scope.get(&name.into()) { Some(info) => { let id = info.id; match info.ty.clone() { @@ -3615,11 +3708,11 @@ impl<'ast, T: Field> Checker<'ast, T> { is_mutable: bool, ) -> bool { let info = IdentifierInfo { - id: self.id_in_this_scope(id), + id: self.id_in_this_scope(id.clone()), ty, is_mutable, }; - self.scope.insert(id, info) + self.scope.insert(id.into(), info) } fn find_functions( diff --git a/zokrates_core/src/static_analysis/flat_propagation.rs b/zokrates_core/src/static_analysis/flat_propagation.rs index f69b93137..155d803c8 100644 --- a/zokrates_core/src/static_analysis/flat_propagation.rs +++ b/zokrates_core/src/static_analysis/flat_propagation.rs @@ -14,8 +14,8 @@ struct Propagator { constants: HashMap, } -impl Folder for Propagator { - fn fold_statement(&mut self, s: FlatStatement) -> Vec> { +impl<'ast, T: Field> Folder<'ast, T> for Propagator { + fn fold_statement(&mut self, s: FlatStatement<'ast, T>) -> Vec> { match s { FlatStatement::Definition(var, expr) => match self.fold_expression(expr) { FlatExpression::Number(n) => { diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index c4683e4ed..2964ff06e 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -1,7 +1,8 @@ +use std::collections::HashSet; use std::marker::PhantomData; use zokrates_ast::typed::types::UBitwidth; use zokrates_ast::typed::{self, Expr, Typed}; -use zokrates_ast::zir::{self, Select}; +use zokrates_ast::zir::{self, Folder, Select}; use zokrates_field::Field; use std::convert::{TryFrom, TryInto}; @@ -224,6 +225,14 @@ impl<'ast, T: Field> Flattener { } } + fn fold_assembly_statement( + &mut self, + statements_buffer: &mut Vec>, + s: typed::TypedAssemblyStatement<'ast, T>, + ) -> zir::ZirAssemblyStatement<'ast, T> { + fold_assembly_statement(self, statements_buffer, s) + } + fn fold_statement( &mut self, statements_buffer: &mut Vec>, @@ -393,12 +402,102 @@ impl<'ast, T: Field> Flattener { } } +#[derive(Default)] +pub struct ArgumentFinder<'ast, T> { + pub identifiers: HashSet>, + _phantom: PhantomData, +} + +impl<'ast, T: Field> Folder<'ast, T> for ArgumentFinder<'ast, T> { + fn fold_name(&mut self, n: zir::Identifier<'ast>) -> zir::Identifier<'ast> { + self.identifiers.insert(n.clone()); + n + } + fn fold_statement(&mut self, s: zir::ZirStatement<'ast, T>) -> Vec> { + match s { + zir::ZirStatement::Definition(assignee, expr) => { + let assignee = self.fold_assignee(assignee); + let expr = self.fold_expression(expr); + self.identifiers.remove(&assignee.id); + vec![zir::ZirStatement::Definition(assignee, expr)] + } + zir::ZirStatement::MultipleDefinition(assignees, list) => { + let assignees: Vec> = assignees + .into_iter() + .map(|v| self.fold_assignee(v)) + .collect(); + let list = self.fold_expression_list(list); + for a in &assignees { + self.identifiers.remove(&a.id); + } + vec![zir::ZirStatement::MultipleDefinition(assignees, list)] + } + s => zir::folder::fold_statement(self, s), + } + } +} + +fn fold_assembly_statement<'ast, T: Field>( + f: &mut Flattener, + statements_buffer: &mut Vec>, + s: typed::TypedAssemblyStatement<'ast, T>, +) -> zir::ZirAssemblyStatement<'ast, T> { + match s { + typed::TypedAssemblyStatement::Assignment(a, e) => { + let mut statements_buffer: Vec> = vec![]; + let a = f.fold_assignee(a); + let e = f.fold_field_expression(&mut statements_buffer, e); + statements_buffer.push(zir::ZirStatement::Return(vec![ + zir::ZirExpression::FieldElement(e), + ])); + + let mut finder = ArgumentFinder::default(); + let mut statements_buffer: Vec> = statements_buffer + .into_iter() + .rev() + .map(|s| finder.fold_statement(s)) + .flatten() + .collect(); + statements_buffer.reverse(); + + let function = zir::ZirFunction { + signature: zir::types::Signature::default() + .inputs(vec![zir::Type::FieldElement; finder.identifiers.len()]) + .outputs(a.iter().map(|a| a.get_type()).collect()), + arguments: finder + .identifiers + .into_iter() + .map(|id| zir::Parameter { + id: zir::Variable::field_element(id), + private: false, + }) + .collect(), + statements: statements_buffer, + }; + + zir::ZirAssemblyStatement::Assignment(a, function) + } + typed::TypedAssemblyStatement::Constraint(lhs, rhs) => { + let lhs = f.fold_field_expression(statements_buffer, lhs); + let rhs = f.fold_field_expression(statements_buffer, rhs); + zir::ZirAssemblyStatement::Constraint(lhs, rhs) + } + } +} + fn fold_statement<'ast, T: Field>( f: &mut Flattener, statements_buffer: &mut Vec>, s: typed::TypedStatement<'ast, T>, ) { let res = match s { + typed::TypedStatement::Assembly(statements) => { + let statements = statements + .into_iter() + .map(|s| f.fold_assembly_statement(statements_buffer, s)) + .collect(); + vec![zir::ZirStatement::Assembly(statements)] + } typed::TypedStatement::Return(expression) => vec![zir::ZirStatement::Return( f.fold_expression(statements_buffer, expression), )], diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_core/src/static_analysis/propagation.rs index 311eec211..f2b31ea90 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_core/src/static_analysis/propagation.rs @@ -220,6 +220,38 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { s: TypedStatement<'ast, T>, ) -> Result>, Error> { match s { + TypedStatement::Assembly(statements) => { + let mut assembly_statement_buffer = vec![]; + let mut statement_buffer = vec![]; + + for s in statements { + match self.fold_assembly_statement(s)? { + TypedAssemblyStatement::Assignment(assignee, expr) => { + // invalidate the cache + let v = self + .try_get_constant_mut(&assignee) + .map(|(v, _)| v) + .unwrap_or_else(|v| v); + + match self.constants.remove(&v.id) { + Some(c) => { + statement_buffer.push(TypedStatement::Definition( + v.clone().into(), + c.into(), + )); + } + None => {} + } + assembly_statement_buffer + .push(TypedAssemblyStatement::Assignment(assignee, expr)); + } + s => assembly_statement_buffer.push(s), + } + } + + statement_buffer.push(TypedStatement::Assembly(assembly_statement_buffer)); + Ok(statement_buffer) + } // propagation to the defined variable if rhs is a constant TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => { let assignee = self.fold_assignee(assignee)?; diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index 72bbdf1f5..d573f8a01 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -3,7 +3,7 @@ use std::fmt; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, - SelectExpression, SelectOrExpression, + SelectExpression, SelectOrExpression, ZirAssemblyStatement, }; use zokrates_ast::zir::{ BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression, @@ -42,6 +42,9 @@ pub struct ZirPropagator<'ast, T> { } impl<'ast, T: Field> ZirPropagator<'ast, T> { + pub fn with_constants(constants: Constants<'ast, T>) -> Self { + Self { constants } + } pub fn propagate(p: ZirProgram) -> Result, Error> { ZirPropagator::default().fold_program(p) } @@ -50,6 +53,24 @@ impl<'ast, T: Field> ZirPropagator<'ast, T> { impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { type Error = Error; + fn fold_assembly_statement( + &mut self, + s: ZirAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + match s { + ZirAssemblyStatement::Assignment(assignees, function) => { + for a in &assignees { + self.constants.remove(&a.id); + } + Ok(ZirAssemblyStatement::Assignment( + assignees, + self.fold_function(function)?, + )) + } + s => fold_assembly_statement(self, s), + } + } + fn fold_statement( &mut self, s: ZirStatement<'ast, T>, diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index 3776d84fa..f24cad3b0 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -24,21 +24,22 @@ impl Interpreter { } impl Interpreter { - pub fn execute>>( + pub fn execute<'ast, T: Field, I: IntoIterator>>( &self, - program: ProgIterator, + program: ProgIterator<'ast, T, I>, inputs: &[T], ) -> ExecutionResult { self.execute_with_log_stream(program, inputs, &mut std::io::sink()) } pub fn execute_with_log_stream< + 'ast, W: std::io::Write, T: Field, - I: IntoIterator>, + I: IntoIterator>, >( &self, - program: ProgIterator, + program: ProgIterator<'ast, T, I>, inputs: &[T], log_stream: &mut W, ) -> ExecutionResult { @@ -142,9 +143,9 @@ impl Interpreter { .collect() } - fn check_inputs>, U>( + fn check_inputs<'ast, T: Field, I: IntoIterator>, U>( &self, - program: &ProgIterator, + program: &ProgIterator<'ast, T, I>, inputs: &[U], ) -> Result<(), Error> { if program.arguments.len() == inputs.len() { @@ -157,11 +158,18 @@ impl Interpreter { } } - pub fn execute_solver(solver: &Solver, inputs: &[T]) -> Result, String> { + pub fn execute_solver<'ast, T: Field>( + solver: &Solver<'ast, T>, + inputs: &[T], + ) -> Result, String> { let (expected_input_count, expected_output_count) = solver.get_signature(); assert_eq!(inputs.len(), expected_input_count); let res = match solver { + Solver::Zir(func) => { + // TODO: implement evaluation of the function + vec![inputs[1].checked_div(&inputs[0]).unwrap()] + } Solver::ConditionEq => match inputs[0].is_zero() { true => vec![T::zero(), T::one()], false => vec![ diff --git a/zokrates_js/src/lib.rs b/zokrates_js/src/lib.rs index cf24252e0..e2c6715de 100644 --- a/zokrates_js/src/lib.rs +++ b/zokrates_js/src/lib.rs @@ -349,13 +349,14 @@ mod internal { } pub fn setup_universal< + 'a, T: Field, - I: IntoIterator>, + I: IntoIterator>, S: UniversalScheme + Serialize, B: UniversalBackend, >( srs: &[u8], - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, ) -> Result { let keypair = B::setup(srs.to_vec(), program).map_err(|e| JsValue::from_str(&e))?; Ok(JsValue::from_serde(&TaggedKeypair::::new(keypair)).unwrap()) diff --git a/zokrates_parser/src/zokrates.pest b/zokrates_parser/src/zokrates.pest index 67ab2ec2e..d0319d13e 100644 --- a/zokrates_parser/src/zokrates.pest +++ b/zokrates_parser/src/zokrates.pest @@ -52,7 +52,7 @@ _mut = {"mut"} // Statements -statement = { (iteration_statement // does not require semicolon +statement = { (iteration_statement | asm_statement // does not require semicolon | ((log_statement |return_statement | definition_statement @@ -66,6 +66,15 @@ return_statement = { "return" ~ expression? } definition_statement = { typed_identifier_or_assignee ~ "=" ~ expression } assertion_statement = {"assert" ~ "(" ~ expression ~ ("," ~ quoted_string)? ~ ")"} +op_asm_assign = @{"<--"} +op_asm_assign_constrain = @{"<=="} + +asm_assignment = { assignee ~ (op_asm_assign | op_asm_assign_constrain) ~ expression } +asm_constraint = { expression ~ "===" ~ expression } + +asm_statement_inner = { (asm_assignment | asm_constraint) ~ semicolon ~ NEWLINE* } +asm_statement = { "asm" ~ "{" ~ NEWLINE* ~ asm_statement_inner* ~ NEWLINE* ~ "}" } + typed_identifier_or_assignee = { typed_identifier | assignee } // Expressions diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 0564e13bb..7e241886d 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -8,11 +8,12 @@ use zokrates_parser::Rule; extern crate lazy_static; pub use ast::{ - Access, Arguments, ArrayAccess, ArrayInitializerExpression, ArrayType, AssertionStatement, - Assignee, AssigneeAccess, BasicOrStructOrTupleType, BasicType, BinaryExpression, - BinaryOperator, CallAccess, ConstantDefinition, ConstantGenericValue, DecimalLiteralExpression, - DecimalNumber, DecimalSuffix, DefinitionStatement, ExplicitGenerics, Expression, FieldType, - File, FromExpression, FunctionDefinition, HexLiteralExpression, HexNumberExpression, + Access, Arguments, ArrayAccess, ArrayInitializerExpression, ArrayType, AssemblyStatement, + AssemblyStatementInner, AssertionStatement, Assignee, AssigneeAccess, AssignmentOperator, + BasicOrStructOrTupleType, BasicType, BinaryExpression, BinaryOperator, CallAccess, + ConstantDefinition, ConstantGenericValue, DecimalLiteralExpression, DecimalNumber, + DecimalSuffix, DefinitionStatement, ExplicitGenerics, Expression, FieldType, File, + FromExpression, FunctionDefinition, HexLiteralExpression, HexNumberExpression, IdentifierExpression, IdentifierOrDecimal, IfElseExpression, ImportDirective, ImportSymbol, InlineArrayExpression, InlineStructExpression, InlineStructMember, InlineTupleExpression, IterationStatement, LiteralExpression, LogStatement, Parameter, PostfixExpression, Range, @@ -366,6 +367,7 @@ mod ast { Assertion(AssertionStatement<'ast>), Iteration(IterationStatement<'ast>), Log(LogStatement<'ast>), + Assembly(AssemblyStatement<'ast>), } #[derive(Debug, FromPest, PartialEq, Clone)] @@ -423,6 +425,72 @@ mod ast { pub span: Span<'ast>, } + // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] + // #[pest_ast(rule(Rule::op_asm_assign))] + // pub struct AssemblyAssignOperator; + // + // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] + // #[pest_ast(rule(Rule::op_asm_assign_constrain))] + // pub struct AssemblyAssignConstrainOperator; + // + // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] + // #[pest_ast(rule(Rule::op_asm_constrain))] + // pub struct AssemblyConstrainOperator; + + #[derive(Debug, PartialEq, Clone)] + pub enum AssignmentOperator { + Assign, + AssignConstrain, + } + + impl<'ast> FromPest<'ast> for AssignmentOperator { + type Rule = Rule; + type FatalError = Void; + + fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result> { + let pair = pest.next().ok_or(::from_pest::ConversionError::NoMatch)?; + match pair.as_rule() { + Rule::op_asm_assign => Ok(AssignmentOperator::Assign), + Rule::op_asm_assign_constrain => Ok(AssignmentOperator::AssignConstrain), + _ => Err(ConversionError::NoMatch), + } + } + } + + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::asm_assignment))] + pub struct AssemblyAssignment<'ast> { + pub assignee: Assignee<'ast>, + pub operator: AssignmentOperator, + pub expression: Expression<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, + } + + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::asm_constraint))] + pub struct AssemblyConstraint<'ast> { + pub lhs: Expression<'ast>, + pub rhs: Expression<'ast>, + #[pest_ast(outer())] + pub span: Span<'ast>, + } + + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::asm_statement_inner))] + pub enum AssemblyStatementInner<'ast> { + Assignment(AssemblyAssignment<'ast>), + Constraint(AssemblyConstraint<'ast>), + } + + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::asm_statement))] + pub struct AssemblyStatement<'ast> { + pub inner: Vec>, + #[pest_ast(outer())] + pub span: Span<'ast>, + } + #[derive(Debug, PartialEq, Eq, Clone)] pub enum BinaryOperator { BitXor, diff --git a/zokrates_proof_systems/src/lib.rs b/zokrates_proof_systems/src/lib.rs index 231fbeee7..4184f6c9f 100644 --- a/zokrates_proof_systems/src/lib.rs +++ b/zokrates_proof_systems/src/lib.rs @@ -96,8 +96,8 @@ impl ToString for G2AffineFq2 { } pub trait Backend> { - fn generate_proof>>( - program: ir::ProgIterator, + fn generate_proof<'a, I: IntoIterator>>( + program: ir::ProgIterator<'a, T, I>, witness: ir::Witness, proving_key: Vec, ) -> Proof; @@ -105,36 +105,36 @@ pub trait Backend> { fn verify(vk: S::VerificationKey, proof: Proof) -> bool; } pub trait NonUniversalBackend>: Backend { - fn setup>>( - program: ir::ProgIterator, + fn setup<'a, I: IntoIterator>>( + program: ir::ProgIterator<'a, T, I>, ) -> SetupKeypair; } pub trait UniversalBackend>: Backend { fn universal_setup(size: u32) -> Vec; - fn setup>>( + fn setup<'a, I: IntoIterator>>( srs: Vec, - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, ) -> Result, String>; } pub trait MpcBackend> { - fn initialize>>( - program: ir::ProgIterator, + fn initialize<'a, R: Read, W: Write, I: IntoIterator>>( + program: ir::ProgIterator<'a, T, I>, phase1_radix: &mut R, output: &mut W, ) -> Result<(), String>; - fn contribute( + fn contribute<'a, R: Read, W: Write, G: Rng>( params: &mut R, rng: &mut G, output: &mut W, ) -> Result<[u8; 64], String>; - fn verify>>( + fn verify<'a, P: Read, R: Read, I: IntoIterator>>( params: &mut P, - program: ir::ProgIterator, + program: ir::ProgIterator<'a, T, I>, phase1_radix: &mut R, ) -> Result, String>; From 485be58a785d7a6dbaed7855a88edafd39167e39 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 11 Oct 2022 09:24:28 -0500 Subject: [PATCH 11/94] wip --- Cargo.lock | 40 +++++++++++++++ Cargo.toml | 2 + zokrates_analysis/Cargo.toml | 31 +++++++++++ .../src}/branch_isolator.rs | 0 .../src}/condition_redefiner.rs | 0 .../src}/constant_argument_checker.rs | 0 .../src}/constant_resolver.rs | 0 .../src}/dead_code.rs | 0 .../src}/flat_propagation.rs | 0 .../src}/flatten_complex_types.rs | 0 .../mod.rs => zokrates_analysis/src/lib.rs | 12 +++-- .../src}/log_ignorer.rs | 0 .../src}/out_of_bounds.rs | 0 .../src}/panic_extractor.rs | 0 .../src}/propagation.rs | 3 +- .../src}/reducer/constants_reader.rs | 2 +- .../src}/reducer/constants_writer.rs | 2 +- .../src}/reducer/inline.rs | 8 ++- .../src}/reducer/mod.rs | 2 +- .../src}/reducer/shallow_ssa.rs | 0 .../src}/struct_concretizer.rs | 0 .../src}/uint_optimizer.rs | 0 .../src}/variable_write_remover.rs | 2 - .../src}/zir_propagation.rs | 38 ++++++++------ zokrates_ast/src/common/embed.rs | 8 +++ zokrates_ast/src/common/solvers.rs | 4 +- zokrates_ast/src/typed/mod.rs | 35 ++++++++++++- zokrates_ast/src/typed/types.rs | 5 +- zokrates_cli/src/ops/check.rs | 4 +- zokrates_cli/src/ops/compile.rs | 4 +- zokrates_codegen/Cargo.toml | 16 ++++++ .../mod.rs => zokrates_codegen/src/lib.rs | 14 ++++- .../flatten => zokrates_codegen/src}/utils.rs | 0 zokrates_common/Cargo.toml | 3 +- zokrates_common/src/lib.rs | 21 ++++++++ zokrates_core/Cargo.toml | 6 ++- zokrates_core/src/compile.rs | 33 +++--------- zokrates_core/src/imports.rs | 4 ++ zokrates_core/src/lib.rs | 2 - zokrates_core/src/semantics.rs | 12 +++-- zokrates_interpreter/Cargo.toml | 1 + zokrates_interpreter/src/lib.rs | 51 +++++++++++++++++-- zokrates_js/index.d.ts | 1 + zokrates_js/lib.js | 3 +- zokrates_js/package-lock.json | 6 +-- zokrates_js/package.json | 4 +- zokrates_js/src/lib.rs | 13 +++-- zokrates_test/src/lib.rs | 3 +- 48 files changed, 302 insertions(+), 93 deletions(-) create mode 100644 zokrates_analysis/Cargo.toml rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/branch_isolator.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/condition_redefiner.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/constant_argument_checker.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/constant_resolver.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/dead_code.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/flat_propagation.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/flatten_complex_types.rs (100%) rename zokrates_core/src/static_analysis/mod.rs => zokrates_analysis/src/lib.rs (95%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/log_ignorer.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/out_of_bounds.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/panic_extractor.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/propagation.rs (99%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/reducer/constants_reader.rs (99%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/reducer/constants_writer.rs (99%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/reducer/inline.rs (97%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/reducer/mod.rs (99%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/reducer/shallow_ssa.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/struct_concretizer.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/uint_optimizer.rs (100%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/variable_write_remover.rs (99%) rename {zokrates_core/src/static_analysis => zokrates_analysis/src}/zir_propagation.rs (98%) create mode 100644 zokrates_codegen/Cargo.toml rename zokrates_core/src/flatten/mod.rs => zokrates_codegen/src/lib.rs (99%) rename {zokrates_core/src/flatten => zokrates_codegen/src}/utils.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ee50059cb..1c237bca5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2997,6 +2997,29 @@ dependencies = [ "zokrates_field", ] +[[package]] +name = "zokrates_analysis" +version = "0.1.0" +dependencies = [ + "cfg-if 0.1.10", + "csv", + "lazy_static", + "log", + "num 0.1.42", + "num-bigint 0.2.6", + "pretty_assertions 0.6.1", + "reduce", + "serde", + "serde_json", + "typed-arena", + "zokrates_ast", + "zokrates_common", + "zokrates_embed", + "zokrates_field", + "zokrates_fs_resolver", + "zokrates_pest_ast", +] + [[package]] name = "zokrates_ark" version = "0.1.1" @@ -3112,9 +3135,23 @@ dependencies = [ "zokrates_solidity_test", ] +[[package]] +name = "zokrates_codegen" +version = "0.1.0" +dependencies = [ + "zokrates_ast", + "zokrates_common", + "zokrates_embed", + "zokrates_field", + "zokrates_interpreter", +] + [[package]] name = "zokrates_common" version = "0.1.1" +dependencies = [ + "serde", +] [[package]] name = "zokrates_core" @@ -3131,7 +3168,9 @@ dependencies = [ "serde", "serde_json", "typed-arena", + "zokrates_analysis", "zokrates_ast", + "zokrates_codegen", "zokrates_common", "zokrates_embed", "zokrates_field", @@ -3208,6 +3247,7 @@ dependencies = [ "pairing_ce", "serde", "zokrates_abi", + "zokrates_analysis", "zokrates_ast", "zokrates_embed", "zokrates_field", diff --git a/Cargo.toml b/Cargo.toml index 92c7358e2..8c5b23352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ members = [ "zokrates_cli", "zokrates_fs_resolver", "zokrates_stdlib", + "zokrates_codegen", + "zokrates_analysis", "zokrates_embed", "zokrates_abi", "zokrates_test", diff --git a/zokrates_analysis/Cargo.toml b/zokrates_analysis/Cargo.toml new file mode 100644 index 000000000..e347abcdf --- /dev/null +++ b/zokrates_analysis/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "zokrates_analysis" +version = "0.1.0" +edition = "2021" + +[features] +default = ["ark", "bellman"] +ark = ["zokrates_ast/ark", "zokrates_embed/ark", "zokrates_common/ark"] +bellman = ["zokrates_ast/bellman", "zokrates_embed/bellman", "zokrates_common/bellman"] + +[dependencies] +log = "0.4" +cfg-if = "0.1" +num = { version = "0.1.36", default-features = false } +num-bigint = { version = "0.2", default-features = false } +lazy_static = "1.4" +typed-arena = "1.4.1" +reduce = "0.1.1" +# serialization and deserialization +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0", features = ["preserve_order"] } +zokrates_field = { version = "0.5.0", path = "../zokrates_field", default-features = false } +zokrates_pest_ast = { version = "0.3.0", path = "../zokrates_pest_ast" } +zokrates_common = { version = "0.1", path = "../zokrates_common", default-features = false } +zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false } +zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false } +csv = "1" + +[dev-dependencies] +pretty_assertions = "0.6.1" +zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"} \ No newline at end of file diff --git a/zokrates_core/src/static_analysis/branch_isolator.rs b/zokrates_analysis/src/branch_isolator.rs similarity index 100% rename from zokrates_core/src/static_analysis/branch_isolator.rs rename to zokrates_analysis/src/branch_isolator.rs diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_analysis/src/condition_redefiner.rs similarity index 100% rename from zokrates_core/src/static_analysis/condition_redefiner.rs rename to zokrates_analysis/src/condition_redefiner.rs diff --git a/zokrates_core/src/static_analysis/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs similarity index 100% rename from zokrates_core/src/static_analysis/constant_argument_checker.rs rename to zokrates_analysis/src/constant_argument_checker.rs diff --git a/zokrates_core/src/static_analysis/constant_resolver.rs b/zokrates_analysis/src/constant_resolver.rs similarity index 100% rename from zokrates_core/src/static_analysis/constant_resolver.rs rename to zokrates_analysis/src/constant_resolver.rs diff --git a/zokrates_core/src/static_analysis/dead_code.rs b/zokrates_analysis/src/dead_code.rs similarity index 100% rename from zokrates_core/src/static_analysis/dead_code.rs rename to zokrates_analysis/src/dead_code.rs diff --git a/zokrates_core/src/static_analysis/flat_propagation.rs b/zokrates_analysis/src/flat_propagation.rs similarity index 100% rename from zokrates_core/src/static_analysis/flat_propagation.rs rename to zokrates_analysis/src/flat_propagation.rs diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs similarity index 100% rename from zokrates_core/src/static_analysis/flatten_complex_types.rs rename to zokrates_analysis/src/flatten_complex_types.rs diff --git a/zokrates_core/src/static_analysis/mod.rs b/zokrates_analysis/src/lib.rs similarity index 95% rename from zokrates_core/src/static_analysis/mod.rs rename to zokrates_analysis/src/lib.rs index e6ed76b24..dae08c06f 100644 --- a/zokrates_core/src/static_analysis/mod.rs +++ b/zokrates_analysis/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(box_patterns, box_syntax)] + //! Module containing static analysis //! //! @file mod.rs @@ -32,14 +34,14 @@ use self::reducer::reduce_program; use self::struct_concretizer::StructConcretizer; use self::uint_optimizer::UintOptimizer; use self::variable_write_remover::VariableWriteRemover; -use crate::compile::CompileConfig; -use crate::static_analysis::constant_resolver::ConstantResolver; -use crate::static_analysis::dead_code::DeadCodeEliminator; -use crate::static_analysis::panic_extractor::PanicExtractor; -use crate::static_analysis::zir_propagation::ZirPropagator; +use crate::constant_resolver::ConstantResolver; +use crate::dead_code::DeadCodeEliminator; +use crate::panic_extractor::PanicExtractor; +pub use crate::zir_propagation::ZirPropagator; use std::fmt; use zokrates_ast::typed::{abi::Abi, TypedProgram}; use zokrates_ast::zir::ZirProgram; +use zokrates_common::CompileConfig; use zokrates_field::Field; #[derive(Debug)] diff --git a/zokrates_core/src/static_analysis/log_ignorer.rs b/zokrates_analysis/src/log_ignorer.rs similarity index 100% rename from zokrates_core/src/static_analysis/log_ignorer.rs rename to zokrates_analysis/src/log_ignorer.rs diff --git a/zokrates_core/src/static_analysis/out_of_bounds.rs b/zokrates_analysis/src/out_of_bounds.rs similarity index 100% rename from zokrates_core/src/static_analysis/out_of_bounds.rs rename to zokrates_analysis/src/out_of_bounds.rs diff --git a/zokrates_core/src/static_analysis/panic_extractor.rs b/zokrates_analysis/src/panic_extractor.rs similarity index 100% rename from zokrates_core/src/static_analysis/panic_extractor.rs rename to zokrates_analysis/src/panic_extractor.rs diff --git a/zokrates_core/src/static_analysis/propagation.rs b/zokrates_analysis/src/propagation.rs similarity index 99% rename from zokrates_core/src/static_analysis/propagation.rs rename to zokrates_analysis/src/propagation.rs index f2b31ea90..8bf898a2f 100644 --- a/zokrates_core/src/static_analysis/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -404,7 +404,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { match embed_call.arguments.iter().all(|a| a.is_constant()) { true => { let r: Option> = match embed_call.embed { - FlatEmbed::BitArrayLe => Ok(None), // todo + FlatEmbed::FieldToBoolUnsafe => Ok(None), // todo + FlatEmbed::BitArrayLe => Ok(None), // todo FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits( &embed_call.arguments, UBitwidth::B64, diff --git a/zokrates_core/src/static_analysis/reducer/constants_reader.rs b/zokrates_analysis/src/reducer/constants_reader.rs similarity index 99% rename from zokrates_core/src/static_analysis/reducer/constants_reader.rs rename to zokrates_analysis/src/reducer/constants_reader.rs index 8ea0d0afa..06164fe24 100644 --- a/zokrates_core/src/static_analysis/reducer/constants_reader.rs +++ b/zokrates_analysis/src/reducer/constants_reader.rs @@ -1,6 +1,6 @@ // given a (partial) map of values for program constants, replace where applicable constants by their value -use crate::static_analysis::reducer::ConstantDefinitions; +use crate::reducer::ConstantDefinitions; use zokrates_ast::typed::{ folder::*, ArrayExpression, ArrayExpressionInner, ArrayType, BooleanExpression, CoreIdentifier, DeclarationConstant, Expr, FieldElementExpression, Identifier, StructExpression, diff --git a/zokrates_core/src/static_analysis/reducer/constants_writer.rs b/zokrates_analysis/src/reducer/constants_writer.rs similarity index 99% rename from zokrates_core/src/static_analysis/reducer/constants_writer.rs rename to zokrates_analysis/src/reducer/constants_writer.rs index 4917a6b9a..d4e03d3d4 100644 --- a/zokrates_core/src/static_analysis/reducer/constants_writer.rs +++ b/zokrates_analysis/src/reducer/constants_writer.rs @@ -1,6 +1,6 @@ // A folder to inline all constant definitions down to a single literal and register them in the state for later use. -use crate::static_analysis::reducer::{ +use crate::reducer::{ constants_reader::ConstantsReader, reduce_function, ConstantDefinitions, Error, }; use std::collections::{BTreeMap, HashSet}; diff --git a/zokrates_core/src/static_analysis/reducer/inline.rs b/zokrates_analysis/src/reducer/inline.rs similarity index 97% rename from zokrates_core/src/static_analysis/reducer/inline.rs rename to zokrates_analysis/src/reducer/inline.rs index b2c12962a..31f237e82 100644 --- a/zokrates_core/src/static_analysis/reducer/inline.rs +++ b/zokrates_analysis/src/reducer/inline.rs @@ -26,9 +26,9 @@ // - The body of the function is in SSA form // - The return value(s) are assigned to internal variables -use crate::static_analysis::reducer::Output; -use crate::static_analysis::reducer::ShallowTransformer; -use crate::static_analysis::reducer::Versions; +use crate::reducer::Output; +use crate::reducer::ShallowTransformer; +use crate::reducer::Versions; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::types::{ConcreteGenericsAssignment, IntoType}; @@ -88,8 +88,6 @@ pub fn inline_call<'a, 'ast, T: Field, E: Expr<'ast, T>>( program: &TypedProgram<'ast, T>, versions: &'a mut Versions<'ast>, ) -> InlineResult<'ast, T> { - use std::convert::TryFrom; - use zokrates_ast::typed::Typed; let output_type = output.clone().into_type(); diff --git a/zokrates_core/src/static_analysis/reducer/mod.rs b/zokrates_analysis/src/reducer/mod.rs similarity index 99% rename from zokrates_core/src/static_analysis/reducer/mod.rs rename to zokrates_analysis/src/reducer/mod.rs index 508e982ec..631511524 100644 --- a/zokrates_core/src/static_analysis/reducer/mod.rs +++ b/zokrates_analysis/src/reducer/mod.rs @@ -36,7 +36,7 @@ use zokrates_field::Field; use self::constants_writer::ConstantsWriter; use self::shallow_ssa::ShallowTransformer; -use crate::static_analysis::propagation::{Constants, Propagator}; +use crate::propagation::{Constants, Propagator}; use std::fmt; diff --git a/zokrates_core/src/static_analysis/reducer/shallow_ssa.rs b/zokrates_analysis/src/reducer/shallow_ssa.rs similarity index 100% rename from zokrates_core/src/static_analysis/reducer/shallow_ssa.rs rename to zokrates_analysis/src/reducer/shallow_ssa.rs diff --git a/zokrates_core/src/static_analysis/struct_concretizer.rs b/zokrates_analysis/src/struct_concretizer.rs similarity index 100% rename from zokrates_core/src/static_analysis/struct_concretizer.rs rename to zokrates_analysis/src/struct_concretizer.rs diff --git a/zokrates_core/src/static_analysis/uint_optimizer.rs b/zokrates_analysis/src/uint_optimizer.rs similarity index 100% rename from zokrates_core/src/static_analysis/uint_optimizer.rs rename to zokrates_analysis/src/uint_optimizer.rs diff --git a/zokrates_core/src/static_analysis/variable_write_remover.rs b/zokrates_analysis/src/variable_write_remover.rs similarity index 99% rename from zokrates_core/src/static_analysis/variable_write_remover.rs rename to zokrates_analysis/src/variable_write_remover.rs index ce80c9607..ea1c72dab 100644 --- a/zokrates_core/src/static_analysis/variable_write_remover.rs +++ b/zokrates_analysis/src/variable_write_remover.rs @@ -37,8 +37,6 @@ impl<'ast> VariableWriteRemover { let inner_ty = base.inner_type(); let size = base.size(); - use std::convert::TryInto; - let size: u32 = size.try_into().unwrap(); let head = indices.remove(0); diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs similarity index 98% rename from zokrates_core/src/static_analysis/zir_propagation.rs rename to zokrates_analysis/src/zir_propagation.rs index d573f8a01..e8bbf9565 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -31,7 +31,7 @@ impl fmt::Display for Error { Error::DivisionByZero => { write!(f, "Division by zero detected in zir during static analysis",) } - Error::AssertionFailed(err) => write!(f, "{}", err), + Error::AssertionFailed(err) => write!(f, "Assertion failed: `{}`", err), } } } @@ -42,7 +42,7 @@ pub struct ZirPropagator<'ast, T> { } impl<'ast, T: Field> ZirPropagator<'ast, T> { - pub fn with_constants(constants: Constants<'ast, T>) -> Self { + pub fn with_constants(constants: Constants<'ast, T>) -> Self { Self { constants } } pub fn propagate(p: ZirProgram) -> Result, Error> { @@ -613,22 +613,28 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { e: ConditionalExpression<'ast, T, E>, ) -> Result, Self::Error> { let condition = self.fold_boolean_expression(*e.condition)?; - let consequence = e.consequence.fold(self)?; - let alternative = e.alternative.fold(self)?; - match (condition, consequence, alternative) { - (_, consequence, alternative) if consequence == alternative => Ok( - ConditionalOrExpression::Expression(consequence.into_inner()), - ), - (BooleanExpression::Value(true), consequence, _) => Ok( - ConditionalOrExpression::Expression(consequence.into_inner()), - ), - (BooleanExpression::Value(false), _, alternative) => Ok( - ConditionalOrExpression::Expression(alternative.into_inner()), - ), - (condition, consequence, alternative) => Ok(ConditionalOrExpression::Conditional( - ConditionalExpression::new(condition, consequence, alternative), + match condition { + BooleanExpression::Value(true) => Ok(ConditionalOrExpression::Expression( + e.consequence.fold(self)?.into_inner(), )), + BooleanExpression::Value(false) => Ok(ConditionalOrExpression::Expression( + e.alternative.fold(self)?.into_inner(), + )), + condition => { + let consequence = e.consequence.fold(self)?; + let alternative = e.alternative.fold(self)?; + + if consequence == alternative { + Ok(ConditionalOrExpression::Expression( + consequence.into_inner(), + )) + } else { + Ok(ConditionalOrExpression::Conditional( + ConditionalExpression::new(condition, consequence, alternative), + )) + } + } } } } diff --git a/zokrates_ast/src/common/embed.rs b/zokrates_ast/src/common/embed.rs index 0e8361d93..58294142f 100644 --- a/zokrates_ast/src/common/embed.rs +++ b/zokrates_ast/src/common/embed.rs @@ -31,6 +31,7 @@ cfg_if::cfg_if! { /// the flattening step when it can be inlined. #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Serialize, Deserialize)] pub enum FlatEmbed { + FieldToBoolUnsafe, BitArrayLe, Unpack, U8ToBits, @@ -50,6 +51,9 @@ pub enum FlatEmbed { impl FlatEmbed { pub fn signature(&self) -> UnresolvedSignature { match self { + FlatEmbed::FieldToBoolUnsafe => UnresolvedSignature::new() + .inputs(vec![UnresolvedType::FieldElement.into()]) + .output(UnresolvedType::Boolean.into()), FlatEmbed::BitArrayLe => UnresolvedSignature::new() .generics(vec![ConstantGenericNode::mock("N")]) .inputs(vec![ @@ -186,6 +190,9 @@ impl FlatEmbed { pub fn typed_signature(&self) -> DeclarationSignature<'static, T> { match self { + FlatEmbed::FieldToBoolUnsafe => DeclarationSignature::new() + .inputs(vec![DeclarationType::FieldElement]) + .output(DeclarationType::Boolean), FlatEmbed::BitArrayLe => DeclarationSignature::new() .generics(vec![Some(DeclarationConstant::Generic( GenericIdentifier::with_name("N").with_index(0), @@ -292,6 +299,7 @@ impl FlatEmbed { pub fn id(&self) -> &'static str { match self { + FlatEmbed::FieldToBoolUnsafe => "_FIELD_TO_BOOL_UNSAFE", FlatEmbed::BitArrayLe => "_BIT_ARRAY_LT", FlatEmbed::Unpack => "_UNPACK", FlatEmbed::U8ToBits => "_U8_TO_BITS", diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index c3e4fe770..598b35e8d 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -23,8 +23,8 @@ pub enum Solver<'ast, T> { impl<'ast, T: fmt::Debug + fmt::Display> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Solver::Zir(func) => write!(f, "Zir({})", func), - _ => write!(f, "{:?}", self) + Solver::Zir(func) => write!(f, "Zir({})", "ignored"), + _ => write!(f, "{:?}", self), } } } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index c8c8c1c6a..f6f865a8f 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1315,7 +1315,40 @@ impl<'ast, T> FieldElementExpression<'ast, T> { FieldElementExpression::Pow(box self, box other) } pub fn is_quadratic(&self) -> bool { - true // TODO: implement + match self { + FieldElementExpression::Mult(box left, box right) => { + left.is_linear() && right.is_linear() + } + _ => false, + } + } + + fn is_linear(&self) -> bool { + match self { + FieldElementExpression::Block(_) => false, + FieldElementExpression::Number(_) => true, + FieldElementExpression::Identifier(_) => true, + FieldElementExpression::Add(box left, box right) => { + left.is_linear() && right.is_linear() + } + FieldElementExpression::Sub(box left, box right) => { + left.is_linear() && right.is_linear() + } + FieldElementExpression::Mult(box left, box right) => match (left, right) { + (FieldElementExpression::Number(_), _) => true, + (_, FieldElementExpression::Number(_)) => true, + _ => false, + }, + FieldElementExpression::Div(_, _) => false, + FieldElementExpression::Pow(_, _) => false, + FieldElementExpression::Conditional(_) => false, + FieldElementExpression::Neg(_) => true, + FieldElementExpression::Pos(_) => true, + FieldElementExpression::FunctionCall(_) => false, + FieldElementExpression::Member(_) => true, + FieldElementExpression::Select(_) => true, + FieldElementExpression::Element(_) => true, + } } } diff --git a/zokrates_ast/src/typed/types.rs b/zokrates_ast/src/typed/types.rs index 8bd863f9a..02239c97a 100644 --- a/zokrates_ast/src/typed/types.rs +++ b/zokrates_ast/src/typed/types.rs @@ -51,7 +51,10 @@ pub struct GenericIdentifier<'ast> { impl<'ast> From> for CoreIdentifier<'ast> { fn from(g: GenericIdentifier<'ast>) -> CoreIdentifier<'ast> { // generic identifiers are always declared in the function scope, which is shadow 0 - CoreIdentifier::Source(ShadowedIdentifier::shadow(std::borrow::Cow::Borrowed(g.name()), 0)) + CoreIdentifier::Source(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed(g.name()), + 0, + )) } } diff --git a/zokrates_cli/src/ops/check.rs b/zokrates_cli/src/ops/check.rs index a32be7f6e..97d697efd 100644 --- a/zokrates_cli/src/ops/check.rs +++ b/zokrates_cli/src/ops/check.rs @@ -5,8 +5,8 @@ use std::fs::File; use std::io::{BufReader, Read}; use std::path::{Path, PathBuf}; use zokrates_common::constants::BN128; -use zokrates_common::helpers::CurveParameter; -use zokrates_core::compile::{check, CompileConfig, CompileError}; +use zokrates_common::{helpers::CurveParameter, CompileConfig}; +use zokrates_core::compile::{check, CompileError}; use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; use zokrates_fs_resolver::FileSystemResolver; diff --git a/zokrates_cli/src/ops/compile.rs b/zokrates_cli/src/ops/compile.rs index b00debe3d..74d26b6f2 100644 --- a/zokrates_cli/src/ops/compile.rs +++ b/zokrates_cli/src/ops/compile.rs @@ -8,8 +8,8 @@ use std::path::{Path, PathBuf}; use typed_arena::Arena; use zokrates_circom::write_r1cs; use zokrates_common::constants::BN128; -use zokrates_common::helpers::CurveParameter; -use zokrates_core::compile::{compile, CompileConfig, CompileError}; +use zokrates_common::{helpers::CurveParameter, CompileConfig}; +use zokrates_core::compile::{compile, CompileError}; use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; use zokrates_fs_resolver::FileSystemResolver; diff --git a/zokrates_codegen/Cargo.toml b/zokrates_codegen/Cargo.toml new file mode 100644 index 000000000..6bb566f4c --- /dev/null +++ b/zokrates_codegen/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "zokrates_codegen" +version = "0.1.0" +edition = "2021" + +[features] +default = ["ark", "bellman"] +ark = ["zokrates_ast/ark", "zokrates_embed/ark", "zokrates_common/ark", "zokrates_interpreter/ark"] +bellman = ["zokrates_ast/bellman", "zokrates_embed/bellman", "zokrates_common/bellman", "zokrates_interpreter/bellman"] + +[dependencies] +zokrates_field = { version = "0.5.0", path = "../zokrates_field", default-features = false } +zokrates_common = { version = "0.1.0", path = "../zokrates_common", default-features = false } +zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false } +zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter", default-features = false } +zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false } \ No newline at end of file diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_codegen/src/lib.rs similarity index 99% rename from zokrates_core/src/flatten/mod.rs rename to zokrates_codegen/src/lib.rs index 8168aee65..d80b7eefe 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_codegen/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(box_patterns, box_syntax)] + //! Module containing the `Flattener` to process a program that is R1CS-able. //! //! @file flatten.rs @@ -14,7 +16,6 @@ use zokrates_ast::zir::{ }; use zokrates_interpreter::Interpreter; -use crate::compile::CompileConfig; use std::collections::{ hash_map::{Entry, HashMap}, VecDeque, @@ -31,6 +32,7 @@ use zokrates_ast::zir::{ UExpression, UExpressionInner, Variable as ZirVariable, ZirExpression, ZirFunction, ZirStatement, }; +use zokrates_common::CompileConfig; use zokrates_field::Field; type FlatStatements<'ast, T> = VecDeque>; @@ -1050,6 +1052,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { .collect(); match embed { + FlatEmbed::FieldToBoolUnsafe => vec![params.pop().unwrap()], FlatEmbed::U8ToBits => self.u_to_bits(params.pop().unwrap(), 8.into()), FlatEmbed::U16ToBits => self.u_to_bits(params.pop().unwrap(), 16.into()), FlatEmbed::U32ToBits => self.u_to_bits(params.pop().unwrap(), 32.into()), @@ -1576,6 +1579,8 @@ impl<'ast, T: Field> Flattener<'ast, T> { let left_metadata = left.metadata.clone().unwrap(); let right_metadata = right.metadata.clone().unwrap(); + println!("left {}, right {}", left, right); + match (left.into_inner(), right.into_inner()) { (UExpressionInner::And(box a, box b), UExpressionInner::And(box aa, box c)) => { if aa.clone().into_inner() == UExpressionInner::Not(box a.clone()) { @@ -2246,7 +2251,12 @@ impl<'ast, T: Field> Flattener<'ast, T> { let lhs = self.flatten_field_expression(statements_flattened, lhs); let rhs = self.flatten_field_expression(statements_flattened, rhs); - self.flatten_equality_assertion(statements_flattened, lhs, rhs, RuntimeError::UnsatisfiedConstraint) + self.flatten_equality_assertion( + statements_flattened, + lhs, + rhs, + RuntimeError::UnsatisfiedConstraint, + ) } } } diff --git a/zokrates_core/src/flatten/utils.rs b/zokrates_codegen/src/utils.rs similarity index 100% rename from zokrates_core/src/flatten/utils.rs rename to zokrates_codegen/src/utils.rs diff --git a/zokrates_common/Cargo.toml b/zokrates_common/Cargo.toml index ef70f90d6..40ee04f0b 100644 --- a/zokrates_common/Cargo.toml +++ b/zokrates_common/Cargo.toml @@ -12,4 +12,5 @@ bellman = [] ark = [] -[dependencies] \ No newline at end of file +[dependencies] +serde = { version = "1.0", features = ["derive"] } \ No newline at end of file diff --git a/zokrates_common/src/lib.rs b/zokrates_common/src/lib.rs index 9bfc0c79b..a37d9112c 100644 --- a/zokrates_common/src/lib.rs +++ b/zokrates_common/src/lib.rs @@ -1,6 +1,7 @@ pub mod constants; pub mod helpers; +use serde::{Deserialize, Serialize}; use std::path::PathBuf; pub trait Resolver { @@ -10,3 +11,23 @@ pub trait Resolver { import_location: PathBuf, ) -> Result<(String, PathBuf), E>; } + +#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)] +pub struct CompileConfig { + #[serde(default)] + pub isolate_branches: bool, + #[serde(default)] + pub debug: bool, +} + +impl CompileConfig { + pub fn isolate_branches(mut self, flag: bool) -> Self { + self.isolate_branches = flag; + self + } + + pub fn debug(mut self, debug: bool) -> Self { + self.debug = debug; + self + } +} diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index 183b10c54..ff713fd36 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -8,8 +8,8 @@ readme = "README.md" [features] default = ["ark", "bellman"] -ark = ["zokrates_ast/ark", "zokrates_embed/ark", "zokrates_common/ark", "zokrates_interpreter/ark"] -bellman = ["zokrates_ast/bellman", "zokrates_embed/bellman", "zokrates_common/bellman", "zokrates_interpreter/bellman"] +ark = ["zokrates_ast/ark", "zokrates_embed/ark", "zokrates_common/ark", "zokrates_interpreter/ark", "zokrates_codegen/ark", "zokrates_analysis/ark"] +bellman = ["zokrates_ast/bellman", "zokrates_embed/bellman", "zokrates_common/bellman", "zokrates_interpreter/bellman", "zokrates_codegen/bellman", "zokrates_analysis/bellman"] [dependencies] log = "0.4" @@ -27,6 +27,8 @@ zokrates_pest_ast = { version = "0.3.0", path = "../zokrates_pest_ast" } zokrates_common = { version = "0.1", path = "../zokrates_common", default-features = false } zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false } zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter", default-features = false } +zokrates_codegen = { version = "0.1", path = "../zokrates_codegen", default-features = false } +zokrates_analysis = { version = "0.1", path = "../zokrates_analysis", default-features = false } zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false } csv = "1" diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index a50b57b39..89261d76b 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -3,24 +3,23 @@ //! @file compile.rs //! @author Thibaut Schaeffer //! @date 2018 -use crate::flatten::from_function_and_config; use crate::imports::{self, Importer}; use crate::macros; use crate::optimizer::optimize; use crate::semantics::{self, Checker}; -use crate::static_analysis::{self, analyse}; use macros::process_macros; -use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt; use std::io; use std::path::{Path, PathBuf}; use typed_arena::Arena; +use zokrates_analysis::{self, analyse}; use zokrates_ast::ir::{self, from_flat::from_flat}; use zokrates_ast::typed::abi::Abi; use zokrates_ast::untyped::{Module, OwnedModuleId, Program}; use zokrates_ast::zir::ZirProgram; -use zokrates_common::Resolver; +use zokrates_codegen::from_function_and_config; +use zokrates_common::{CompileConfig, Resolver}; use zokrates_field::Field; use zokrates_pest_ast as pest; @@ -67,7 +66,7 @@ pub enum CompileErrorInner { MacroError(macros::Error), SemanticError(semantics::ErrorInner), ReadError(io::Error), - AnalysisError(static_analysis::Error), + AnalysisError(zokrates_analysis::Error), } impl CompileErrorInner { @@ -142,8 +141,8 @@ impl From for CompileError { } } -impl From for CompileErrorInner { - fn from(error: static_analysis::Error) -> Self { +impl From for CompileErrorInner { + fn from(error: zokrates_analysis::Error) -> Self { CompileErrorInner::AnalysisError(error) } } @@ -173,26 +172,6 @@ impl fmt::Display for CompileErrorInner { } } -#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy)] -pub struct CompileConfig { - #[serde(default)] - pub isolate_branches: bool, - #[serde(default)] - pub debug: bool, -} - -impl CompileConfig { - pub fn isolate_branches(mut self, flag: bool) -> Self { - self.isolate_branches = flag; - self - } - - pub fn debug(mut self, debug: bool) -> Self { - self.debug = debug; - self - } -} - type FilePath = PathBuf; pub fn compile<'ast, T: Field, E: Into>( diff --git a/zokrates_core/src/imports.rs b/zokrates_core/src/imports.rs index 9abd9c1ba..f7fa95f13 100644 --- a/zokrates_core/src/imports.rs +++ b/zokrates_core/src/imports.rs @@ -147,6 +147,10 @@ impl Importer { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::Unpack), }, + "field_to_bool_unsafe" => SymbolDeclaration { + id: symbol.get_alias(), + symbol: Symbol::Flat(FlatEmbed::FieldToBoolUnsafe), + }, "bit_array_le" => SymbolDeclaration { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::BitArrayLe), diff --git a/zokrates_core/src/lib.rs b/zokrates_core/src/lib.rs index b6cebfcb6..51de21db8 100644 --- a/zokrates_core/src/lib.rs +++ b/zokrates_core/src/lib.rs @@ -1,9 +1,7 @@ #![feature(box_patterns, box_syntax)] pub mod compile; -mod flatten; pub mod imports; mod macros; mod optimizer; mod semantics; -mod static_analysis; diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index baba3ab2a..5a325cb85 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1130,12 +1130,18 @@ impl<'ast, T: Field> Checker<'ast, T> { // for declaration signatures, generics cannot be ignored generics.0.insert( generic.clone(), - UExpressionInner::Identifier(self.id_in_this_scope(generic.name().into()).into()) - .annotate(UBitwidth::B32), + UExpressionInner::Identifier( + self.id_in_this_scope(generic.name().into()).into(), + ) + .annotate(UBitwidth::B32), ); //we don't have to check for conflicts here, because this was done when checking the signature - self.insert_into_scope(generic.name().into(), Type::Uint(UBitwidth::B32), false); + self.insert_into_scope( + generic.name().into(), + Type::Uint(UBitwidth::B32), + false, + ); } for (arg, decl_ty) in funct.arguments.into_iter().zip(s.inputs.iter()) { diff --git a/zokrates_interpreter/Cargo.toml b/zokrates_interpreter/Cargo.toml index 290962557..7e36f1f9f 100644 --- a/zokrates_interpreter/Cargo.toml +++ b/zokrates_interpreter/Cargo.toml @@ -13,6 +13,7 @@ zokrates_field = { version = "0.5", path = "../zokrates_field", default-features zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false } zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false } zokrates_abi = { version = "0.1", path = "../zokrates_abi", default-features = false } +zokrates_analysis = { version = "0.1", path = "../zokrates_analysis", default-features = false } num = { version = "0.1.36", default-features = false } num-bigint = { version = "0.2", default-features = false } diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index f24cad3b0..12eb7b90f 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -82,7 +82,7 @@ impl Interpreter { } _ => Self::execute_solver(&d.solver, &inputs), } - .map_err(|_| Error::Solver)?; + .map_err(|e| Error::Solver(e))?; for (i, o) in d.outputs.iter().enumerate() { witness.insert(*o, res[i].clone()); @@ -167,8 +167,49 @@ impl Interpreter { let res = match solver { Solver::Zir(func) => { - // TODO: implement evaluation of the function - vec![inputs[1].checked_div(&inputs[0]).unwrap()] + use zokrates_ast::zir::result_folder::ResultFolder; + + assert!(func + .arguments + .iter() + .all(|a| a.id._type == zokrates_ast::zir::Type::FieldElement)); + assert_eq!(func.arguments.len(), inputs.len()); + + let constants = func + .arguments + .iter() + .zip(inputs) + .map(|(a, v)| { + ( + a.id.id.clone(), + zokrates_ast::zir::FieldElementExpression::Number(v.clone()).into(), + ) + }) + .collect(); + + let mut propagator = zokrates_analysis::ZirPropagator::with_constants(constants); + + let folded_function = propagator + .fold_function(func.clone()) + .map_err(|e| e.to_string())?; + + assert!(folded_function.statements.len() == 1); + let res = if let zokrates_ast::zir::ZirStatement::Return(v) = + folded_function.statements[0].clone() + { + v.into_iter() + .map(|v| match v { + zokrates_ast::zir::ZirExpression::FieldElement( + zokrates_ast::zir::FieldElementExpression::Number(n), + ) => n, + _ => unreachable!(), + }) + .collect() + } else { + unreachable!() + }; + + res } Solver::ConditionEq => match inputs[0].is_zero() { true => vec![T::zero(), T::one()], @@ -284,7 +325,7 @@ pub struct EvaluationError; #[derive(PartialEq, Eq, Clone, Serialize, Deserialize)] pub enum Error { UnsatisfiedConstraint { error: Option }, - Solver, + Solver(String), WrongInputCount { expected: usize, received: usize }, LogStream, } @@ -327,7 +368,7 @@ impl fmt::Display for Error { _ => write!(f, ""), } } - Error::Solver => write!(f, ""), + Error::Solver(ref e) => write!(f, "Solver error: `{}`", e), Error::WrongInputCount { expected, received } => write!( f, "Program takes {} input{} but was passed {} value{}", diff --git a/zokrates_js/index.d.ts b/zokrates_js/index.d.ts index 979603e86..2aa5892ab 100644 --- a/zokrates_js/index.d.ts +++ b/zokrates_js/index.d.ts @@ -60,6 +60,7 @@ declare module "zokrates-js" { snarkjs?: { program: Uint8Array; }; + constraint_count: number; } export interface SetupKeypair { diff --git a/zokrates_js/lib.js b/zokrates_js/lib.js index 717541231..62886e3d4 100644 --- a/zokrates_js/lib.js +++ b/zokrates_js/lib.js @@ -16,8 +16,9 @@ module.exports = (pkg) => { { program: ptr.program(), abi: ptr.abi(), + constraint_count: ptr.constraint_count(), }, - snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} + snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}, ); ptr.free(); return result; diff --git a/zokrates_js/package-lock.json b/zokrates_js/package-lock.json index 74772fd07..0754562fd 100644 --- a/zokrates_js/package-lock.json +++ b/zokrates_js/package-lock.json @@ -1,18 +1,18 @@ { "name": "zokrates-js", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "zokrates-js", - "version": "1.1.1", + "version": "1.1.2", "license": "GPLv3", "devDependencies": { "dree": "^2.6.1", "mocha": "^9.2.0", "rimraf": "^3.0.2", - "snarkjs": "^0.4.24", + "snarkjs": "^0.4.25", "wasm-pack": "^0.10.2" } }, diff --git a/zokrates_js/package.json b/zokrates_js/package.json index ba2226920..5a0835eaa 100644 --- a/zokrates_js/package.json +++ b/zokrates_js/package.json @@ -32,9 +32,9 @@ "prebuild": "npm install", "build": "npm run build:bundler && npm run build:node", "build:dev": "npm run build:bundler:dev && npm run build:node:dev", - "build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg", + "build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler && npm run clean-pkg", "build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg", - "build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg", + "build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg && npm run clean-node-pkg", "build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg", "clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts", "clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts", diff --git a/zokrates_js/src/lib.rs b/zokrates_js/src/lib.rs index e2c6715de..07082c3e5 100644 --- a/zokrates_js/src/lib.rs +++ b/zokrates_js/src/lib.rs @@ -20,10 +20,8 @@ use zokrates_ast::typed::types::{ConcreteSignature, ConcreteType, GTupleType}; use zokrates_bellman::Bellman; use zokrates_circom::{write_r1cs, write_witness}; use zokrates_common::helpers::{BackendParameter, CurveParameter, SchemeParameter}; -use zokrates_common::Resolver; -use zokrates_core::compile::{ - compile as core_compile, CompilationArtifacts, CompileConfig, CompileError, -}; +use zokrates_common::{CompileConfig, Resolver}; +use zokrates_core::compile::{compile as core_compile, CompilationArtifacts, CompileError}; use zokrates_core::imports::Error; use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; use zokrates_proof_systems::groth16::G16; @@ -43,6 +41,7 @@ pub struct CompilationResult { program: Vec, abi: Abi, snarkjs_program: Option>, + constraint_count: u32, } #[wasm_bindgen] @@ -63,6 +62,10 @@ impl CompilationResult { arr }) } + + pub fn constraint_count(&self) -> JsValue { + JsValue::from_serde(&self.constraint_count).unwrap() + } } #[derive(Serialize, Deserialize)] @@ -255,6 +258,7 @@ mod internal { let abi = artifacts.abi().clone(); let program = artifacts.prog().collect(); + let constraint_count = program.constraint_count() as u32; let snarkjs_program = with_snarkjs_program.then(|| { let mut buffer = Cursor::new(vec![]); write_r1cs(&mut buffer, program.clone()).unwrap(); @@ -267,6 +271,7 @@ mod internal { abi, program: buffer.into_inner(), snarkjs_program, + constraint_count, }) } diff --git a/zokrates_test/src/lib.rs b/zokrates_test/src/lib.rs index fd4b0f7a4..0aa85f907 100644 --- a/zokrates_test/src/lib.rs +++ b/zokrates_test/src/lib.rs @@ -8,7 +8,8 @@ use std::path::{Path, PathBuf}; use zokrates_ast::typed::types::GTupleType; use zokrates_ast::typed::ConcreteSignature; use zokrates_ast::typed::ConcreteType; -use zokrates_core::compile::{compile, CompileConfig}; +use zokrates_common::CompileConfig; +use zokrates_core::compile::compile; use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; use zokrates_fs_resolver::FileSystemResolver; From 8879c42837774181025a1fee5f41c15ce21a0239 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 17 Oct 2022 13:39:16 +0200 Subject: [PATCH 12/94] minor refactor --- zokrates_analysis/src/flatten_complex_types.rs | 3 +-- zokrates_ast/src/common/solvers.rs | 2 +- zokrates_ast/src/typed/mod.rs | 9 ++++----- zokrates_ast/src/zir/mod.rs | 2 +- zokrates_codegen/src/lib.rs | 2 -- zokrates_core/src/optimizer/directive.rs | 4 +++- zokrates_core/src/semantics.rs | 4 ++-- zokrates_interpreter/src/lib.rs | 10 ++++------ zokrates_js/index.d.ts | 2 +- zokrates_js/lib.js | 2 +- zokrates_js/package.json | 4 ++-- zokrates_js/tests/tests.js | 1 + zokrates_proof_systems/src/lib.rs | 2 +- 13 files changed, 22 insertions(+), 25 deletions(-) diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 2964ff06e..666470410 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -455,8 +455,7 @@ fn fold_assembly_statement<'ast, T: Field>( let mut statements_buffer: Vec> = statements_buffer .into_iter() .rev() - .map(|s| finder.fold_statement(s)) - .flatten() + .flat_map(|s| finder.fold_statement(s)) .collect(); statements_buffer.reverse(); diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index 598b35e8d..b63a71d15 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -23,7 +23,7 @@ pub enum Solver<'ast, T> { impl<'ast, T: fmt::Debug + fmt::Display> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Solver::Zir(func) => write!(f, "Zir({})", "ignored"), + Solver::Zir(_) => write!(f, "Zir(ignored)"), _ => write!(f, "{:?}", self), } } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index f6f865a8f..59e793032 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1334,11 +1334,10 @@ impl<'ast, T> FieldElementExpression<'ast, T> { FieldElementExpression::Sub(box left, box right) => { left.is_linear() && right.is_linear() } - FieldElementExpression::Mult(box left, box right) => match (left, right) { - (FieldElementExpression::Number(_), _) => true, - (_, FieldElementExpression::Number(_)) => true, - _ => false, - }, + FieldElementExpression::Mult(box left, box right) => matches!( + (left, right), + (FieldElementExpression::Number(_), _) | (_, FieldElementExpression::Number(_)) + ), FieldElementExpression::Div(_, _) => false, FieldElementExpression::Pow(_, _) => false, FieldElementExpression::Conditional(_) => false, diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index c1752b526..d33ea7efc 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -209,7 +209,7 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> { match self { ZirStatement::Return(ref exprs) => { write!(f, "return")?; - if exprs.len() > 0 { + if !exprs.is_empty() { write!( f, " {}", diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index d80b7eefe..3e7c2689f 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -1579,8 +1579,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { let left_metadata = left.metadata.clone().unwrap(); let right_metadata = right.metadata.clone().unwrap(); - println!("left {}, right {}", left, right); - match (left.into_inner(), right.into_inner()) { (UExpressionInner::And(box a, box b), UExpressionInner::And(box aa, box c)) => { if aa.clone().into_inner() == UExpressionInner::Not(box a.clone()) { diff --git a/zokrates_core/src/optimizer/directive.rs b/zokrates_core/src/optimizer/directive.rs index b216bef67..4d140637a 100644 --- a/zokrates_core/src/optimizer/directive.rs +++ b/zokrates_core/src/optimizer/directive.rs @@ -14,9 +14,11 @@ use zokrates_ast::ir::folder::*; use zokrates_ast::ir::*; use zokrates_field::Field; +type SolverCall<'ast, T> = (Solver<'ast, T>, Vec>); + #[derive(Debug, Default)] pub struct DirectiveOptimizer<'ast, T> { - calls: HashMap<(Solver<'ast, T>, Vec>), Vec>, + calls: HashMap, Vec>, /// Map of renamings for reassigned variables while processing the program. substitution: HashMap, } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 5a325cb85..246f1166f 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1791,7 +1791,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let e = match checked_e { TypedExpression::FieldElement(e) => Ok(e), - TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), // todo: handle properly + TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), _ => Err(ErrorInner { pos: Some(pos), message: "Only field element expressions are allowed in the assembly" @@ -3718,7 +3718,7 @@ impl<'ast, T: Field> Checker<'ast, T> { ty, is_mutable, }; - self.scope.insert(id.into(), info) + self.scope.insert(id, info) } fn find_functions( diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index 12eb7b90f..6de067647 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -82,7 +82,7 @@ impl Interpreter { } _ => Self::execute_solver(&d.solver, &inputs), } - .map_err(|e| Error::Solver(e))?; + .map_err(Error::Solver)?; for (i, o) in d.outputs.iter().enumerate() { witness.insert(*o, res[i].clone()); @@ -193,8 +193,8 @@ impl Interpreter { .fold_function(func.clone()) .map_err(|e| e.to_string())?; - assert!(folded_function.statements.len() == 1); - let res = if let zokrates_ast::zir::ZirStatement::Return(v) = + assert_eq!(folded_function.statements.len(), 1); + if let zokrates_ast::zir::ZirStatement::Return(v) = folded_function.statements[0].clone() { v.into_iter() @@ -207,9 +207,7 @@ impl Interpreter { .collect() } else { unreachable!() - }; - - res + } } Solver::ConditionEq => match inputs[0].is_zero() { true => vec![T::zero(), T::one()], diff --git a/zokrates_js/index.d.ts b/zokrates_js/index.d.ts index 2aa5892ab..7c7bc8e05 100644 --- a/zokrates_js/index.d.ts +++ b/zokrates_js/index.d.ts @@ -60,7 +60,7 @@ declare module "zokrates-js" { snarkjs?: { program: Uint8Array; }; - constraint_count: number; + constraintCount?: number; } export interface SetupKeypair { diff --git a/zokrates_js/lib.js b/zokrates_js/lib.js index 62886e3d4..464e8cb5a 100644 --- a/zokrates_js/lib.js +++ b/zokrates_js/lib.js @@ -16,7 +16,7 @@ module.exports = (pkg) => { { program: ptr.program(), abi: ptr.abi(), - constraint_count: ptr.constraint_count(), + constraintCount: ptr.constraint_count(), }, snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}, ); diff --git a/zokrates_js/package.json b/zokrates_js/package.json index 5a0835eaa..ba2226920 100644 --- a/zokrates_js/package.json +++ b/zokrates_js/package.json @@ -32,9 +32,9 @@ "prebuild": "npm install", "build": "npm run build:bundler && npm run build:node", "build:dev": "npm run build:bundler:dev && npm run build:node:dev", - "build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler && npm run clean-pkg", + "build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg", "build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg", - "build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg && npm run clean-node-pkg", + "build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg", "build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg", "clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts", "clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts", diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index 86ed3bcd0..d9b74b703 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -44,6 +44,7 @@ describe("tests", () => { ); assert.ok(artifacts); assert.ok(artifacts.snarkjs === undefined); + assert.eq(artifacts.constraintCount === 1); }); }); diff --git a/zokrates_proof_systems/src/lib.rs b/zokrates_proof_systems/src/lib.rs index 4184f6c9f..7076cde06 100644 --- a/zokrates_proof_systems/src/lib.rs +++ b/zokrates_proof_systems/src/lib.rs @@ -126,7 +126,7 @@ pub trait MpcBackend> { output: &mut W, ) -> Result<(), String>; - fn contribute<'a, R: Read, W: Write, G: Rng>( + fn contribute( params: &mut R, rng: &mut G, output: &mut W, From 608a7c41d296ad621d217a6e2b67aaf6b50b51f6 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 18 Oct 2022 13:43:29 +0200 Subject: [PATCH 13/94] fix tests --- zokrates_ast/src/typed/mod.rs | 2 +- zokrates_ast/src/zir/mod.rs | 29 --------- zokrates_cli/src/bin.rs | 7 +- zokrates_core/src/semantics.rs | 64 ++++++++++++++----- .../tests/tests/assembly/division.json | 25 ++++++++ .../tests/tests/assembly/division.zok | 8 +++ zokrates_interpreter/src/lib.rs | 2 +- zokrates_js/tests/tests.js | 2 +- zokrates_test/tests/out_of_range.rs | 10 +-- 9 files changed, 93 insertions(+), 56 deletions(-) create mode 100644 zokrates_core_test/tests/tests/assembly/division.json create mode 100644 zokrates_core_test/tests/tests/assembly/division.zok diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 59e793032..b695d6a25 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1319,7 +1319,7 @@ impl<'ast, T> FieldElementExpression<'ast, T> { FieldElementExpression::Mult(box left, box right) => { left.is_linear() && right.is_linear() } - _ => false, + e => e.is_linear(), } } diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index d33ea7efc..b1577f8aa 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -116,35 +116,6 @@ impl RuntimeError { } } -// #[derive(Clone, PartialEq, Hash, Eq, Debug)] -// pub struct ZirBlock<'ast, T> { -// pub statements: Vec>, -// pub value: FieldElementExpression<'ast, T>, -// } -// -// impl<'ast, T> ZirBlock<'ast, T> { -// pub fn new( -// statements: Vec>, -// value: FieldElementExpression<'ast, T>, -// ) -> Self { -// Self { statements, value } -// } -// } -// impl<'ast, T: fmt::Display> fmt::Display for ZirBlock<'ast, T> { -// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { -// write!( -// f, -// "{{\n{}\n}}", -// self.statements -// .iter() -// .map(|s| s.to_string()) -// .chain(std::iter::once(self.value.to_string())) -// .collect::>() -// .join("\n") -// ) -// } -// } - #[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum ZirAssemblyStatement<'ast, T> { Assignment( diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 99a1b0838..a2b857a91 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -121,7 +121,8 @@ mod tests { use std::io::{BufReader, Read}; use std::string::String; use typed_arena::Arena; - use zokrates_core::compile::{compile, CompilationArtifacts, CompileConfig}; + use zokrates_common::CompileConfig; + use zokrates_core::compile::{compile, CompilationArtifacts}; use zokrates_field::Bn128Field; use zokrates_fs_resolver::FileSystemResolver; @@ -219,7 +220,7 @@ mod tests { let interpreter = zokrates_interpreter::Interpreter::default(); let _ = interpreter - .execute(artifacts.prog(), &[Bn128Field::from(0)]) + .execute(artifacts.prog(), &[Bn128Field::from(0u32)]) .unwrap(); } } @@ -258,7 +259,7 @@ mod tests { let interpreter = zokrates_interpreter::Interpreter::default(); - let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]); + let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0u32)]); assert!(res.is_err()); } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 246f1166f..369c9fa6d 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1799,7 +1799,6 @@ impl<'ast, T: Field> Checker<'ast, T> { }), }?; - let e = FieldElementExpression::block(vec![], e); match constrained { true => { if !e.is_quadratic() { @@ -1808,6 +1807,7 @@ impl<'ast, T: Field> Checker<'ast, T> { message: "Non quadratic constraints are not allowed".to_string(), }); } + let e = FieldElementExpression::block(vec![], e); match assignee.get_type() { Type::FieldElement => Ok(vec![ TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()), @@ -1819,7 +1819,10 @@ impl<'ast, T: Field> Checker<'ast, T> { }), } } - false => Ok(vec![TypedAssemblyStatement::Assignment(assignee, e)]), + false => { + let e = FieldElementExpression::block(vec![], e); + Ok(vec![TypedAssemblyStatement::Assignment(assignee, e)]) + } } } AssemblyStatement::Constraint(lhs, rhs) => { @@ -4572,7 +4575,7 @@ mod tests { let mut scope = Scope::default(); scope.insert( - "b", + std::borrow::Cow::Borrowed("b"), IdentifierInfo { id: "b".into(), ty: Type::FieldElement, @@ -4815,12 +4818,19 @@ mod tests { let for_statements_checked = vec![TypedStatement::definition( typed::Variable::uint( - CoreIdentifier::Source(ShadowedIdentifier::shadow("a", 1)), + CoreIdentifier::Source(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("a"), + 1, + )), UBitwidth::B32, ) .into(), UExpressionInner::Identifier( - CoreIdentifier::Source(ShadowedIdentifier::shadow("i", 1)).into(), + CoreIdentifier::Source(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("i"), + 1, + )) + .into(), ) .annotate(UBitwidth::B32) .into(), @@ -4829,7 +4839,10 @@ mod tests { let foo_statements_checked = vec![ TypedStatement::For( typed::Variable::uint( - CoreIdentifier::Source(ShadowedIdentifier::shadow("i", 1)), + CoreIdentifier::Source(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("i"), + 1, + )), UBitwidth::B32, ), 0u32.into(), @@ -5373,7 +5386,11 @@ mod tests { ); assert!(s2_checked.is_ok()); assert_eq!( - checker.scope.get(&"a").unwrap().ty, + checker + .scope + .get(&std::borrow::Cow::Borrowed("a")) + .unwrap() + .ty, DeclarationType::Boolean ); } @@ -5433,16 +5450,22 @@ mod tests { let expected = vec![ TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), + CoreIdentifier::from(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("a"), + 0, + )), Type::FieldElement, true, ) .into(), - FieldElementExpression::Number(2.into()).into(), + FieldElementExpression::Number(2u32.into()).into(), ), TypedStatement::For( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow("i", 1)), + CoreIdentifier::from(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("i"), + 1, + )), Type::Uint(UBitwidth::B32), false, ), @@ -5451,32 +5474,41 @@ mod tests { vec![ TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), + CoreIdentifier::from(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("a"), + 0, + )), Type::FieldElement, true, ) .into(), - FieldElementExpression::Number(3.into()).into(), + FieldElementExpression::Number(3u32.into()).into(), ), TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow("a", 1)), + CoreIdentifier::from(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("a"), + 1, + )), Type::FieldElement, false, ) .into(), - FieldElementExpression::Number(4.into()).into(), + FieldElementExpression::Number(4u32.into()).into(), ), ], ), TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow("a", 0)), + CoreIdentifier::from(ShadowedIdentifier::shadow( + std::borrow::Cow::Borrowed("a"), + 0, + )), Type::FieldElement, true, ) .into(), - FieldElementExpression::Number(5.into()).into(), + FieldElementExpression::Number(5u32.into()).into(), ), ]; diff --git a/zokrates_core_test/tests/tests/assembly/division.json b/zokrates_core_test/tests/tests/assembly/division.json new file mode 100644 index 000000000..f0da6cc0d --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/division.json @@ -0,0 +1,25 @@ +{ + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["4", "2"] + }, + "output": { + "Ok": { + "value": "2" + } + } + }, + { + "input": { + "values": ["4", "0"] + }, + "output": { + "Err": { + "Solver": "Assertion failed: `Division by zero`" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/division.zok b/zokrates_core_test/tests/tests/assembly/division.zok new file mode 100644 index 000000000..35669ffd6 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/division.zok @@ -0,0 +1,8 @@ +def main(field x, field y) -> field { + field mut z = 0; + asm { + z <-- x / y; + z * y === x; + } + return z; +} \ No newline at end of file diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index 6de067647..6753866fa 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -366,7 +366,7 @@ impl fmt::Display for Error { _ => write!(f, ""), } } - Error::Solver(ref e) => write!(f, "Solver error: `{}`", e), + Error::Solver(ref e) => write!(f, "Solver error: {}", e), Error::WrongInputCount { expected, received } => write!( f, "Program takes {} input{} but was passed {} value{}", diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index d9b74b703..8202baa12 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -44,7 +44,7 @@ describe("tests", () => { ); assert.ok(artifacts); assert.ok(artifacts.snarkjs === undefined); - assert.eq(artifacts.constraintCount === 1); + assert.equal(artifacts.constraintCount, 1); }); }); diff --git a/zokrates_test/tests/out_of_range.rs b/zokrates_test/tests/out_of_range.rs index 9304757d8..781bae761 100644 --- a/zokrates_test/tests/out_of_range.rs +++ b/zokrates_test/tests/out_of_range.rs @@ -4,8 +4,8 @@ extern crate zokrates_field; use std::io; use typed_arena::Arena; +use zokrates_common::CompileConfig; use zokrates_common::Resolver; -use zokrates_core::compile::CompileConfig; use zokrates_core::compile::{compile, CompilationArtifacts}; use zokrates_field::Bn128Field; use zokrates_fs_resolver::FileSystemResolver; @@ -42,7 +42,7 @@ fn lt_field() { assert!(interpreter .execute( res.prog(), - &[Bn128Field::from(10000), Bn128Field::from(5555)] + &[Bn128Field::from(10000u32), Bn128Field::from(5555u32)] ) .is_err()); } @@ -78,7 +78,7 @@ fn lt_uint() { assert!(interpreter .execute( res.prog(), - &[Bn128Field::from(10000), Bn128Field::from(5555)] + &[Bn128Field::from(10000u32), Bn128Field::from(5555u32)] ) .is_err()); } @@ -123,7 +123,7 @@ fn unpack256() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(res.prog(), &[Bn128Field::from(0)]) + .execute(res.prog(), &[Bn128Field::from(0u32)]) .is_err()); } @@ -167,6 +167,6 @@ fn unpack256_unchecked() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(res.prog(), &[Bn128Field::from(0)]) + .execute(res.prog(), &[Bn128Field::from(0u32)]) .is_ok()); } From 6b8f792a1172a8ab48d671702fff77089d97100f Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 18 Oct 2022 15:41:50 +0200 Subject: [PATCH 14/94] js fmt --- zokrates_js/lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_js/lib.js b/zokrates_js/lib.js index 464e8cb5a..b3e1ff4ef 100644 --- a/zokrates_js/lib.js +++ b/zokrates_js/lib.js @@ -18,7 +18,7 @@ module.exports = (pkg) => { abi: ptr.abi(), constraintCount: ptr.constraint_count(), }, - snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}, + snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} ); ptr.free(); return result; From 0abf8504585460f90508335d7248519d8c84a3ec Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 18 Oct 2022 15:43:23 +0200 Subject: [PATCH 15/94] clippy --- zokrates_pest_ast/src/lib.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 7e241886d..d58231ea5 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -425,19 +425,7 @@ mod ast { pub span: Span<'ast>, } - // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] - // #[pest_ast(rule(Rule::op_asm_assign))] - // pub struct AssemblyAssignOperator; - // - // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] - // #[pest_ast(rule(Rule::op_asm_assign_constrain))] - // pub struct AssemblyAssignConstrainOperator; - // - // #[derive(Debug, FromPest, PartialEq, Eq, Clone)] - // #[pest_ast(rule(Rule::op_asm_constrain))] - // pub struct AssemblyConstrainOperator; - - #[derive(Debug, PartialEq, Clone)] + #[derive(Debug, PartialEq, Eq, Clone)] pub enum AssignmentOperator { Assign, AssignConstrain, From 9ff49a076f1b9d0a6c79e30726a97b855285d76b Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 25 Oct 2022 14:49:18 +0200 Subject: [PATCH 16/94] remove quadratic check in semantics --- zokrates_ast/src/typed/mod.rs | 2 +- zokrates_core/src/semantics.rs | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index b695d6a25..59e793032 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1319,7 +1319,7 @@ impl<'ast, T> FieldElementExpression<'ast, T> { FieldElementExpression::Mult(box left, box right) => { left.is_linear() && right.is_linear() } - e => e.is_linear(), + _ => false, } } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 369c9fa6d..b02611650 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1794,19 +1794,13 @@ impl<'ast, T: Field> Checker<'ast, T> { TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), _ => Err(ErrorInner { pos: Some(pos), - message: "Only field element expressions are allowed in the assembly" + message: "Only field element expressions are allowed in the assembly block" .to_string(), }), }?; match constrained { true => { - if !e.is_quadratic() { - return Err(ErrorInner { - pos: Some(pos), - message: "Non quadratic constraints are not allowed".to_string(), - }); - } let e = FieldElementExpression::block(vec![], e); match assignee.get_type() { Type::FieldElement => Ok(vec![ @@ -1852,7 +1846,7 @@ impl<'ast, T: Field> Checker<'ast, T> { } _ => Err(ErrorInner { pos: Some(pos), - message: "Only field element expressions are allowed in the assembly" + message: "Only field element expressions are allowed in the assembly block" .to_string(), }), } From 9aca2d7360574d344de793ddad331321107a328e Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 26 Oct 2022 11:20:51 -0500 Subject: [PATCH 17/94] fix typo --- zokrates_core/src/static_analysis/boolean_array_comparator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zokrates_core/src/static_analysis/boolean_array_comparator.rs b/zokrates_core/src/static_analysis/boolean_array_comparator.rs index f33d07b4f..cb016c034 100644 --- a/zokrates_core/src/static_analysis/boolean_array_comparator.rs +++ b/zokrates_core/src/static_analysis/boolean_array_comparator.rs @@ -124,7 +124,7 @@ mod tests { // a single field is sufficient, as the prime we're working with is 3 bits long, so we can pack up to 2 bits let x = a_id("x").annotate(Type::Boolean, 2u32); - let y = a_id("x").annotate(Type::Boolean, 2u32); + let y = a_id("y").annotate(Type::Boolean, 2u32); let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new(x.clone(), y.clone())); @@ -152,7 +152,7 @@ mod tests { // [x[0] ? 2**2 : 0 + x[1] ? 2**1 : 0, x[2] ? 2**0 : 0] == [y[0] ? 2**2 : 0 + y[1] ? 2**1 : 0 y[2] ? 2**0 : 0] let x = a_id("x").annotate(Type::Boolean, 3u32); - let y = a_id("x").annotate(Type::Boolean, 3u32); + let y = a_id("y").annotate(Type::Boolean, 3u32); let e: BooleanExpression = BooleanExpression::ArrayEq(EqExpression::new(x.clone(), y.clone())); From 113ada36382e7e061f5b694c4d02185f85e232ad Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 31 Oct 2022 20:55:31 +0100 Subject: [PATCH 18/94] bitwise op on field --- zokrates_analysis/src/assembly_analyzer.rs | 55 ++++++++++ .../src/flatten_complex_types.rs | 38 +++++++ zokrates_analysis/src/lib.rs | 14 +++ zokrates_analysis/src/propagation.rs | 100 ++++++++++++++++++ zokrates_analysis/src/zir_propagation.rs | 73 +++++++++++++ zokrates_ast/src/common/error.rs | 7 +- zokrates_ast/src/typed/folder.rs | 30 ++++++ zokrates_ast/src/typed/mod.rs | 30 ++++++ zokrates_ast/src/typed/result_folder.rs | 30 ++++++ zokrates_ast/src/zir/folder.rs | 28 +++++ zokrates_ast/src/zir/mod.rs | 23 ++++ zokrates_ast/src/zir/result_folder.rs | 28 +++++ zokrates_cli/src/ops/inspect.rs | 3 + zokrates_codegen/src/lib.rs | 10 +- zokrates_core/src/semantics.rs | 20 +++- .../tests/tests/assembly/num2bits.json | 57 ++++++++++ .../tests/tests/assembly/num2bits.zok | 21 ++++ 17 files changed, 557 insertions(+), 10 deletions(-) create mode 100644 zokrates_analysis/src/assembly_analyzer.rs create mode 100644 zokrates_core_test/tests/tests/assembly/num2bits.json create mode 100644 zokrates_core_test/tests/tests/assembly/num2bits.zok diff --git a/zokrates_analysis/src/assembly_analyzer.rs b/zokrates_analysis/src/assembly_analyzer.rs new file mode 100644 index 000000000..9d07f77af --- /dev/null +++ b/zokrates_analysis/src/assembly_analyzer.rs @@ -0,0 +1,55 @@ +use std::fmt; +use zokrates_ast::typed::result_folder::{ + fold_assembly_statement, fold_field_expression, ResultFolder, +}; +use zokrates_ast::typed::{FieldElementExpression, TypedAssemblyStatement, TypedProgram}; +use zokrates_field::Field; + +#[derive(Debug)] +pub struct Error(String); + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +pub struct AssemblyAnalyzer; + +impl AssemblyAnalyzer { + pub fn analyze(p: TypedProgram) -> Result, Error> { + let mut checker = AssemblyAnalyzer; + checker.fold_program(p) + } +} + +impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyAnalyzer { + type Error = Error; + + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + match s { + TypedAssemblyStatement::Assignment(_, _) => Ok(s), + s => fold_assembly_statement(self, s), + } + } + + fn fold_field_expression( + &mut self, + e: FieldElementExpression<'ast, T>, + ) -> Result, Self::Error> { + match e { + FieldElementExpression::And(_, _) + | FieldElementExpression::Or(_, _) + | FieldElementExpression::Xor(_, _) + | FieldElementExpression::LeftShift(_, _) + | FieldElementExpression::RightShift(_, _) => Err(Error( + "Bitwise operations on field elements are allowed only in witness assignment statement" + .to_string(), + )), + e => fold_field_expression(self, e), + } + } +} diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 666470410..c38b6c9ba 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -973,6 +973,44 @@ fn fold_field_expression<'ast, T: Field>( ) } typed::FieldElementExpression::Pos(box e) => f.fold_field_expression(statements_buffer, e), + typed::FieldElementExpression::Xor(box left, box right) => { + let left = f.fold_field_expression(statements_buffer, left); + let right = f.fold_field_expression(statements_buffer, right); + + zir::FieldElementExpression::Xor(box left, box right) + } + typed::FieldElementExpression::And(box left, box right) => { + let left = f.fold_field_expression(statements_buffer, left); + let right = f.fold_field_expression(statements_buffer, right); + + zir::FieldElementExpression::And(box left, box right) + } + typed::FieldElementExpression::Or(box left, box right) => { + let left = f.fold_field_expression(statements_buffer, left); + let right = f.fold_field_expression(statements_buffer, right); + + zir::FieldElementExpression::Or(box left, box right) + } + typed::FieldElementExpression::LeftShift(box e, box by) => { + let e = f.fold_field_expression(statements_buffer, e); + + let by = match by.as_inner() { + typed::UExpressionInner::Value(by) => by, + _ => unreachable!("static analysis should have made sure that this is constant"), + }; + + zir::FieldElementExpression::LeftShift(box e, *by as u32) + } + typed::FieldElementExpression::RightShift(box e, box by) => { + let e = f.fold_field_expression(statements_buffer, e); + + let by = match by.as_inner() { + typed::UExpressionInner::Value(by) => by, + _ => unreachable!("static analysis should have made sure that this is constant"), + }; + + zir::FieldElementExpression::RightShift(box e, *by as u32) + } typed::FieldElementExpression::Conditional(c) => f .fold_conditional_expression(statements_buffer, c) .pop() diff --git a/zokrates_analysis/src/lib.rs b/zokrates_analysis/src/lib.rs index dae08c06f..1018a5287 100644 --- a/zokrates_analysis/src/lib.rs +++ b/zokrates_analysis/src/lib.rs @@ -6,6 +6,7 @@ //! @author Thibaut Schaeffer //! @date 2018 +mod assembly_analyzer; mod branch_isolator; mod condition_redefiner; mod constant_argument_checker; @@ -34,6 +35,7 @@ use self::reducer::reduce_program; use self::struct_concretizer::StructConcretizer; use self::uint_optimizer::UintOptimizer; use self::variable_write_remover::VariableWriteRemover; +use crate::assembly_analyzer::AssemblyAnalyzer; use crate::constant_resolver::ConstantResolver; use crate::dead_code::DeadCodeEliminator; use crate::panic_extractor::PanicExtractor; @@ -51,6 +53,7 @@ pub enum Error { ZirPropagation(self::zir_propagation::Error), NonConstantArgument(self::constant_argument_checker::Error), OutOfBounds(self::out_of_bounds::Error), + Assembly(self::assembly_analyzer::Error), } impl From for Error { @@ -83,6 +86,12 @@ impl From for Error { } } +impl From for Error { + fn from(e: assembly_analyzer::Error) -> Self { + Error::Assembly(e) + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -91,6 +100,7 @@ impl fmt::Display for Error { Error::ZirPropagation(e) => write!(f, "{}", e), Error::NonConstantArgument(e) => write!(f, "{}", e), Error::OutOfBounds(e) => write!(f, "{}", e), + Error::Assembly(e) => write!(f, "{}", e), } } } @@ -168,6 +178,10 @@ pub fn analyse<'ast, T: Field>( let r = ConditionRedefiner::redefine(r); log::trace!("\n{}", r); + // analyze assembly + log::debug!("Static analyser: Analyze assembly"); + let r = AssemblyAnalyzer::analyze(r).map_err(Error::from)?; + // convert to zir, removing complex types log::debug!("Static analyser: Convert to zir"); let zir = Flattener::flatten(r); diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index 8bf898a2f..1f8cb11bf 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -10,6 +10,7 @@ use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; use std::fmt; +use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr}; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::result_folder::*; use zokrates_ast::typed::types::Type; @@ -881,6 +882,105 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { )), } } + FieldElementExpression::Xor(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitxor(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) if e1.eq(&e2) => Ok(FieldElementExpression::Number(T::from(0))), + (e1, e2) => Ok(FieldElementExpression::Xor(box e1, box e2)), + } + } + + FieldElementExpression::And(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (_, FieldElementExpression::Number(n)) + | (FieldElementExpression::Number(n), _) + if n == T::from(0) => + { + Ok(FieldElementExpression::Number(n)) + } + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitand(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) => Ok(FieldElementExpression::And(box e1, box e2)), + } + } + FieldElementExpression::Or(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (e, FieldElementExpression::Number(n)) + | (FieldElementExpression::Number(n), e) + if n == T::from(0) => + { + Ok(e) + } + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitor(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) => Ok(FieldElementExpression::Or(box e1, box e2)), + } + } + FieldElementExpression::LeftShift(box e, box by) => { + let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; + match (e, by) { + ( + e, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by == 0 => Ok(e), + ( + FieldElementExpression::Number(n), + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) => Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().shl(by as usize)).unwrap(), + )), + (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), + } + } + FieldElementExpression::RightShift(box e, box by) => { + let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; + match (e, by) { + ( + e, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by == 0 => Ok(e), + ( + FieldElementExpression::Number(n), + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) => Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().shr(by as usize)).unwrap(), + )), + (e, by) => Ok(FieldElementExpression::RightShift(box e, box by)), + } + } e => fold_field_expression(self, e), } } diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index e8bbf9565..32ce06576 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::fmt; +use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr}; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, @@ -242,6 +243,78 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { )), } } + FieldElementExpression::Xor(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitxor(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) if e1.eq(&e2) => Ok(FieldElementExpression::Number(T::from(0))), + (e1, e2) => Ok(FieldElementExpression::Xor(box e1, box e2)), + } + } + FieldElementExpression::And(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (_, FieldElementExpression::Number(n)) + | (FieldElementExpression::Number(n), _) + if n == T::from(0) => + { + Ok(FieldElementExpression::Number(n)) + } + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitand(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) => Ok(FieldElementExpression::And(box e1, box e2)), + } + } + FieldElementExpression::Or(box e1, box e2) => { + let e1 = self.fold_field_expression(e1)?; + let e2 = self.fold_field_expression(e2)?; + + match (e1, e2) { + (e, FieldElementExpression::Number(n)) + | (FieldElementExpression::Number(n), e) + if n == T::from(0) => + { + Ok(e) + } + (FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => { + Ok(FieldElementExpression::Number( + T::try_from(n1.to_biguint().bitor(n2.to_biguint())).unwrap(), + )) + } + (e1, e2) => Ok(FieldElementExpression::Or(box e1, box e2)), + } + } + FieldElementExpression::LeftShift(box e, by) => { + let e = self.fold_field_expression(e)?; + match (e, by) { + (e, by) if by == 0u32 => Ok(e), + (FieldElementExpression::Number(n), by) => Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().shl(by as usize)).unwrap(), + )), + (e, by) => Ok(FieldElementExpression::LeftShift(box e, by)), + } + } + FieldElementExpression::RightShift(box e, by) => { + let e = self.fold_field_expression(e)?; + match (e, by) { + (e, by) if by == 0u32 => Ok(e), + (FieldElementExpression::Number(n), by) => Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().shr(by as usize)).unwrap(), + )), + (e, by) => Ok(FieldElementExpression::RightShift(box e, by)), + } + } e => fold_field_expression(self, e), } } diff --git a/zokrates_ast/src/common/error.rs b/zokrates_ast/src/common/error.rs index b5ea381b4..28c209f46 100644 --- a/zokrates_ast/src/common/error.rs +++ b/zokrates_ast/src/common/error.rs @@ -3,7 +3,7 @@ use std::fmt; #[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)] pub enum RuntimeError { - UnsatisfiedConstraint, + UserConstraint, BellmanConstraint, BellmanOneBinding, BellmanInputBinding, @@ -50,7 +50,8 @@ impl RuntimeError { !matches!( self, - SourceAssertion(_) + UserConstraint + | SourceAssertion(_) | Inverse | SelectRangeCheck | ArgumentBitness @@ -64,7 +65,7 @@ impl fmt::Display for RuntimeError { use RuntimeError::*; let msg = match self { - UnsatisfiedConstraint => "Constraint is unsatisfied", + UserConstraint => "User constraint is unsatisfied", BellmanConstraint => "Bellman constraint is unsatisfied", BellmanOneBinding => "Bellman ~one binding is unsatisfied", BellmanInputBinding => "Bellman input binding is unsatisfied", diff --git a/zokrates_ast/src/typed/folder.rs b/zokrates_ast/src/typed/folder.rs index c0f6daf66..d4cfbc3a7 100644 --- a/zokrates_ast/src/typed/folder.rs +++ b/zokrates_ast/src/typed/folder.rs @@ -754,6 +754,36 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( Pos(box e) } + And(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + And(box left, box right) + } + Or(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + Or(box left, box right) + } + Xor(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + Xor(box left, box right) + } + LeftShift(box e, box by) => { + let e = f.fold_field_expression(e); + let by = f.fold_uint_expression(by); + + LeftShift(box e, box by) + } + RightShift(box e, box by) => { + let e = f.fold_field_expression(e); + let by = f.fold_uint_expression(by); + + RightShift(box e, box by) + } Conditional(c) => match f.fold_conditional_expression(&Type::FieldElement, c) { ConditionalOrExpression::Conditional(s) => Conditional(s), ConditionalOrExpression::Expression(u) => u, diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 59e793032..47eb190f6 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1203,6 +1203,26 @@ pub enum FieldElementExpression<'ast, T> { Box>, Box>, ), + And( + Box>, + Box>, + ), + Or( + Box>, + Box>, + ), + Xor( + Box>, + Box>, + ), + LeftShift( + Box>, + Box>, + ), + RightShift( + Box>, + Box>, + ), Conditional(ConditionalExpression<'ast, T, Self>), Neg(Box>), Pos(Box>), @@ -1340,6 +1360,11 @@ impl<'ast, T> FieldElementExpression<'ast, T> { ), FieldElementExpression::Div(_, _) => false, FieldElementExpression::Pow(_, _) => false, + FieldElementExpression::And(_, _) => false, + FieldElementExpression::Or(_, _) => false, + FieldElementExpression::Xor(_, _) => false, + FieldElementExpression::LeftShift(_, _) => false, + FieldElementExpression::RightShift(_, _) => false, FieldElementExpression::Conditional(_) => false, FieldElementExpression::Neg(_) => true, FieldElementExpression::Pos(_) => true, @@ -1793,6 +1818,11 @@ impl<'ast, T: fmt::Display> fmt::Display for FieldElementExpression<'ast, T> { FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs), FieldElementExpression::Neg(ref e) => write!(f, "(-{})", e), FieldElementExpression::Pos(ref e) => write!(f, "(+{})", e), + FieldElementExpression::And(ref lhs, ref rhs) => write!(f, "({} & {})", lhs, rhs), + FieldElementExpression::Or(ref lhs, ref rhs) => write!(f, "({} | {})", lhs, rhs), + FieldElementExpression::Xor(ref lhs, ref rhs) => write!(f, "({} ^ {})", lhs, rhs), + FieldElementExpression::RightShift(ref e, ref by) => write!(f, "({} >> {})", e, by), + FieldElementExpression::LeftShift(ref e, ref by) => write!(f, "({} << {})", e, by), FieldElementExpression::Conditional(ref c) => write!(f, "{}", c), FieldElementExpression::FunctionCall(ref function_call) => { write!(f, "{}", function_call) diff --git a/zokrates_ast/src/typed/result_folder.rs b/zokrates_ast/src/typed/result_folder.rs index 7732bc391..0f2897697 100644 --- a/zokrates_ast/src/typed/result_folder.rs +++ b/zokrates_ast/src/typed/result_folder.rs @@ -788,6 +788,36 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( Pos(box e) } + And(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + And(box left, box right) + } + Or(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + Or(box left, box right) + } + Xor(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + Xor(box left, box right) + } + LeftShift(box e, box by) => { + let e = f.fold_field_expression(e)?; + let by = f.fold_uint_expression(by)?; + + LeftShift(box e, box by) + } + RightShift(box e, box by) => { + let e = f.fold_field_expression(e)?; + let by = f.fold_uint_expression(by)?; + + RightShift(box e, box by) + } Conditional(c) => match f.fold_conditional_expression(&Type::FieldElement, c)? { ConditionalOrExpression::Conditional(c) => Conditional(c), ConditionalOrExpression::Expression(u) => u, diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index 6523e2f8d..2f754cdf0 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -240,6 +240,34 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( let e2 = f.fold_uint_expression(e2); FieldElementExpression::Pow(box e1, box e2) } + FieldElementExpression::And(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + FieldElementExpression::And(box left, box right) + } + FieldElementExpression::Or(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + FieldElementExpression::Or(box left, box right) + } + FieldElementExpression::Xor(box left, box right) => { + let left = f.fold_field_expression(left); + let right = f.fold_field_expression(right); + + FieldElementExpression::Xor(box left, box right) + } + FieldElementExpression::LeftShift(box e, by) => { + let e = f.fold_field_expression(e); + + FieldElementExpression::LeftShift(box e, by) + } + FieldElementExpression::RightShift(box e, by) => { + let e = f.fold_field_expression(e); + + FieldElementExpression::RightShift(box e, by) + } FieldElementExpression::Conditional(c) => { match f.fold_conditional_expression(&Type::FieldElement, c) { ConditionalOrExpression::Conditional(s) => FieldElementExpression::Conditional(s), diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index b1577f8aa..6f3bb81fc 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -429,6 +429,20 @@ pub enum FieldElementExpression<'ast, T> { Box>, #[serde(borrow)] Box>, ), + And( + Box>, + Box>, + ), + Or( + Box>, + Box>, + ), + Xor( + Box>, + Box>, + ), + LeftShift(Box>, u32), + RightShift(Box>, u32), Conditional(ConditionalExpression<'ast, T, FieldElementExpression<'ast, T>>), } @@ -544,6 +558,15 @@ impl<'ast, T: fmt::Display> fmt::Display for FieldElementExpression<'ast, T> { FieldElementExpression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs), FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs), FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs), + FieldElementExpression::And(ref lhs, ref rhs) => write!(f, "({} & {})", lhs, rhs), + FieldElementExpression::Or(ref lhs, ref rhs) => write!(f, "({} | {})", lhs, rhs), + FieldElementExpression::Xor(ref lhs, ref rhs) => write!(f, "({} ^ {})", lhs, rhs), + FieldElementExpression::LeftShift(ref lhs, ref rhs) => { + write!(f, "({} << {})", lhs, rhs) + } + FieldElementExpression::RightShift(ref lhs, ref rhs) => { + write!(f, "({} >> {})", lhs, rhs) + } FieldElementExpression::Conditional(ref c) => { write!(f, "{}", c) } diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 16f78f019..dc9677aa6 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -277,6 +277,34 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( let e2 = f.fold_uint_expression(e2)?; FieldElementExpression::Pow(box e1, box e2) } + FieldElementExpression::Xor(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + FieldElementExpression::Xor(box left, box right) + } + FieldElementExpression::And(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + FieldElementExpression::And(box left, box right) + } + FieldElementExpression::Or(box left, box right) => { + let left = f.fold_field_expression(left)?; + let right = f.fold_field_expression(right)?; + + FieldElementExpression::Or(box left, box right) + } + FieldElementExpression::LeftShift(box e, by) => { + let e = f.fold_field_expression(e)?; + + FieldElementExpression::LeftShift(box e, by) + } + FieldElementExpression::RightShift(box e, by) => { + let e = f.fold_field_expression(e)?; + + FieldElementExpression::RightShift(box e, by) + } FieldElementExpression::Conditional(c) => { match f.fold_conditional_expression(&Type::FieldElement, c)? { ConditionalOrExpression::Conditional(s) => FieldElementExpression::Conditional(s), diff --git a/zokrates_cli/src/ops/inspect.rs b/zokrates_cli/src/ops/inspect.rs index 338c01c41..b8ca37545 100644 --- a/zokrates_cli/src/ops/inspect.rs +++ b/zokrates_cli/src/ops/inspect.rs @@ -52,6 +52,9 @@ fn cli_inspect<'a, T: Field, I: Iterator>>( let curve = format!("{:<17} {}", "curve:", T::name()); let constraint_count = format!("{:<17} {}", "constraint_count:", ir_prog.constraint_count()); + println!("{}", curve); + println!("{}", constraint_count); + if sub_matches.is_present("ztf") { let output_path = PathBuf::from(sub_matches.value_of("input").unwrap()).with_extension("ztf"); diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index 3e7c2689f..a93e68b10 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -2222,6 +2222,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { FieldElementExpression::Conditional(e) => self .flatten_conditional_expression(statements_flattened, e) .get_field_unchecked(), + _ => unreachable!(), } } @@ -2234,7 +2235,12 @@ impl<'ast, T: Field> Flattener<'ast, T> { ZirAssemblyStatement::Assignment(assignees, function) => { let outputs: Vec = assignees .iter() - .map(|a| self.use_variable(a)) /*self.layout.get(&a.id).cloned().unwrap()*/ + .map(|a| { + self.layout + .get(&a.id) + .cloned() + .unwrap_or_else(|| self.use_variable(a)) + }) .collect(); let inputs: Vec> = function .arguments @@ -2253,7 +2259,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened, lhs, rhs, - RuntimeError::UnsatisfiedConstraint, + RuntimeError::UserConstraint, ) } } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index b02611650..d70c71dda 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -3553,9 +3553,11 @@ impl<'ast, T: Field> Checker<'ast, T> { match e1 { TypedExpression::Int(e1) => Ok(IntExpression::LeftShift(box e1, box e2).into()), TypedExpression::Uint(e1) => Ok(UExpression::left_shift(e1, e2).into()), + TypedExpression::FieldElement(e1) => { + Ok(FieldElementExpression::LeftShift(box e1, box e2).into()) + } e1 => Err(ErrorInner { pos: Some(pos), - message: format!( "Cannot left-shift {} by {}", e1.get_type(), @@ -3582,9 +3584,11 @@ impl<'ast, T: Field> Checker<'ast, T> { Ok(IntExpression::RightShift(box e1, box e2).into()) } TypedExpression::Uint(e1) => Ok(UExpression::right_shift(e1, e2).into()), + TypedExpression::FieldElement(e1) => { + Ok(FieldElementExpression::RightShift(box e1, box e2).into()) + } e1 => Err(ErrorInner { pos: Some(pos), - message: format!( "Cannot right-shift {} by {}", e1.get_type(), @@ -3609,6 +3613,9 @@ impl<'ast, T: Field> Checker<'ast, T> { (TypedExpression::Int(e1), TypedExpression::Int(e2)) => { Ok(IntExpression::Or(box e1, box e2).into()) } + (TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => { + Ok(FieldElementExpression::Or(box e1, box e2).into()) + } (TypedExpression::Uint(e1), TypedExpression::Uint(e2)) if e1.bitwidth() == e2.bitwidth() => { @@ -3616,7 +3623,6 @@ impl<'ast, T: Field> Checker<'ast, T> { } (e1, e2) => Err(ErrorInner { pos: Some(pos), - message: format!( "Cannot apply `|` to {}, {}", e1.get_type(), @@ -3641,6 +3647,9 @@ impl<'ast, T: Field> Checker<'ast, T> { (TypedExpression::Int(e1), TypedExpression::Int(e2)) => { Ok(IntExpression::And(box e1, box e2).into()) } + (TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => { + Ok(FieldElementExpression::And(box e1, box e2).into()) + } (TypedExpression::Uint(e1), TypedExpression::Uint(e2)) if e1.bitwidth() == e2.bitwidth() => { @@ -3648,7 +3657,6 @@ impl<'ast, T: Field> Checker<'ast, T> { } (e1, e2) => Err(ErrorInner { pos: Some(pos), - message: format!( "Cannot apply `&` to {}, {}", e1.get_type(), @@ -3673,6 +3681,9 @@ impl<'ast, T: Field> Checker<'ast, T> { (TypedExpression::Int(e1), TypedExpression::Int(e2)) => { Ok(IntExpression::Xor(box e1, box e2).into()) } + (TypedExpression::FieldElement(e1), TypedExpression::FieldElement(e2)) => { + Ok(FieldElementExpression::Xor(box e1, box e2).into()) + } (TypedExpression::Uint(e1), TypedExpression::Uint(e2)) if e1.bitwidth() == e2.bitwidth() => { @@ -3680,7 +3691,6 @@ impl<'ast, T: Field> Checker<'ast, T> { } (e1, e2) => Err(ErrorInner { pos: Some(pos), - message: format!( "Cannot apply `^` to {}, {}", e1.get_type(), diff --git a/zokrates_core_test/tests/tests/assembly/num2bits.json b/zokrates_core_test/tests/tests/assembly/num2bits.json new file mode 100644 index 000000000..ba04a1e67 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/num2bits.json @@ -0,0 +1,57 @@ +{ + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "value": ["1", "0", "0", "0"] + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Ok": { + "value": ["0", "1", "0", "0"] + } + } + }, + { + "input": { + "values": ["3"] + }, + "output": { + "Ok": { + "value": ["1", "1", "0", "0"] + } + } + }, + { + "input": { + "values": ["15"] + }, + "output": { + "Ok": { + "value": ["1", "1", "1", "1"] + } + } + }, + { + "input": { + "values": ["16"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": "UserConstraint" + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/num2bits.zok b/zokrates_core_test/tests/tests/assembly/num2bits.zok new file mode 100644 index 000000000..72b42e083 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/num2bits.zok @@ -0,0 +1,21 @@ +def num2bits(field num) -> field[N] { + field[N] mut out = [0; N]; + field mut lc1 = 0; + field mut e2 = 1; + for u32 i in 0..N { + asm { + out[i] <-- (num >> i) & 1; + out[i] * (out[i] - 1) === 0; + } + lc1 = lc1 + out[i] * e2; + e2 = e2 + e2; + } + asm { + lc1 === num; + } + return out; +} + +def main(field input) -> field[4] { + return num2bits(input); +} \ No newline at end of file From 33c6bfce9bf8b39bee0e5f23434bddeaa2fe79a8 Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 3 Nov 2022 19:34:32 +0100 Subject: [PATCH 19/94] add more asm tests --- .../src/constant_argument_checker.rs | 43 +++++++++++++++++- zokrates_analysis/src/lib.rs | 18 ++++---- ...{assembly_analyzer.rs => zir_validator.rs} | 23 +++++----- zokrates_ast/src/common/solvers.rs | 2 +- .../tests/tests/assembly/binary_check.json | 37 +++++++++++++++ .../tests/tests/assembly/binary_check.zok | 5 +++ .../assembly/{num2bits.json => bitify.json} | 0 .../assembly/{num2bits.zok => bitify.zok} | 4 +- .../tests/tests/assembly/xor_gate.json | 45 +++++++++++++++++++ .../tests/tests/assembly/xor_gate.zok | 8 ++++ 10 files changed, 159 insertions(+), 26 deletions(-) rename zokrates_analysis/src/{assembly_analyzer.rs => zir_validator.rs} (59%) create mode 100644 zokrates_core_test/tests/tests/assembly/binary_check.json create mode 100644 zokrates_core_test/tests/tests/assembly/binary_check.zok rename zokrates_core_test/tests/tests/assembly/{num2bits.json => bitify.json} (100%) rename zokrates_core_test/tests/tests/assembly/{num2bits.zok => bitify.zok} (83%) create mode 100644 zokrates_core_test/tests/tests/assembly/xor_gate.json create mode 100644 zokrates_core_test/tests/tests/assembly/xor_gate.zok diff --git a/zokrates_analysis/src/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs index c7ee629a3..7f3a1ce36 100644 --- a/zokrates_analysis/src/constant_argument_checker.rs +++ b/zokrates_analysis/src/constant_argument_checker.rs @@ -2,8 +2,8 @@ use std::fmt; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::{ result_folder::ResultFolder, - result_folder::{fold_statement, fold_uint_expression_inner}, - Constant, EmbedCall, TypedStatement, UBitwidth, UExpressionInner, + result_folder::{fold_field_expression, fold_statement, fold_uint_expression_inner}, + Constant, EmbedCall, FieldElementExpression, TypedStatement, UBitwidth, UExpressionInner, }; use zokrates_ast::typed::{DefinitionRhs, TypedProgram}; use zokrates_field::Field; @@ -72,6 +72,45 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker { } } + fn fold_field_expression( + &mut self, + e: FieldElementExpression<'ast, T>, + ) -> Result, Self::Error> { + match e { + FieldElementExpression::LeftShift(box e, box by) => { + let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; + + match by.as_inner() { + UExpressionInner::Value(_) => { + Ok(FieldElementExpression::LeftShift(box e, box by)) + } + by => Err(Error(format!( + "Cannot shift by a variable value, found `{} << {}`", + e, + by.clone().annotate(UBitwidth::B32) + ))), + } + } + FieldElementExpression::RightShift(box e, box by) => { + let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; + + match by.as_inner() { + UExpressionInner::Value(_) => { + Ok(FieldElementExpression::RightShift(box e, box by)) + } + by => Err(Error(format!( + "Cannot shift by a variable value, found `{} << {}`", + e, + by.clone().annotate(UBitwidth::B32) + ))), + } + } + e => fold_field_expression(self, e), + } + } + fn fold_uint_expression_inner( &mut self, bitwidth: UBitwidth, diff --git a/zokrates_analysis/src/lib.rs b/zokrates_analysis/src/lib.rs index 1018a5287..79efe9f88 100644 --- a/zokrates_analysis/src/lib.rs +++ b/zokrates_analysis/src/lib.rs @@ -6,7 +6,6 @@ //! @author Thibaut Schaeffer //! @date 2018 -mod assembly_analyzer; mod branch_isolator; mod condition_redefiner; mod constant_argument_checker; @@ -23,6 +22,7 @@ mod struct_concretizer; mod uint_optimizer; mod variable_write_remover; mod zir_propagation; +mod zir_validator; use self::branch_isolator::Isolator; use self::condition_redefiner::ConditionRedefiner; @@ -35,11 +35,11 @@ use self::reducer::reduce_program; use self::struct_concretizer::StructConcretizer; use self::uint_optimizer::UintOptimizer; use self::variable_write_remover::VariableWriteRemover; -use crate::assembly_analyzer::AssemblyAnalyzer; use crate::constant_resolver::ConstantResolver; use crate::dead_code::DeadCodeEliminator; use crate::panic_extractor::PanicExtractor; pub use crate::zir_propagation::ZirPropagator; +use crate::zir_validator::ZirValidator; use std::fmt; use zokrates_ast::typed::{abi::Abi, TypedProgram}; use zokrates_ast::zir::ZirProgram; @@ -53,7 +53,7 @@ pub enum Error { ZirPropagation(self::zir_propagation::Error), NonConstantArgument(self::constant_argument_checker::Error), OutOfBounds(self::out_of_bounds::Error), - Assembly(self::assembly_analyzer::Error), + Assembly(self::zir_validator::Error), } impl From for Error { @@ -86,8 +86,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: assembly_analyzer::Error) -> Self { +impl From for Error { + fn from(e: zir_validator::Error) -> Self { Error::Assembly(e) } } @@ -178,10 +178,6 @@ pub fn analyse<'ast, T: Field>( let r = ConditionRedefiner::redefine(r); log::trace!("\n{}", r); - // analyze assembly - log::debug!("Static analyser: Analyze assembly"); - let r = AssemblyAnalyzer::analyze(r).map_err(Error::from)?; - // convert to zir, removing complex types log::debug!("Static analyser: Convert to zir"); let zir = Flattener::flatten(r); @@ -205,5 +201,9 @@ pub fn analyse<'ast, T: Field>( let zir = UintOptimizer::optimize(zir); log::trace!("\n{}", zir); + // validate zir + log::debug!("Static analyser: Validate zir"); + let zir = ZirValidator::validate(zir).map_err(Error::from)?; + Ok((zir, abi)) } diff --git a/zokrates_analysis/src/assembly_analyzer.rs b/zokrates_analysis/src/zir_validator.rs similarity index 59% rename from zokrates_analysis/src/assembly_analyzer.rs rename to zokrates_analysis/src/zir_validator.rs index 9d07f77af..ea9e61503 100644 --- a/zokrates_analysis/src/assembly_analyzer.rs +++ b/zokrates_analysis/src/zir_validator.rs @@ -1,8 +1,8 @@ use std::fmt; -use zokrates_ast::typed::result_folder::{ +use zokrates_ast::zir::result_folder::{ fold_assembly_statement, fold_field_expression, ResultFolder, }; -use zokrates_ast::typed::{FieldElementExpression, TypedAssemblyStatement, TypedProgram}; +use zokrates_ast::zir::{FieldElementExpression, ZirAssemblyStatement, ZirProgram}; use zokrates_field::Field; #[derive(Debug)] @@ -14,24 +14,24 @@ impl fmt::Display for Error { } } -pub struct AssemblyAnalyzer; +pub struct ZirValidator; -impl AssemblyAnalyzer { - pub fn analyze(p: TypedProgram) -> Result, Error> { - let mut checker = AssemblyAnalyzer; +impl ZirValidator { + pub fn validate(p: ZirProgram) -> Result, Error> { + let mut checker = ZirValidator; checker.fold_program(p) } } -impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyAnalyzer { +impl<'ast, T: Field> ResultFolder<'ast, T> for ZirValidator { type Error = Error; fn fold_assembly_statement( &mut self, - s: TypedAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { + s: ZirAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { match s { - TypedAssemblyStatement::Assignment(_, _) => Ok(s), + ZirAssemblyStatement::Assignment(_, _) => Ok(s), s => fold_assembly_statement(self, s), } } @@ -46,8 +46,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyAnalyzer { | FieldElementExpression::Xor(_, _) | FieldElementExpression::LeftShift(_, _) | FieldElementExpression::RightShift(_, _) => Err(Error( - "Bitwise operations on field elements are allowed only in witness assignment statement" - .to_string(), + format!("Found bitwise operation in expression `{}` of type `field` (only allowed in assembly assignment statement)", e) )), e => fold_field_expression(self, e), } diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index b63a71d15..26247f596 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -23,7 +23,7 @@ pub enum Solver<'ast, T> { impl<'ast, T: fmt::Debug + fmt::Display> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - Solver::Zir(_) => write!(f, "Zir(ignored)"), + Solver::Zir(_) => write!(f, "Zir(..)"), _ => write!(f, "{:?}", self), } } diff --git a/zokrates_core_test/tests/tests/assembly/binary_check.json b/zokrates_core_test/tests/tests/assembly/binary_check.json new file mode 100644 index 000000000..05148b36c --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/binary_check.json @@ -0,0 +1,37 @@ +{ + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "value": [] + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "value": [] + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": "UserConstraint" + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/binary_check.zok b/zokrates_core_test/tests/tests/assembly/binary_check.zok new file mode 100644 index 000000000..60b08d7cf --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/binary_check.zok @@ -0,0 +1,5 @@ +def main(field x) { + asm { + x * (x - 1) === 0; + } +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/num2bits.json b/zokrates_core_test/tests/tests/assembly/bitify.json similarity index 100% rename from zokrates_core_test/tests/tests/assembly/num2bits.json rename to zokrates_core_test/tests/tests/assembly/bitify.json diff --git a/zokrates_core_test/tests/tests/assembly/num2bits.zok b/zokrates_core_test/tests/tests/assembly/bitify.zok similarity index 83% rename from zokrates_core_test/tests/tests/assembly/num2bits.zok rename to zokrates_core_test/tests/tests/assembly/bitify.zok index 72b42e083..9867f5f6b 100644 --- a/zokrates_core_test/tests/tests/assembly/num2bits.zok +++ b/zokrates_core_test/tests/tests/assembly/bitify.zok @@ -1,4 +1,4 @@ -def num2bits(field num) -> field[N] { +def bitify(field num) -> field[N] { field[N] mut out = [0; N]; field mut lc1 = 0; field mut e2 = 1; @@ -17,5 +17,5 @@ def num2bits(field num) -> field[N] { } def main(field input) -> field[4] { - return num2bits(input); + return bitify(input); } \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/xor_gate.json b/zokrates_core_test/tests/tests/assembly/xor_gate.json new file mode 100644 index 000000000..099f89b7d --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/xor_gate.json @@ -0,0 +1,45 @@ +{ + "curves": ["Bn128"], + "tests": [ + { + "input": { + "values": ["0", "0"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["1", "0"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["0", "1"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["1", "1"] + }, + "output": { + "Ok": { + "value": "0" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/xor_gate.zok b/zokrates_core_test/tests/tests/assembly/xor_gate.zok new file mode 100644 index 000000000..85d286a4c --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/xor_gate.zok @@ -0,0 +1,8 @@ +def main(field a, field b) -> field { + field mut c = 0; + asm { + c <-- a + b - 2*a*b; + a + b - c === 2*a*b; + } + return c; +} \ No newline at end of file From e51600579f5b3529f8375eaaea3a878e1ad66137 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 8 Nov 2022 14:21:53 +0100 Subject: [PATCH 20/94] implement identifier expression in zir --- zokrates_ast/src/zir/folder.rs | 37 +++++- zokrates_ast/src/zir/mod.rs | 56 +++++++- zokrates_ast/src/zir/result_folder.rs | 40 +++++- zokrates_ast/src/zir/uint.rs | 4 +- zokrates_core/src/flatten/mod.rs | 61 ++++----- .../static_analysis/flatten_complex_types.rs | 14 +- .../src/static_analysis/uint_optimizer.rs | 8 +- .../src/static_analysis/zir_propagation.rs | 124 +++++++++--------- 8 files changed, 229 insertions(+), 115 deletions(-) diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index f934ed3c7..917f8131d 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -60,6 +60,14 @@ pub trait Folder<'ast, T: Field>: Sized { fold_statement(self, s) } + fn fold_identifier_expression + Id<'ast, T>>( + &mut self, + ty: &E::Ty, + e: IdentifierExpression<'ast, E>, + ) -> IdentifierOrExpression<'ast, T, E> { + fold_identifier_expression(self, ty, e) + } + fn fold_conditional_expression + Fold<'ast, T> + Conditional<'ast, T>>( &mut self, ty: &E::Ty, @@ -169,6 +177,19 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( vec![res] } +pub fn fold_identifier_expression< + 'ast, + T: Field, + E: Expr<'ast, T> + Id<'ast, T>, + F: Folder<'ast, T>, +>( + f: &mut F, + _: &E::Ty, + e: IdentifierExpression<'ast, E>, +) -> IdentifierOrExpression<'ast, T, E> { + IdentifierOrExpression::Identifier(IdentifierExpression::new(f.fold_name(e.id))) +} + pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, e: FieldElementExpression<'ast, T>, @@ -176,7 +197,10 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( match e { FieldElementExpression::Number(n) => FieldElementExpression::Number(n), FieldElementExpression::Identifier(id) => { - FieldElementExpression::Identifier(f.fold_name(id)) + match f.fold_identifier_expression(&Type::FieldElement, id) { + IdentifierOrExpression::Identifier(i) => FieldElementExpression::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + } } FieldElementExpression::Select(e) => { match f.fold_select_expression(&Type::FieldElement, e) { @@ -224,7 +248,11 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>( ) -> BooleanExpression<'ast, T> { match e { BooleanExpression::Value(v) => BooleanExpression::Value(v), - BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)), + BooleanExpression::Identifier(id) => match f.fold_identifier_expression(&Type::Boolean, id) + { + IdentifierOrExpression::Identifier(i) => BooleanExpression::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + }, BooleanExpression::Select(e) => match f.fold_select_expression(&Type::Boolean, e) { SelectOrExpression::Select(s) => BooleanExpression::Select(s), SelectOrExpression::Expression(u) => u, @@ -303,7 +331,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: Folder<'ast, T>>( ) -> UExpressionInner<'ast, T> { match e { UExpressionInner::Value(v) => UExpressionInner::Value(v), - UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)), + UExpressionInner::Identifier(id) => match f.fold_identifier_expression(&ty, id) { + IdentifierOrExpression::Identifier(i) => UExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + }, UExpressionInner::Select(e) => match f.fold_select_expression(&ty, e) { SelectOrExpression::Select(s) => UExpressionInner::Select(s), SelectOrExpression::Expression(u) => u, diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index d2cbf6330..ee886ef39 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -17,6 +17,7 @@ pub use crate::zir::uint::{ShouldReduce, UExpression, UExpressionInner, UMetadat use crate::zir::types::Signature; use std::convert::TryFrom; use std::fmt; +use std::marker::PhantomData; use zokrates_field::Field; pub use self::folder::Folder; @@ -208,6 +209,27 @@ pub trait Typed { fn get_type(&self) -> Type; } +#[derive(Debug, Clone, PartialEq, Hash, Eq)] +pub struct IdentifierExpression<'ast, E> { + pub id: Identifier<'ast>, + ty: PhantomData, +} + +impl<'ast, E> fmt::Display for IdentifierExpression<'ast, E> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.id) + } +} + +impl<'ast, E> IdentifierExpression<'ast, E> { + pub fn new(id: Identifier<'ast>) -> Self { + IdentifierExpression { + id, + ty: PhantomData, + } + } +} + #[derive(Debug, Clone, PartialEq, Hash, Eq)] pub struct ConditionalExpression<'ast, T, E> { pub condition: Box>, @@ -352,7 +374,7 @@ pub enum ZirExpressionList<'ast, T> { #[derive(Clone, PartialEq, Hash, Eq, Debug)] pub enum FieldElementExpression<'ast, T> { Number(T), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, Self>), Select(SelectExpression<'ast, T, Self>), Add( Box>, @@ -381,7 +403,7 @@ pub enum FieldElementExpression<'ast, T> { #[derive(Clone, PartialEq, Hash, Eq, Debug)] pub enum BooleanExpression<'ast, T> { Value(bool), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, Self>), Select(SelectExpression<'ast, T, Self>), FieldLt( Box>, @@ -588,7 +610,7 @@ impl<'ast, T: fmt::Debug> fmt::Debug for ZirExpressionList<'ast, T> { } // Common behaviour accross expressions -pub trait Expr<'ast, T>: fmt::Display + PartialEq { +pub trait Expr<'ast, T>: fmt::Display + PartialEq + TryFrom> { type Inner; type Ty: Clone + IntoType; @@ -663,6 +685,34 @@ impl<'ast, T: Field> Expr<'ast, T> for UExpression<'ast, T> { &mut self.inner } } + +pub trait Id<'ast, T>: Expr<'ast, T> { + fn identifier(id: Identifier<'ast>) -> Self::Inner; +} + +impl<'ast, T: Field> Id<'ast, T> for FieldElementExpression<'ast, T> { + fn identifier(id: Identifier<'ast>) -> Self::Inner { + FieldElementExpression::Identifier(IdentifierExpression::new(id)) + } +} + +impl<'ast, T: Field> Id<'ast, T> for BooleanExpression<'ast, T> { + fn identifier(id: Identifier<'ast>) -> Self::Inner { + BooleanExpression::Identifier(IdentifierExpression::new(id)) + } +} + +impl<'ast, T: Field> Id<'ast, T> for UExpression<'ast, T> { + fn identifier(id: Identifier<'ast>) -> Self::Inner { + UExpressionInner::Identifier(IdentifierExpression::new(id)) + } +} + +pub enum IdentifierOrExpression<'ast, T, E: Expr<'ast, T>> { + Identifier(IdentifierExpression<'ast, E>), + Expression(E::Inner), +} + pub trait Conditional<'ast, T> { fn conditional( condition: BooleanExpression<'ast, T>, diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 6b172ff84..803e3ca61 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -97,6 +97,14 @@ pub trait ResultFolder<'ast, T: Field>: Sized { } } + fn fold_identifier_expression + Id<'ast, T> + ResultFold<'ast, T>>( + &mut self, + ty: &E::Ty, + id: IdentifierExpression<'ast, E>, + ) -> Result, Self::Error> { + fold_identifier_expression(self, ty, id) + } + fn fold_conditional_expression< E: Expr<'ast, T> + ResultFold<'ast, T> + Conditional<'ast, T>, >( @@ -210,7 +218,10 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( Ok(match e { FieldElementExpression::Number(n) => FieldElementExpression::Number(n), FieldElementExpression::Identifier(id) => { - FieldElementExpression::Identifier(f.fold_name(id)?) + match f.fold_identifier_expression(&Type::FieldElement, id)? { + IdentifierOrExpression::Identifier(i) => FieldElementExpression::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + } } FieldElementExpression::Select(e) => { match f.fold_select_expression(&Type::FieldElement, e)? { @@ -258,7 +269,12 @@ pub fn fold_boolean_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( ) -> Result, F::Error> { Ok(match e { BooleanExpression::Value(v) => BooleanExpression::Value(v), - BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)?), + BooleanExpression::Identifier(id) => { + match f.fold_identifier_expression(&Type::Boolean, id)? { + IdentifierOrExpression::Identifier(i) => BooleanExpression::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + } + } BooleanExpression::Select(e) => match f.fold_select_expression(&Type::Boolean, e)? { SelectOrExpression::Select(s) => BooleanExpression::Select(s), SelectOrExpression::Expression(u) => u, @@ -338,7 +354,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>( ) -> Result, F::Error> { Ok(match e { UExpressionInner::Value(v) => UExpressionInner::Value(v), - UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)?), + UExpressionInner::Identifier(id) => match f.fold_identifier_expression(&ty, id)? { + IdentifierOrExpression::Identifier(i) => UExpressionInner::Identifier(i), + IdentifierOrExpression::Expression(e) => e, + }, UExpressionInner::Select(e) => match f.fold_select_expression(&ty, e)? { SelectOrExpression::Select(s) => UExpressionInner::Select(s), SelectOrExpression::Expression(u) => u, @@ -444,6 +463,21 @@ pub fn fold_program<'ast, T: Field, F: ResultFolder<'ast, T>>( }) } +pub fn fold_identifier_expression< + 'ast, + T: Field, + E: Expr<'ast, T> + Id<'ast, T>, + F: ResultFolder<'ast, T>, +>( + f: &mut F, + _: &E::Ty, + e: IdentifierExpression<'ast, E>, +) -> Result, F::Error> { + Ok(IdentifierOrExpression::Identifier( + IdentifierExpression::new(f.fold_name(e.id)?), + )) +} + pub fn fold_conditional_expression< 'ast, T: Field, diff --git a/zokrates_ast/src/zir/uint.rs b/zokrates_ast/src/zir/uint.rs index 5d09b4285..6360372c3 100644 --- a/zokrates_ast/src/zir/uint.rs +++ b/zokrates_ast/src/zir/uint.rs @@ -1,5 +1,5 @@ -use crate::zir::identifier::Identifier; use crate::zir::types::UBitwidth; +use crate::zir::IdentifierExpression; use zokrates_field::Field; use super::{ConditionalExpression, SelectExpression}; @@ -172,7 +172,7 @@ pub struct UExpression<'ast, T> { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum UExpressionInner<'ast, T> { Value(u128), - Identifier(Identifier<'ast>), + Identifier(IdentifierExpression<'ast, UExpression<'ast, T>>), Select(SelectExpression<'ast, T, UExpression<'ast, T>>), Add(Box>, Box>), Sub(Box>, Box>), diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index cd2e455c6..6352af7e2 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -832,7 +832,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { ) -> FlatExpression { match expression { BooleanExpression::Identifier(x) => { - FlatExpression::Identifier(*self.layout.get(&x).unwrap()) + FlatExpression::Identifier(*self.layout.get(&x.id).unwrap()) } BooleanExpression::Select(e) => self .flatten_select_expression(statements_flattened, e) @@ -1403,7 +1403,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { FlatUExpression::with_field(FlatExpression::Number(T::from(x))) } // force to be a field element UExpressionInner::Identifier(x) => { - let field = FlatExpression::Identifier(*self.layout.get(&x).unwrap()); + let field = FlatExpression::Identifier(*self.layout.get(&x.id).unwrap()); let bits = self.bits_cache.get(&field).map(|bits| { assert_eq!(bits.len(), target_bitwidth.to_usize()); bits.clone() @@ -2038,9 +2038,9 @@ impl<'ast, T: Field> Flattener<'ast, T> { ) -> FlatExpression { match expr { FieldElementExpression::Number(x) => FlatExpression::Number(x), // force to be a field element - FieldElementExpression::Identifier(x) => { - FlatExpression::Identifier(*self.layout.get(&x).unwrap_or_else(|| panic!("{}", x))) - } + FieldElementExpression::Identifier(x) => FlatExpression::Identifier( + *self.layout.get(&x.id).unwrap_or_else(|| panic!("{}", x)), + ), FieldElementExpression::Select(e) => self .flatten_select_expression(statements_flattened, e) .get_field_unchecked(), @@ -2760,6 +2760,7 @@ mod tests { use zokrates_ast::zir; use zokrates_ast::zir::types::Signature; use zokrates_ast::zir::types::Type; + use zokrates_ast::zir::Id; use zokrates_field::Bn128Field; fn flatten_function(f: ZirFunction) -> FlatProg { @@ -2793,8 +2794,8 @@ mod tests { ), ZirStatement::Assertion( BooleanExpression::BoolEq( - box BooleanExpression::Identifier("x".into()), - box BooleanExpression::Identifier("y".into()), + box BooleanExpression::identifier("x".into()), + box BooleanExpression::identifier("y".into()), ), zir::RuntimeError::mock(), ), @@ -2861,10 +2862,10 @@ mod tests { ZirStatement::Assertion( BooleanExpression::FieldEq( box FieldElementExpression::Add( - box FieldElementExpression::Identifier("x".into()), + box FieldElementExpression::identifier("x".into()), box FieldElementExpression::Number(Bn128Field::from(1)), ), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("y".into()), ), zir::RuntimeError::mock(), ), @@ -2936,7 +2937,7 @@ mod tests { ), ZirStatement::Assertion( BooleanExpression::UintEq( - box UExpressionInner::Identifier("x".into()) + box UExpression::identifier("x".into()) .annotate(32) .metadata(metadata.clone()), box UExpressionInner::Value(42).annotate(32).metadata(metadata), @@ -3002,8 +3003,8 @@ mod tests { ), ZirStatement::Assertion( BooleanExpression::FieldEq( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), zir::RuntimeError::mock(), ), @@ -3077,10 +3078,10 @@ mod tests { ZirStatement::Assertion( BooleanExpression::FieldEq( box FieldElementExpression::Mult( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), - box FieldElementExpression::Identifier("z".into()), + box FieldElementExpression::identifier("z".into()), ), zir::RuntimeError::mock(), ), @@ -3157,10 +3158,10 @@ mod tests { ), ZirStatement::Assertion( BooleanExpression::FieldEq( - box FieldElementExpression::Identifier("z".into()), + box FieldElementExpression::identifier("z".into()), box FieldElementExpression::Mult( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), ), zir::RuntimeError::mock(), @@ -3246,12 +3247,12 @@ mod tests { ZirStatement::Assertion( BooleanExpression::FieldEq( box FieldElementExpression::Mult( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), box FieldElementExpression::Mult( - box FieldElementExpression::Identifier("z".into()), - box FieldElementExpression::Identifier("t".into()), + box FieldElementExpression::identifier("z".into()), + box FieldElementExpression::identifier("t".into()), ), ), zir::RuntimeError::mock(), @@ -3329,12 +3330,12 @@ mod tests { ZirStatement::Definition( zir::Variable::field_element("b"), FieldElementExpression::Pow( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box 0u32.into(), ) .into(), ), - ZirStatement::Return(vec![FieldElementExpression::Identifier("b".into()).into()]), + ZirStatement::Return(vec![FieldElementExpression::identifier("b".into()).into()]), ], signature: Signature { inputs: vec![], @@ -3390,12 +3391,12 @@ mod tests { ZirStatement::Definition( zir::Variable::field_element("b"), FieldElementExpression::Pow( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box 1u32.into(), ) .into(), ), - ZirStatement::Return(vec![FieldElementExpression::Identifier("b".into()).into()]), + ZirStatement::Return(vec![FieldElementExpression::identifier("b".into()).into()]), ], signature: Signature { inputs: vec![], @@ -3471,12 +3472,12 @@ mod tests { ZirStatement::Definition( zir::Variable::field_element("b"), FieldElementExpression::Pow( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box 13u32.into(), ) .into(), ), - ZirStatement::Return(vec![FieldElementExpression::Identifier("b".into()).into()]), + ZirStatement::Return(vec![FieldElementExpression::identifier("b".into()).into()]), ], signature: Signature { inputs: vec![], @@ -3614,9 +3615,9 @@ mod tests { FieldElementExpression::Div( box FieldElementExpression::Div( box FieldElementExpression::Number(Bn128Field::from(5)), - box FieldElementExpression::Identifier("b".into()), + box FieldElementExpression::identifier("b".into()), ), - box FieldElementExpression::Identifier("b".into()), + box FieldElementExpression::identifier("b".into()), ) .into(), ); diff --git a/zokrates_core/src/static_analysis/flatten_complex_types.rs b/zokrates_core/src/static_analysis/flatten_complex_types.rs index 39acb1684..b7571f9df 100644 --- a/zokrates_core/src/static_analysis/flatten_complex_types.rs +++ b/zokrates_core/src/static_analysis/flatten_complex_types.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use zokrates_ast::typed::types::{ConcreteArrayType, IntoType, UBitwidth}; use zokrates_ast::typed::{self, Expr, Typed}; -use zokrates_ast::zir::{self, Select}; +use zokrates_ast::zir::{self, Id, Select}; use zokrates_field::Field; use std::convert::{TryFrom, TryInto}; @@ -64,17 +64,15 @@ fn flatten_identifier_to_expression_rec<'ast, T: Field>( match ty { typed::ConcreteType::Int => unreachable!(), typed::ConcreteType::FieldElement => { - vec![zir::FieldElementExpression::Identifier(zir::Identifier::Source(id)).into()] + vec![zir::FieldElementExpression::identifier(zir::Identifier::Source(id)).into()] } typed::ConcreteType::Boolean => { - vec![zir::BooleanExpression::Identifier(zir::Identifier::Source(id)).into()] + vec![zir::BooleanExpression::identifier(zir::Identifier::Source(id)).into()] } typed::ConcreteType::Uint(bitwidth) => { - vec![ - zir::UExpressionInner::Identifier(zir::Identifier::Source(id)) - .annotate(bitwidth.to_usize()) - .into(), - ] + vec![zir::UExpression::identifier(zir::Identifier::Source(id)) + .annotate(bitwidth.to_usize()) + .into()] } typed::ConcreteType::Array(array_type) => (0..*array_type.size) .flat_map(|i| { diff --git a/zokrates_core/src/static_analysis/uint_optimizer.rs b/zokrates_core/src/static_analysis/uint_optimizer.rs index fbafe1748..ac96dbfe1 100644 --- a/zokrates_core/src/static_analysis/uint_optimizer.rs +++ b/zokrates_core/src/static_analysis/uint_optimizer.rs @@ -123,7 +123,7 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> { Value(v) => Value(v).annotate(range).with_max(v), Identifier(id) => Identifier(id.clone()).annotate(range).metadata( self.ids - .get(&Variable::uint(id.clone(), range)) + .get(&Variable::uint(id.id.clone(), range)) .cloned() .unwrap_or_else(|| panic!("identifier should have been defined: {}", id)), ), @@ -594,7 +594,7 @@ mod tests { } fn e_with_max<'a, U: Into>(max: U) -> UExpression<'a, Bn128Field> { - UExpressionInner::Identifier("foo".into()) + UExpression::identifier("foo".into()) .annotate(32) .metadata(UMetadata::with_max(max)) } @@ -766,11 +766,11 @@ mod tests { #[test] fn if_else() { // `left` and `right` are smaller than the target - let consequence: UExpression = UExpressionInner::Identifier("a".into()) + let consequence: UExpression = UExpression::identifier("a".into()) .annotate(32) .metadata(UMetadata::with_max(42u32)); - let alternative = UExpressionInner::Identifier("b".into()) + let alternative = UExpression::identifier("b".into()) .annotate(32) .metadata(UMetadata::with_max(33u32)); diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index 72bbdf1f5..d628467a3 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use std::fmt; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ - result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, - SelectExpression, SelectOrExpression, + result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, Id, + IdentifierExpression, IdentifierOrExpression, SelectExpression, SelectOrExpression, }; use zokrates_ast::zir::{ BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression, @@ -126,18 +126,28 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { } } + fn fold_identifier_expression + Id<'ast, T> + ResultFold<'ast, T>>( + &mut self, + _: &E::Ty, + id: IdentifierExpression<'ast, E>, + ) -> Result, Self::Error> { + match self.constants.get(&id.id).cloned() { + Some(e) => Ok(IdentifierOrExpression::Expression( + E::try_from(e) + .map_err(|_| "downcast failed") + .unwrap() + .into_inner(), + )), + None => Ok(IdentifierOrExpression::Identifier(id)), + } + } + fn fold_field_expression( &mut self, e: FieldElementExpression<'ast, T>, ) -> Result, Self::Error> { match e { FieldElementExpression::Number(n) => Ok(FieldElementExpression::Number(n)), - FieldElementExpression::Identifier(id) => match self.constants.get(&id) { - Some(ZirExpression::FieldElement(FieldElementExpression::Number(v))) => { - Ok(FieldElementExpression::Number(v.clone())) - } - _ => Ok(FieldElementExpression::Identifier(id)), - }, FieldElementExpression::Add(box e1, box e2) => { match ( self.fold_field_expression(e1)?, @@ -231,12 +241,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { ) -> Result, Error> { match e { BooleanExpression::Value(v) => Ok(BooleanExpression::Value(v)), - BooleanExpression::Identifier(id) => match self.constants.get(&id) { - Some(ZirExpression::Boolean(BooleanExpression::Value(v))) => { - Ok(BooleanExpression::Value(*v)) - } - _ => Ok(BooleanExpression::Identifier(id)), - }, BooleanExpression::FieldLt(box e1, box e2) => { match ( self.fold_field_expression(e1)?, @@ -410,10 +414,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { ) -> Result, Self::Error> { match e { UExpressionInner::Value(v) => Ok(UExpressionInner::Value(v)), - UExpressionInner::Identifier(id) => match self.constants.get(&id) { - Some(ZirExpression::Uint(e)) => Ok(e.as_inner().clone()), - _ => Ok(UExpressionInner::Identifier(id)), - }, UExpressionInner::Add(box e1, box e2) => { let e1 = self.fold_uint_expression(e1)?; let e2 = self.fold_uint_expression(e2)?; @@ -615,7 +615,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { #[cfg(test)] mod tests { use super::*; - use zokrates_ast::zir::RuntimeError; + use zokrates_ast::zir::{Id, RuntimeError}; use zokrates_field::Bn128Field; #[test] @@ -624,8 +624,8 @@ mod tests { let statements = vec![ZirStatement::Assertion( BooleanExpression::And( box BooleanExpression::FieldEq( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), box BooleanExpression::FieldEq( box FieldElementExpression::Number(Bn128Field::from(1)), @@ -649,8 +649,8 @@ mod tests { statements, vec![ZirStatement::Assertion( BooleanExpression::FieldEq( - box FieldElementExpression::Identifier("x".into()), - box FieldElementExpression::Identifier("y".into()), + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::identifier("y".into()), ), RuntimeError::mock() )] @@ -706,10 +706,10 @@ mod tests { // a + 0 = a assert_eq!( propagator.fold_field_expression(FieldElementExpression::Add( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(0)), )), - Ok(FieldElementExpression::Identifier("a".into())) + Ok(FieldElementExpression::identifier("a".into())) ); } @@ -728,10 +728,10 @@ mod tests { // a - 0 = a assert_eq!( propagator.fold_field_expression(FieldElementExpression::Sub( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(0)), )), - Ok(FieldElementExpression::Identifier("a".into())) + Ok(FieldElementExpression::identifier("a".into())) ); } @@ -750,7 +750,7 @@ mod tests { // a * 0 = 0 assert_eq!( propagator.fold_field_expression(FieldElementExpression::Mult( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(0)), )), Ok(FieldElementExpression::Number(Bn128Field::from(0))) @@ -759,10 +759,10 @@ mod tests { // a * 1 = a assert_eq!( propagator.fold_field_expression(FieldElementExpression::Mult( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(1)), )), - Ok(FieldElementExpression::Identifier("a".into())) + Ok(FieldElementExpression::identifier("a".into())) ); } @@ -780,15 +780,15 @@ mod tests { assert_eq!( propagator.fold_field_expression(FieldElementExpression::Div( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(1)), )), - Ok(FieldElementExpression::Identifier("a".into())) + Ok(FieldElementExpression::identifier("a".into())) ); assert_eq!( propagator.fold_field_expression(FieldElementExpression::Div( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(0)), )), Err(Error::DivisionByZero) @@ -810,7 +810,7 @@ mod tests { // a ** 0 = 1 assert_eq!( propagator.fold_field_expression(FieldElementExpression::Pow( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box UExpressionInner::Value(0).annotate(UBitwidth::B32), )), Ok(FieldElementExpression::Number(Bn128Field::from(1))) @@ -819,10 +819,10 @@ mod tests { // a ** 1 = a assert_eq!( propagator.fold_field_expression(FieldElementExpression::Pow( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box UExpressionInner::Value(1).annotate(UBitwidth::B32), )), - Ok(FieldElementExpression::Identifier("a".into())) + Ok(FieldElementExpression::identifier("a".into())) ); } @@ -850,7 +850,7 @@ mod tests { assert_eq!( propagator.fold_field_expression(FieldElementExpression::conditional( - BooleanExpression::Identifier("a".into()), + BooleanExpression::identifier("a".into()), FieldElementExpression::Number(Bn128Field::from(2)), FieldElementExpression::Number(Bn128Field::from(2)), )), @@ -915,7 +915,7 @@ mod tests { assert_eq!( propagator.fold_boolean_expression(BooleanExpression::FieldLt( - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), box FieldElementExpression::Number(Bn128Field::from(0)), )), Ok(BooleanExpression::Value(false)) @@ -924,7 +924,7 @@ mod tests { assert_eq!( propagator.fold_boolean_expression(BooleanExpression::FieldLt( box FieldElementExpression::Number(Bn128Field::max_value()), - box FieldElementExpression::Identifier("a".into()), + box FieldElementExpression::identifier("a".into()), )), Ok(BooleanExpression::Value(false)) ); @@ -1078,15 +1078,15 @@ mod tests { assert_eq!( propagator.fold_boolean_expression(BooleanExpression::And( - box BooleanExpression::Identifier("a".into()), + box BooleanExpression::identifier("a".into()), box BooleanExpression::Value(true), )), - Ok(BooleanExpression::Identifier("a".into())) + Ok(BooleanExpression::identifier("a".into())) ); assert_eq!( propagator.fold_boolean_expression(BooleanExpression::And( - box BooleanExpression::Identifier("a".into()), + box BooleanExpression::identifier("a".into()), box BooleanExpression::Value(false), )), Ok(BooleanExpression::Value(false)) @@ -1157,7 +1157,7 @@ mod tests { assert_eq!( propagator.fold_boolean_expression(BooleanExpression::conditional( - BooleanExpression::Identifier("a".into()), + BooleanExpression::identifier("a".into()), BooleanExpression::Value(true), BooleanExpression::Value(true) )), @@ -1227,11 +1227,11 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Add( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); } @@ -1255,11 +1255,11 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Sub( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); } @@ -1283,11 +1283,11 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Mult( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(1).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); // a * 0 = 0 @@ -1295,7 +1295,7 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Mult( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), @@ -1322,18 +1322,18 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Div( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(1).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); assert_eq!( propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Div( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), @@ -1387,8 +1387,8 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Xor( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), ) ), Ok(UExpressionInner::Value(0)) @@ -1414,7 +1414,7 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::And( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), @@ -1425,11 +1425,11 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::And( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(u32::MAX as u128).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); } @@ -1452,18 +1452,18 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Or( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(0).annotate(UBitwidth::B32), ) ), - Ok(UExpressionInner::Identifier("a".into())) + Ok(UExpression::identifier("a".into())) ); assert_eq!( propagator.fold_uint_expression_inner( UBitwidth::B32, UExpressionInner::Or( - box UExpressionInner::Identifier("a".into()).annotate(UBitwidth::B32), + box UExpression::identifier("a".into()).annotate(UBitwidth::B32), box UExpressionInner::Value(u32::MAX as u128).annotate(UBitwidth::B32), ) ), @@ -1594,7 +1594,7 @@ mod tests { propagator.fold_uint_expression_inner( UBitwidth::B32, UExpression::conditional( - BooleanExpression::Identifier("a".into()), + BooleanExpression::identifier("a".into()), UExpressionInner::Value(2).annotate(UBitwidth::B32), UExpressionInner::Value(2).annotate(UBitwidth::B32), ) From b3a27bed381425b826b57c5bf6eaabfcef058090 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 8 Nov 2022 19:32:55 +0100 Subject: [PATCH 21/94] implement from instead of try_from on zir expression --- zokrates_ast/src/zir/mod.rs | 43 ++++++++----------- zokrates_core/src/flatten/mod.rs | 5 +-- .../src/static_analysis/zir_propagation.rs | 7 +-- 3 files changed, 19 insertions(+), 36 deletions(-) diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index ee886ef39..d8f325936 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -15,7 +15,6 @@ use crate::typed::ConcreteType; pub use crate::zir::uint::{ShouldReduce, UExpression, UExpressionInner, UMetadata}; use crate::zir::types::Signature; -use std::convert::TryFrom; use std::fmt; use std::marker::PhantomData; use zokrates_field::Field; @@ -464,37 +463,29 @@ impl<'ast, T> BooleanExpression<'ast, T> { } // Downcasts -impl<'ast, T> TryFrom> for FieldElementExpression<'ast, T> { - type Error = (); - - fn try_from( - te: ZirExpression<'ast, T>, - ) -> Result, Self::Error> { - match te { - ZirExpression::FieldElement(e) => Ok(e), - _ => Err(()), +impl<'ast, T> From> for FieldElementExpression<'ast, T> { + fn from(e: ZirExpression<'ast, T>) -> FieldElementExpression<'ast, T> { + match e { + ZirExpression::FieldElement(e) => e, + _ => unreachable!("downcast failed"), } } } -impl<'ast, T> TryFrom> for BooleanExpression<'ast, T> { - type Error = (); - - fn try_from(te: ZirExpression<'ast, T>) -> Result, Self::Error> { - match te { - ZirExpression::Boolean(e) => Ok(e), - _ => Err(()), +impl<'ast, T> From> for BooleanExpression<'ast, T> { + fn from(e: ZirExpression<'ast, T>) -> BooleanExpression<'ast, T> { + match e { + ZirExpression::Boolean(e) => e, + _ => unreachable!("downcast failed"), } } } -impl<'ast, T> TryFrom> for UExpression<'ast, T> { - type Error = (); - - fn try_from(te: ZirExpression<'ast, T>) -> Result, Self::Error> { - match te { - ZirExpression::Uint(e) => Ok(e), - _ => Err(()), +impl<'ast, T> From> for UExpression<'ast, T> { + fn from(e: ZirExpression<'ast, T>) -> UExpression<'ast, T> { + match e { + ZirExpression::Uint(e) => e, + _ => unreachable!("downcast failed"), } } } @@ -609,8 +600,8 @@ impl<'ast, T: fmt::Debug> fmt::Debug for ZirExpressionList<'ast, T> { } } -// Common behaviour accross expressions -pub trait Expr<'ast, T>: fmt::Display + PartialEq + TryFrom> { +// Common behaviour across expressions +pub trait Expr<'ast, T>: fmt::Display + PartialEq + From> { type Inner; type Ty: Clone + IntoType; diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 6352af7e2..2e3e95b8b 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -18,7 +18,6 @@ use std::collections::{ hash_map::{Entry, HashMap}, VecDeque, }; -use std::convert::TryFrom; use zokrates_ast::common::embed::*; use zokrates_ast::common::FlatEmbed; use zokrates_ast::common::{RuntimeError, Variable}; @@ -119,9 +118,7 @@ impl FlattenOutput for FlatUExpression { // We introduce a trait in order to make it possible to make flattening `e` generic over the type of `e` -trait Flatten<'ast, T: Field>: - TryFrom, Error = ()> + Conditional<'ast, T> -{ +trait Flatten<'ast, T: Field>: From> + Conditional<'ast, T> { type Output: FlattenOutput; fn flatten( diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index d628467a3..403555584 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -132,12 +132,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { id: IdentifierExpression<'ast, E>, ) -> Result, Self::Error> { match self.constants.get(&id.id).cloned() { - Some(e) => Ok(IdentifierOrExpression::Expression( - E::try_from(e) - .map_err(|_| "downcast failed") - .unwrap() - .into_inner(), - )), + Some(e) => Ok(IdentifierOrExpression::Expression(E::from(e).into_inner())), None => Ok(IdentifierOrExpression::Identifier(id)), } } From bccb08c836f8f61a083ae5101d8b88a8ab9525d1 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 9 Nov 2022 18:57:30 +0100 Subject: [PATCH 22/94] wip --- zokrates_analysis/src/assembly_transformer.rs | 117 ++++++++++++++++ zokrates_analysis/src/lib.rs | 14 +- zokrates_analysis/src/zir_validator.rs | 54 ------- zokrates_ast/src/typed/mod.rs | 48 +++---- zokrates_ast/src/zir/lqc.rs | 132 ++++++++++++++++++ zokrates_ast/src/zir/mod.rs | 1 + zokrates_core/src/semantics.rs | 41 +++--- .../tests/tests/assembly/division.json | 1 + 8 files changed, 299 insertions(+), 109 deletions(-) create mode 100644 zokrates_analysis/src/assembly_transformer.rs delete mode 100644 zokrates_analysis/src/zir_validator.rs create mode 100644 zokrates_ast/src/zir/lqc.rs diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs new file mode 100644 index 000000000..aa2f25950 --- /dev/null +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -0,0 +1,117 @@ +use std::fmt; +use zokrates_ast::zir::lqc::LinQuadComb; +use zokrates_ast::zir::result_folder::{fold_field_expression, ResultFolder}; +use zokrates_ast::zir::{FieldElementExpression, ZirAssemblyStatement, ZirProgram}; +use zokrates_field::Field; + +#[derive(Debug)] +pub struct Error(String); + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +pub struct AssemblyTransformer; + +impl AssemblyTransformer { + pub fn transform(p: ZirProgram) -> Result, Error> { + let mut f = AssemblyTransformer; + f.fold_program(p) + } +} + +impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { + type Error = Error; + + fn fold_assembly_statement( + &mut self, + s: ZirAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + match s { + ZirAssemblyStatement::Assignment(_, _) => Ok(s), + ZirAssemblyStatement::Constraint(lhs, rhs) => { + let lhs = self.fold_field_expression(lhs)?; + let rhs = self.fold_field_expression(rhs)?; + let sub = FieldElementExpression::Sub(box lhs, box rhs); + + // let sub = match (lhs, rhs) { + // (FieldElementExpression::Number(n), e) + // | (e, FieldElementExpression::Number(n)) => { + // FieldElementExpression::Sub(box FieldElementExpression::Number(n), box e) + // } + // (lhs, rhs) => FieldElementExpression::Sub(box lhs, box rhs), + // }; + + let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { + Error("Found forbidden operation in user-defined constraint".to_string()) + })?; + + println!("{:#?}", lqc); + + if lqc.quadratic.len() > 1 { + return Err(Error( + "Non-quadratic constraints are not allowed".to_string(), + )); + } + + let linear = lqc + .linear + .into_iter() + .filter_map(|(c, i)| match c { + c if c == T::from(0) => None, + c if c == T::from(1) => Some(FieldElementExpression::Identifier(i)), + _ => Some(FieldElementExpression::Mult( + box FieldElementExpression::Number(c), + box FieldElementExpression::Identifier(i), + )), + }) + .reduce(|p, n| FieldElementExpression::Add(box p, box n)) + .unwrap(); + + let lhs = match lqc.constant { + c if c == T::from(0) => linear, + c => FieldElementExpression::Add( + box FieldElementExpression::Number(c), + box linear, + ), + }; + + let rhs: FieldElementExpression<'ast, T> = lqc + .quadratic + .pop() + .map(|(c, i0, i1)| { + FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(T::zero() - c), + box FieldElementExpression::Identifier(i0), + ), + box FieldElementExpression::Identifier(i1), + ) + }) + .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))); + + println!("{} == {}", lhs, rhs); + + Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) + } + } + } + + fn fold_field_expression( + &mut self, + e: FieldElementExpression<'ast, T>, + ) -> Result, Self::Error> { + match e { + FieldElementExpression::And(_, _) + | FieldElementExpression::Or(_, _) + | FieldElementExpression::Xor(_, _) + | FieldElementExpression::LeftShift(_, _) + | FieldElementExpression::RightShift(_, _) => Err(Error( + format!("Found bitwise operation in expression `{}` of type `field` (only allowed in assembly assignment statement)", e) + )), + e => fold_field_expression(self, e), + } + } +} diff --git a/zokrates_analysis/src/lib.rs b/zokrates_analysis/src/lib.rs index 79efe9f88..552b5db8c 100644 --- a/zokrates_analysis/src/lib.rs +++ b/zokrates_analysis/src/lib.rs @@ -6,6 +6,7 @@ //! @author Thibaut Schaeffer //! @date 2018 +mod assembly_transformer; mod branch_isolator; mod condition_redefiner; mod constant_argument_checker; @@ -22,7 +23,6 @@ mod struct_concretizer; mod uint_optimizer; mod variable_write_remover; mod zir_propagation; -mod zir_validator; use self::branch_isolator::Isolator; use self::condition_redefiner::ConditionRedefiner; @@ -35,11 +35,11 @@ use self::reducer::reduce_program; use self::struct_concretizer::StructConcretizer; use self::uint_optimizer::UintOptimizer; use self::variable_write_remover::VariableWriteRemover; +use crate::assembly_transformer::AssemblyTransformer; use crate::constant_resolver::ConstantResolver; use crate::dead_code::DeadCodeEliminator; use crate::panic_extractor::PanicExtractor; pub use crate::zir_propagation::ZirPropagator; -use crate::zir_validator::ZirValidator; use std::fmt; use zokrates_ast::typed::{abi::Abi, TypedProgram}; use zokrates_ast::zir::ZirProgram; @@ -53,7 +53,7 @@ pub enum Error { ZirPropagation(self::zir_propagation::Error), NonConstantArgument(self::constant_argument_checker::Error), OutOfBounds(self::out_of_bounds::Error), - Assembly(self::zir_validator::Error), + Assembly(self::assembly_transformer::Error), } impl From for Error { @@ -86,8 +86,8 @@ impl From for Error { } } -impl From for Error { - fn from(e: zir_validator::Error) -> Self { +impl From for Error { + fn from(e: assembly_transformer::Error) -> Self { Error::Assembly(e) } } @@ -202,8 +202,8 @@ pub fn analyse<'ast, T: Field>( log::trace!("\n{}", zir); // validate zir - log::debug!("Static analyser: Validate zir"); - let zir = ZirValidator::validate(zir).map_err(Error::from)?; + log::debug!("Static analyser: Apply constraint transformations in assembly"); + let zir = AssemblyTransformer::transform(zir).map_err(Error::from)?; Ok((zir, abi)) } diff --git a/zokrates_analysis/src/zir_validator.rs b/zokrates_analysis/src/zir_validator.rs deleted file mode 100644 index ea9e61503..000000000 --- a/zokrates_analysis/src/zir_validator.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::fmt; -use zokrates_ast::zir::result_folder::{ - fold_assembly_statement, fold_field_expression, ResultFolder, -}; -use zokrates_ast::zir::{FieldElementExpression, ZirAssemblyStatement, ZirProgram}; -use zokrates_field::Field; - -#[derive(Debug)] -pub struct Error(String); - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -pub struct ZirValidator; - -impl ZirValidator { - pub fn validate(p: ZirProgram) -> Result, Error> { - let mut checker = ZirValidator; - checker.fold_program(p) - } -} - -impl<'ast, T: Field> ResultFolder<'ast, T> for ZirValidator { - type Error = Error; - - fn fold_assembly_statement( - &mut self, - s: ZirAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { - match s { - ZirAssemblyStatement::Assignment(_, _) => Ok(s), - s => fold_assembly_statement(self, s), - } - } - - fn fold_field_expression( - &mut self, - e: FieldElementExpression<'ast, T>, - ) -> Result, Self::Error> { - match e { - FieldElementExpression::And(_, _) - | FieldElementExpression::Or(_, _) - | FieldElementExpression::Xor(_, _) - | FieldElementExpression::LeftShift(_, _) - | FieldElementExpression::RightShift(_, _) => Err(Error( - format!("Found bitwise operation in expression `{}` of type `field` (only allowed in assembly assignment statement)", e) - )), - e => fold_field_expression(self, e), - } - } -} diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 47eb190f6..fbde38138 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1334,44 +1334,28 @@ impl<'ast, T> FieldElementExpression<'ast, T> { pub fn pow(self, other: UExpression<'ast, T>) -> Self { FieldElementExpression::Pow(box self, box other) } - pub fn is_quadratic(&self) -> bool { - match self { - FieldElementExpression::Mult(box left, box right) => { - left.is_linear() && right.is_linear() - } - _ => false, - } - } - fn is_linear(&self) -> bool { + // This is used for early detection in semantics but it is not completely accurate + // Deeper analysis is done in a separate step after semantic checks + pub fn is_non_quadratic(&self) -> bool { match self { - FieldElementExpression::Block(_) => false, - FieldElementExpression::Number(_) => true, - FieldElementExpression::Identifier(_) => true, + FieldElementExpression::Number(_) => false, + FieldElementExpression::Identifier(_) => false, FieldElementExpression::Add(box left, box right) => { - left.is_linear() && right.is_linear() + left.is_non_quadratic() || right.is_non_quadratic() } FieldElementExpression::Sub(box left, box right) => { - left.is_linear() && right.is_linear() + left.is_non_quadratic() || right.is_non_quadratic() } - FieldElementExpression::Mult(box left, box right) => matches!( - (left, right), - (FieldElementExpression::Number(_), _) | (_, FieldElementExpression::Number(_)) - ), - FieldElementExpression::Div(_, _) => false, - FieldElementExpression::Pow(_, _) => false, - FieldElementExpression::And(_, _) => false, - FieldElementExpression::Or(_, _) => false, - FieldElementExpression::Xor(_, _) => false, - FieldElementExpression::LeftShift(_, _) => false, - FieldElementExpression::RightShift(_, _) => false, - FieldElementExpression::Conditional(_) => false, - FieldElementExpression::Neg(_) => true, - FieldElementExpression::Pos(_) => true, - FieldElementExpression::FunctionCall(_) => false, - FieldElementExpression::Member(_) => true, - FieldElementExpression::Select(_) => true, - FieldElementExpression::Element(_) => true, + FieldElementExpression::Mult(box left, box right) => { + left.is_non_quadratic() || right.is_non_quadratic() + } + FieldElementExpression::Neg(_) => false, + FieldElementExpression::Pos(_) => false, + FieldElementExpression::Member(_) => false, + FieldElementExpression::Select(_) => false, + FieldElementExpression::Element(_) => false, + _ => true, } } } diff --git a/zokrates_ast/src/zir/lqc.rs b/zokrates_ast/src/zir/lqc.rs new file mode 100644 index 000000000..54f165486 --- /dev/null +++ b/zokrates_ast/src/zir/lqc.rs @@ -0,0 +1,132 @@ +use crate::zir::{FieldElementExpression, Identifier}; +use zokrates_field::Field; + +#[derive(Clone, PartialEq, Hash, Eq, Debug, Default)] +pub struct LinQuadComb<'ast, T> { + // the constant terms + pub constant: T, + // the linear terms + pub linear: Vec<(T, Identifier<'ast>)>, + // the quadratic terms + pub quadratic: Vec<(T, Identifier<'ast>, Identifier<'ast>)>, +} + +impl<'ast, T: Field> std::ops::Add for LinQuadComb<'ast, T> { + type Output = Self; + + fn add(self, mut other: Self) -> Self::Output { + Self { + constant: self.constant + other.constant, + linear: { + let mut l = self.linear; + l.append(&mut other.linear); + l + }, + quadratic: { + let mut q = self.quadratic; + q.append(&mut other.quadratic); + q + }, + } + } +} + +impl<'ast, T: Field> std::ops::Sub for LinQuadComb<'ast, T> { + type Output = Self; + + fn sub(self, mut other: Self) -> Self::Output { + Self { + constant: self.constant - other.constant, + linear: { + let mut l = self.linear; + other.linear.iter_mut().for_each(|(c, _)| { + *c = T::zero() - &*c; + }); + l.append(&mut other.linear); + l + }, + quadratic: { + let mut q = self.quadratic; + other.quadratic.iter_mut().for_each(|(c, _, _)| { + *c = T::zero() - &*c; + }); + q.append(&mut other.quadratic); + q + }, + } + } +} + +impl<'ast, T: Field> LinQuadComb<'ast, T> { + fn try_mul(self, rhs: Self) -> Result { + // fail if the result has degree higher than 2 + if !(self.quadratic.is_empty() || rhs.quadratic.is_empty()) { + return Err(()); + } + + Ok(Self { + constant: self.constant.clone() * rhs.constant.clone(), + linear: { + // lin0 * const1 + lin1 * const0 + self.linear + .clone() + .into_iter() + .map(|(c, i)| (c * rhs.constant.clone(), i)) + .chain( + rhs.linear + .clone() + .into_iter() + .map(|(c, i)| (c * self.constant.clone(), i)), + ) + .collect() + }, + quadratic: { + // quad0 * const1 + quad1 * const0 + lin0 * lin1 + self.quadratic + .into_iter() + .map(|(c, i0, i1)| (c * rhs.constant.clone(), i0, i1)) + .chain( + rhs.quadratic + .into_iter() + .map(|(c, i0, i1)| (c * self.constant.clone(), i0, i1)), + ) + .chain(self.linear.iter().flat_map(|(cl, l)| { + rhs.linear + .iter() + .map(|(cr, r)| (cl.clone() * cr.clone(), l.clone(), r.clone())) + })) + .collect() + }, + }) + } +} + +impl<'ast, T: Field> TryFrom> for LinQuadComb<'ast, T> { + type Error = (); + + fn try_from(e: FieldElementExpression<'ast, T>) -> Result { + match e { + FieldElementExpression::Number(v) => Ok(Self { + constant: v, + ..Self::default() + }), + FieldElementExpression::Identifier(id) => Ok(Self { + linear: vec![(T::one(), id)], + ..Self::default() + }), + FieldElementExpression::Add(box left, box right) => { + Ok(Self::try_from(left)? + Self::try_from(right)?) + } + FieldElementExpression::Sub(box left, box right) => { + Ok(Self::try_from(left)? - Self::try_from(right)?) + } + FieldElementExpression::Mult(box left, box right) => { + let left = Self::try_from(left)?; + let right = Self::try_from(right)?; + + left.try_mul(right) + } + _ => Err(()), + } + } +} diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index 6f3bb81fc..284083462 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -1,6 +1,7 @@ pub mod folder; mod from_typed; mod identifier; +pub mod lqc; mod parameter; pub mod result_folder; pub mod types; diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index d70c71dda..d66ffb7b0 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1801,6 +1801,13 @@ impl<'ast, T: Field> Checker<'ast, T> { match constrained { true => { + // early non-quadratic detection + if e.is_non_quadratic() { + return Err(ErrorInner { + pos: Some(pos), + message: "Non-quadratic constraints are not allowed".to_string(), + }); + } let e = FieldElementExpression::block(vec![], e); match assignee.get_type() { Type::FieldElement => Ok(vec![ @@ -1822,34 +1829,36 @@ impl<'ast, T: Field> Checker<'ast, T> { AssemblyStatement::Constraint(lhs, rhs) => { let lhs = self.check_expression(lhs, module_id, types)?; let rhs = self.check_expression(rhs, module_id, types)?; - match (lhs, rhs) { + + let (lhs, rhs) = match (lhs, rhs) { (TypedExpression::FieldElement(lhs), TypedExpression::FieldElement(rhs)) => { - Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)]) + Ok((lhs, rhs)) } (TypedExpression::FieldElement(lhs), TypedExpression::Int(rhs)) => { - Ok(vec![TypedAssemblyStatement::Constraint( - lhs, - FieldElementExpression::try_from_int(rhs).unwrap(), - )]) + Ok((lhs, FieldElementExpression::try_from_int(rhs).unwrap())) } (TypedExpression::Int(lhs), TypedExpression::FieldElement(rhs)) => { - Ok(vec![TypedAssemblyStatement::Constraint( - FieldElementExpression::try_from_int(lhs).unwrap(), - rhs, - )]) - } - (TypedExpression::Int(lhs), TypedExpression::Int(rhs)) => { - Ok(vec![TypedAssemblyStatement::Constraint( - FieldElementExpression::try_from_int(lhs).unwrap(), - FieldElementExpression::try_from_int(rhs).unwrap(), - )]) + Ok((FieldElementExpression::try_from_int(lhs).unwrap(), rhs)) } + (TypedExpression::Int(lhs), TypedExpression::Int(rhs)) => Ok(( + FieldElementExpression::try_from_int(lhs).unwrap(), + FieldElementExpression::try_from_int(rhs).unwrap(), + )), _ => Err(ErrorInner { pos: Some(pos), message: "Only field element expressions are allowed in the assembly block" .to_string(), }), + }?; + + if lhs.is_non_quadratic() || rhs.is_non_quadratic() { + return Err(ErrorInner { + pos: Some(pos), + message: "Non-quadratic constraints are not allowed".to_string(), + }); } + + Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)]) } } } diff --git a/zokrates_core_test/tests/tests/assembly/division.json b/zokrates_core_test/tests/tests/assembly/division.json index f0da6cc0d..7478326fd 100644 --- a/zokrates_core_test/tests/tests/assembly/division.json +++ b/zokrates_core_test/tests/tests/assembly/division.json @@ -1,5 +1,6 @@ { "curves": ["Bn128"], + "max_constraint_count": 2, "tests": [ { "input": { From fd3ff7054b45d37c85de2e3b9348e9c038ebca05 Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 10 Nov 2022 17:54:11 +0100 Subject: [PATCH 23/94] fix asm flattening --- zokrates_analysis/src/assembly_transformer.rs | 12 ------------ zokrates_codegen/src/lib.rs | 6 ++---- .../tests/tests/assembly/binary_check.json | 1 + .../tests/tests/assembly/xor_gate.json | 1 + 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index aa2f25950..21259f265 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -36,20 +36,10 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { let rhs = self.fold_field_expression(rhs)?; let sub = FieldElementExpression::Sub(box lhs, box rhs); - // let sub = match (lhs, rhs) { - // (FieldElementExpression::Number(n), e) - // | (e, FieldElementExpression::Number(n)) => { - // FieldElementExpression::Sub(box FieldElementExpression::Number(n), box e) - // } - // (lhs, rhs) => FieldElementExpression::Sub(box lhs, box rhs), - // }; - let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { Error("Found forbidden operation in user-defined constraint".to_string()) })?; - println!("{:#?}", lqc); - if lqc.quadratic.len() > 1 { return Err(Error( "Non-quadratic constraints are not allowed".to_string(), @@ -92,8 +82,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { }) .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))); - println!("{} == {}", lhs, rhs); - Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) } } diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index a93e68b10..ba99e6f7b 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -2254,13 +2254,11 @@ impl<'ast, T: Field> Flattener<'ast, T> { ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = self.flatten_field_expression(statements_flattened, lhs); let rhs = self.flatten_field_expression(statements_flattened, rhs); - - self.flatten_equality_assertion( - statements_flattened, + statements_flattened.push_back(FlatStatement::Condition( lhs, rhs, RuntimeError::UserConstraint, - ) + )); } } } diff --git a/zokrates_core_test/tests/tests/assembly/binary_check.json b/zokrates_core_test/tests/tests/assembly/binary_check.json index 05148b36c..53912338b 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_check.json +++ b/zokrates_core_test/tests/tests/assembly/binary_check.json @@ -1,5 +1,6 @@ { "curves": ["Bn128"], + "max_constraint_count": 1, "tests": [ { "input": { diff --git a/zokrates_core_test/tests/tests/assembly/xor_gate.json b/zokrates_core_test/tests/tests/assembly/xor_gate.json index 099f89b7d..14908d6a0 100644 --- a/zokrates_core_test/tests/tests/assembly/xor_gate.json +++ b/zokrates_core_test/tests/tests/assembly/xor_gate.json @@ -1,5 +1,6 @@ { "curves": ["Bn128"], + "max_constraint_count": 2, "tests": [ { "input": { From bc9f103fdfd98071f08b8b08d64e8f3ef338603c Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 16 Nov 2022 21:27:36 +0100 Subject: [PATCH 24/94] add more asm tests --- zokrates_analysis/src/assembly_transformer.rs | 159 +++++++++++++----- .../src/constant_argument_checker.rs | 13 ++ zokrates_analysis/src/propagation.rs | 13 +- zokrates_analysis/src/reducer/shallow_ssa.rs | 19 +++ zokrates_ast/src/typed/mod.rs | 24 --- zokrates_ast/src/zir/mod.rs | 20 +++ zokrates_core/src/semantics.rs | 14 -- .../tests/tests/assembly/binary_sub.json | 46 +++++ .../tests/tests/assembly/binary_sub.zok | 34 ++++ .../{xor_gate.json => gates/xor.json} | 0 .../assembly/{xor_gate.zok => gates/xor.zok} | 3 +- .../tests/tests/assembly/is_zero.json | 26 +++ .../tests/tests/assembly/is_zero.zok | 10 ++ .../tests/tests/assembly/sha256_maj.json | 5 + .../tests/tests/assembly/sha256_maj.zok | 9 + 15 files changed, 302 insertions(+), 93 deletions(-) create mode 100644 zokrates_core_test/tests/tests/assembly/binary_sub.json create mode 100644 zokrates_core_test/tests/tests/assembly/binary_sub.zok rename zokrates_core_test/tests/tests/assembly/{xor_gate.json => gates/xor.json} (100%) rename zokrates_core_test/tests/tests/assembly/{xor_gate.zok => gates/xor.zok} (60%) create mode 100644 zokrates_core_test/tests/tests/assembly/is_zero.json create mode 100644 zokrates_core_test/tests/tests/assembly/is_zero.zok create mode 100644 zokrates_core_test/tests/tests/assembly/sha256_maj.json create mode 100644 zokrates_core_test/tests/tests/assembly/sha256_maj.zok diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index 21259f265..356d9084c 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -1,7 +1,7 @@ use std::fmt; use zokrates_ast::zir::lqc::LinQuadComb; use zokrates_ast::zir::result_folder::{fold_field_expression, ResultFolder}; -use zokrates_ast::zir::{FieldElementExpression, ZirAssemblyStatement, ZirProgram}; +use zokrates_ast::zir::{FieldElementExpression, Identifier, ZirAssemblyStatement, ZirProgram}; use zokrates_field::Field; #[derive(Debug)] @@ -34,55 +34,126 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = self.fold_field_expression(lhs)?; let rhs = self.fold_field_expression(rhs)?; - let sub = FieldElementExpression::Sub(box lhs, box rhs); - let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { - Error("Found forbidden operation in user-defined constraint".to_string()) - })?; + // println!("o: {} == {}", lhs, rhs); - if lqc.quadratic.len() > 1 { - return Err(Error( - "Non-quadratic constraints are not allowed".to_string(), - )); - } - - let linear = lqc - .linear - .into_iter() - .filter_map(|(c, i)| match c { - c if c == T::from(0) => None, - c if c == T::from(1) => Some(FieldElementExpression::Identifier(i)), - _ => Some(FieldElementExpression::Mult( - box FieldElementExpression::Number(c), - box FieldElementExpression::Identifier(i), - )), - }) - .reduce(|p, n| FieldElementExpression::Add(box p, box n)) - .unwrap(); - - let lhs = match lqc.constant { - c if c == T::from(0) => linear, - c => FieldElementExpression::Add( - box FieldElementExpression::Number(c), - box linear, - ), + let (is_quadratic, lhs, rhs) = match (lhs, rhs) { + (FieldElementExpression::Mult(x, y), other) + | (other, FieldElementExpression::Mult(x, y)) + if other.is_linear() => + { + ( + x.is_linear() && y.is_linear(), + other, + FieldElementExpression::Mult(x, y), + ) + } + (lhs, rhs) => (false, lhs, rhs), }; - let rhs: FieldElementExpression<'ast, T> = lqc - .quadratic - .pop() - .map(|(c, i0, i1)| { - FieldElementExpression::Mult( - box FieldElementExpression::Mult( - box FieldElementExpression::Number(T::zero() - c), - box FieldElementExpression::Identifier(i0), + match is_quadratic { + true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs)), + false => { + let sub = FieldElementExpression::Sub(box lhs.clone(), box rhs.clone()); + let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { + Error( + "Found forbidden operation in user-defined constraint".to_string(), + ) + })?; + + let linear = lqc + .linear + .into_iter() + .filter_map(|(c, i)| match c { + c if c == T::from(0) => None, + c if c == T::from(1) => Some(FieldElementExpression::Identifier(i)), + _ => Some(FieldElementExpression::Mult( + box FieldElementExpression::Number(c), + box FieldElementExpression::Identifier(i), + )), + }) + .reduce(|p, n| FieldElementExpression::Add(box p, box n)) + .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))); + + let lhs = match lqc.constant { + c if c == T::from(0) => linear, + c => FieldElementExpression::Add( + box FieldElementExpression::Number(c), + box linear, ), - box FieldElementExpression::Identifier(i1), - ) - }) - .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))); + }; - Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) + let rhs: FieldElementExpression<'ast, T> = if lqc.quadratic.len() > 1 { + let is_common_factor = |id: &Identifier<'ast>, + q: &Vec<( + T, + Identifier<'ast>, + Identifier<'ast>, + )>| { + q.iter().all(|(_, i0, i1)| i0.eq(id) || i1.eq(id)) + }; + + let common_factor: Option> = + lqc.quadratic.iter().find_map(|(_, i0, i1)| { + if is_common_factor(i0, &lqc.quadratic) { + Some(i0.clone()) + } else if is_common_factor(i1, &lqc.quadratic) { + Some(i1.clone()) + } else { + None + } + }); + + match common_factor { + Some(id) => Ok(FieldElementExpression::Mult( + box lqc + .quadratic + .into_iter() + .filter_map(|(c, i0, i1)| { + let c = T::zero() - c; + let id = if id.eq(&i0) { i1 } else { i0 }; + match c { + c if c == T::from(0) => None, + c if c == T::from(1) => { + Some(FieldElementExpression::Identifier(id)) + } + _ => Some(FieldElementExpression::Mult( + box FieldElementExpression::Number(c), + box FieldElementExpression::Identifier(id), + )), + } + }) + .reduce(|p, n| FieldElementExpression::Add(box p, box n)) + .unwrap_or_else(|| { + FieldElementExpression::Number(T::from(0)) + }), + box FieldElementExpression::Identifier(id), + )), + _ => Err(Error(format!( + "Non-quadratic constraints are not allowed `{} == {}`", + lhs, rhs + ))), + }? + } else { + lqc.quadratic + .pop() + .map(|(c, i0, i1)| { + FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(T::zero() - c), + box FieldElementExpression::Identifier(i0), + ), + box FieldElementExpression::Identifier(i1), + ) + }) + .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))) + }; + + // println!("t: {} == {}", lhs, rhs); + + Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) + } + } } } } diff --git a/zokrates_analysis/src/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs index 7f3a1ce36..db77c5a35 100644 --- a/zokrates_analysis/src/constant_argument_checker.rs +++ b/zokrates_analysis/src/constant_argument_checker.rs @@ -77,6 +77,19 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker { e: FieldElementExpression<'ast, T>, ) -> Result, Self::Error> { match e { + FieldElementExpression::Pow(box e, box exp) => { + let e = self.fold_field_expression(e)?; + let exp = self.fold_uint_expression(exp)?; + + match exp.as_inner() { + UExpressionInner::Value(_) => Ok(FieldElementExpression::Pow(box e, box exp)), + exp => Err(Error(format!( + "Found non-constant exponent in expression `{}**{}`", + e, + exp.clone().annotate(UBitwidth::B32) + ))), + } + } FieldElementExpression::LeftShift(box e, box by) => { let e = self.fold_field_expression(e)?; let by = self.fold_uint_expression(by)?; diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index 1f8cb11bf..1b492140a 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -25,7 +25,6 @@ pub enum Error { AssertionFailed(String), ValueTooLarge(String), OutOfBounds(u128, u128), - NonConstantExponent(String), } impl fmt::Display for Error { @@ -39,11 +38,6 @@ impl fmt::Display for Error { "Out of bounds index ({} >= {}) found during static analysis", index, size ), - Error::NonConstantExponent(s) => write!( - f, - "Non-constant exponent `{}` detected during static analysis", - s - ), } } } @@ -877,8 +871,9 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { box e1, box UExpressionInner::Value(n2).annotate(UBitwidth::B32), )), - (_, e2) => Err(Error::NonConstantExponent( - e2.annotate(UBitwidth::B32).to_string(), + (e1, e2) => Ok(FieldElementExpression::Pow( + box e1, + box e2.annotate(UBitwidth::B32), )), } } @@ -960,7 +955,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } FieldElementExpression::RightShift(box e, box by) => { let e = self.fold_field_expression(e)?; - let by = self.fold_uint_expression(by)?; + let by = dbg!(self.fold_uint_expression(by)?); match (e, by) { ( e, diff --git a/zokrates_analysis/src/reducer/shallow_ssa.rs b/zokrates_analysis/src/reducer/shallow_ssa.rs index 6abcc8a78..61464a1e2 100644 --- a/zokrates_analysis/src/reducer/shallow_ssa.rs +++ b/zokrates_analysis/src/reducer/shallow_ssa.rs @@ -124,6 +124,25 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> { } impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> TypedAssemblyStatement<'ast, T> { + match s { + TypedAssemblyStatement::Assignment(a, e) => { + let e = self.fold_field_expression(e); + let a = match a { + TypedAssignee::Identifier(v) => { + let v = self.issue_next_ssa_variable(v); + TypedAssignee::Identifier(self.fold_variable(v)) + } + a => fold_assignee(self, a), + }; + TypedAssemblyStatement::Assignment(a, e) + } + s => fold_assembly_statement(self, s), + } + } fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec> { match s { TypedStatement::Definition(a, DefinitionRhs::Expression(e)) => { diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index fbde38138..944b9d669 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -1334,30 +1334,6 @@ impl<'ast, T> FieldElementExpression<'ast, T> { pub fn pow(self, other: UExpression<'ast, T>) -> Self { FieldElementExpression::Pow(box self, box other) } - - // This is used for early detection in semantics but it is not completely accurate - // Deeper analysis is done in a separate step after semantic checks - pub fn is_non_quadratic(&self) -> bool { - match self { - FieldElementExpression::Number(_) => false, - FieldElementExpression::Identifier(_) => false, - FieldElementExpression::Add(box left, box right) => { - left.is_non_quadratic() || right.is_non_quadratic() - } - FieldElementExpression::Sub(box left, box right) => { - left.is_non_quadratic() || right.is_non_quadratic() - } - FieldElementExpression::Mult(box left, box right) => { - left.is_non_quadratic() || right.is_non_quadratic() - } - FieldElementExpression::Neg(_) => false, - FieldElementExpression::Pos(_) => false, - FieldElementExpression::Member(_) => false, - FieldElementExpression::Select(_) => false, - FieldElementExpression::Element(_) => false, - _ => true, - } - } } impl<'ast, T> From for FieldElementExpression<'ast, T> { diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index 284083462..e5fceebc4 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -447,6 +447,26 @@ pub enum FieldElementExpression<'ast, T> { Conditional(ConditionalExpression<'ast, T, FieldElementExpression<'ast, T>>), } +impl<'ast, T> FieldElementExpression<'ast, T> { + pub fn is_linear(&self) -> bool { + match self { + FieldElementExpression::Number(_) => true, + FieldElementExpression::Identifier(_) => true, + FieldElementExpression::Add(box left, box right) => { + left.is_linear() && right.is_linear() + } + FieldElementExpression::Sub(box left, box right) => { + left.is_linear() && right.is_linear() + } + FieldElementExpression::Mult(box left, box right) => matches!( + (left, right), + (FieldElementExpression::Number(_), _) | (_, FieldElementExpression::Number(_)) + ), + _ => false, + } + } +} + /// An expression of type `bool` #[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum BooleanExpression<'ast, T> { diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index d66ffb7b0..78bd01502 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1801,13 +1801,6 @@ impl<'ast, T: Field> Checker<'ast, T> { match constrained { true => { - // early non-quadratic detection - if e.is_non_quadratic() { - return Err(ErrorInner { - pos: Some(pos), - message: "Non-quadratic constraints are not allowed".to_string(), - }); - } let e = FieldElementExpression::block(vec![], e); match assignee.get_type() { Type::FieldElement => Ok(vec![ @@ -1851,13 +1844,6 @@ impl<'ast, T: Field> Checker<'ast, T> { }), }?; - if lhs.is_non_quadratic() || rhs.is_non_quadratic() { - return Err(ErrorInner { - pos: Some(pos), - message: "Non-quadratic constraints are not allowed".to_string(), - }); - } - Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)]) } } diff --git a/zokrates_core_test/tests/tests/assembly/binary_sub.json b/zokrates_core_test/tests/tests/assembly/binary_sub.json new file mode 100644 index 000000000..d3b343a6e --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/binary_sub.json @@ -0,0 +1,46 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 10, + "tests": [ + { + "input": { + "values": [["1", "1", "1", "1"], ["0", "1", "1", "0"]] + }, + "output": { + "Ok": { + "value": ["1", "0", "0", "1"] + } + } + }, + { + "input": { + "values": [["0", "1", "1", "0"], ["1", "1", "1", "1"]] + }, + "output": { + "Ok": { + "value": ["1", "1", "1", "0"] + } + } + }, + { + "input": { + "values": [["0", "0", "0", "0"], ["1", "1", "1", "1"]] + }, + "output": { + "Ok": { + "value": ["1", "0", "0", "0"] + } + } + }, + { + "input": { + "values": [["1", "1", "1", "1"], ["1", "1", "1", "1"]] + }, + "output": { + "Ok": { + "value": ["0", "0", "0", "0"] + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/binary_sub.zok b/zokrates_core_test/tests/tests/assembly/binary_sub.zok new file mode 100644 index 000000000..58a60072b --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/binary_sub.zok @@ -0,0 +1,34 @@ +def bin_sub(field[N] a, field[N] b) -> field[N] { + field mut lin = 2**N; + field mut lout = 0; + + for u32 i in 0..N { + lin = lin + a[i] * (2**i); + lin = lin - b[i] * (2**i); + } + + field[N] mut out = [0; N]; + for u32 i in 0..N { + asm { + out[i] <-- (lin >> i) & 1; + out[i] * (out[i] - 1) === 0; + } + lout = lout + out[i] * (2**i); + } + + field mut aux = 0; + asm { + aux <-- (lin >> N) & 1; + aux * (aux - 1) === 0; + } + + lout = lout + aux * (2**N); + asm { + lin === lout; + } + return out; +} + +def main(field[4] a, field[4] b) -> field[4] { + return bin_sub(a, b); +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/xor_gate.json b/zokrates_core_test/tests/tests/assembly/gates/xor.json similarity index 100% rename from zokrates_core_test/tests/tests/assembly/xor_gate.json rename to zokrates_core_test/tests/tests/assembly/gates/xor.json diff --git a/zokrates_core_test/tests/tests/assembly/xor_gate.zok b/zokrates_core_test/tests/tests/assembly/gates/xor.zok similarity index 60% rename from zokrates_core_test/tests/tests/assembly/xor_gate.zok rename to zokrates_core_test/tests/tests/assembly/gates/xor.zok index 85d286a4c..ef49721e2 100644 --- a/zokrates_core_test/tests/tests/assembly/xor_gate.zok +++ b/zokrates_core_test/tests/tests/assembly/gates/xor.zok @@ -1,8 +1,7 @@ def main(field a, field b) -> field { field mut c = 0; asm { - c <-- a + b - 2*a*b; - a + b - c === 2*a*b; + c <== a + b - 2*a*b; } return c; } \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/is_zero.json b/zokrates_core_test/tests/tests/assembly/is_zero.json new file mode 100644 index 000000000..ad409b2cc --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/is_zero.json @@ -0,0 +1,26 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 3, + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "value": "0" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/is_zero.zok b/zokrates_core_test/tests/tests/assembly/is_zero.zok new file mode 100644 index 000000000..b366620df --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/is_zero.zok @@ -0,0 +1,10 @@ +def main(field inp) -> field { + field mut out = 0; + field mut inv = 0; + asm { + inv <-- inp != 0 ? 1 / inp : 0; + out <== -inp * inv + 1; + inp * out === 0; + } + return out; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/sha256_maj.json b/zokrates_core_test/tests/tests/assembly/sha256_maj.json new file mode 100644 index 000000000..a2b04fe80 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/sha256_maj.json @@ -0,0 +1,5 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [] +} diff --git a/zokrates_core_test/tests/tests/assembly/sha256_maj.zok b/zokrates_core_test/tests/tests/assembly/sha256_maj.zok new file mode 100644 index 000000000..ecd5b87d8 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/sha256_maj.zok @@ -0,0 +1,9 @@ +// Maj function for sha256 +// (a & b) ^ (a & c) ^ (b & c) +def main(field a, field b, field c) { + field mut out = 0; + field bc = b * c; + asm { + out <== a * (b + c - 2*bc) + bc; + } +} \ No newline at end of file From 83aebd5f876df4e3cc014af10a62e120d7cf174c Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 14:04:22 +0100 Subject: [PATCH 25/94] add assembly condition test --- .../src/constant_argument_checker.rs | 2 +- .../tests/tests/assembly/condition.json | 26 +++++++++++++++++++ .../tests/tests/assembly/condition.zok | 8 ++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 zokrates_core_test/tests/tests/assembly/condition.json create mode 100644 zokrates_core_test/tests/tests/assembly/condition.zok diff --git a/zokrates_analysis/src/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs index db77c5a35..726da8ee1 100644 --- a/zokrates_analysis/src/constant_argument_checker.rs +++ b/zokrates_analysis/src/constant_argument_checker.rs @@ -84,7 +84,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker { match exp.as_inner() { UExpressionInner::Value(_) => Ok(FieldElementExpression::Pow(box e, box exp)), exp => Err(Error(format!( - "Found non-constant exponent in expression `{}**{}`", + "Found non-constant exponent in pow expression `{}**{}`", e, exp.clone().annotate(UBitwidth::B32) ))), diff --git a/zokrates_core_test/tests/tests/assembly/condition.json b/zokrates_core_test/tests/tests/assembly/condition.json new file mode 100644 index 000000000..83d535f24 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/condition.json @@ -0,0 +1,26 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["1", "1", "0"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["0", "1", "0"] + }, + "output": { + "Ok": { + "value": "0" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/condition.zok b/zokrates_core_test/tests/tests/assembly/condition.zok new file mode 100644 index 000000000..9530ce7a8 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/condition.zok @@ -0,0 +1,8 @@ +def main(field c, field l, field r) -> field { + field mut out = 0; + asm { + out <-- c != 0 ? l : r; + out - r === c * (l - r); + } + return out; +} \ No newline at end of file From 063a8153084be75461c798d5d1f6ad38176f7d4c Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 19:08:56 +0100 Subject: [PATCH 26/94] allow variable shifts in witness assignment --- zokrates_analysis/src/assembly_transformer.rs | 11 ++--- .../src/constant_argument_checker.rs | 30 ------------ .../src/flatten_complex_types.rs | 46 +++++++++---------- zokrates_analysis/src/propagation.rs | 2 +- zokrates_analysis/src/zir_propagation.rs | 42 +++++++++++++---- zokrates_ast/src/zir/folder.rs | 10 ++-- zokrates_ast/src/zir/mod.rs | 12 +++-- zokrates_ast/src/zir/result_folder.rs | 10 ++-- .../tests/tests/assembly/gates/and.json | 46 +++++++++++++++++++ .../tests/tests/assembly/gates/and.zok | 7 +++ .../tests/tests/assembly/gates/not.json | 26 +++++++++++ .../tests/tests/assembly/gates/not.zok | 7 +++ .../tests/tests/assembly/gates/or.json | 46 +++++++++++++++++++ .../tests/tests/assembly/gates/or.zok | 7 +++ .../tests/tests/assembly/is_equal.json | 36 +++++++++++++++ .../tests/tests/assembly/is_equal.zok | 5 ++ zokrates_interpreter/src/lib.rs | 24 +++++++--- 17 files changed, 281 insertions(+), 86 deletions(-) create mode 100644 zokrates_core_test/tests/tests/assembly/gates/and.json create mode 100644 zokrates_core_test/tests/tests/assembly/gates/and.zok create mode 100644 zokrates_core_test/tests/tests/assembly/gates/not.json create mode 100644 zokrates_core_test/tests/tests/assembly/gates/not.zok create mode 100644 zokrates_core_test/tests/tests/assembly/gates/or.json create mode 100644 zokrates_core_test/tests/tests/assembly/gates/or.zok create mode 100644 zokrates_core_test/tests/tests/assembly/is_equal.json create mode 100644 zokrates_core_test/tests/tests/assembly/is_equal.zok diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index e067c5c3a..eb4b8ef5c 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -54,9 +54,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { false => { let sub = FieldElementExpression::Sub(box lhs.clone(), box rhs.clone()); let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { - Error( - "Found forbidden operation in user-defined constraint".to_string(), - ) + Error("Non-quadratic constraints are not allowed".to_string()) })?; let linear = lqc @@ -127,10 +125,9 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { }), box FieldElementExpression::identifier(id), )), - _ => Err(Error(format!( - "Non-quadratic constraints are not allowed `{} == {}`", - lhs, rhs - ))), + _ => Err(Error( + "Non-quadratic constraints are not allowed".to_string(), + )), }? } else { lqc.quadratic diff --git a/zokrates_analysis/src/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs index 726da8ee1..5d5429b51 100644 --- a/zokrates_analysis/src/constant_argument_checker.rs +++ b/zokrates_analysis/src/constant_argument_checker.rs @@ -90,36 +90,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker { ))), } } - FieldElementExpression::LeftShift(box e, box by) => { - let e = self.fold_field_expression(e)?; - let by = self.fold_uint_expression(by)?; - - match by.as_inner() { - UExpressionInner::Value(_) => { - Ok(FieldElementExpression::LeftShift(box e, box by)) - } - by => Err(Error(format!( - "Cannot shift by a variable value, found `{} << {}`", - e, - by.clone().annotate(UBitwidth::B32) - ))), - } - } - FieldElementExpression::RightShift(box e, box by) => { - let e = self.fold_field_expression(e)?; - let by = self.fold_uint_expression(by)?; - - match by.as_inner() { - UExpressionInner::Value(_) => { - Ok(FieldElementExpression::RightShift(box e, box by)) - } - by => Err(Error(format!( - "Cannot shift by a variable value, found `{} << {}`", - e, - by.clone().annotate(UBitwidth::B32) - ))), - } - } e => fold_field_expression(self, e), } } diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 8ce87a714..b6bd14593 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -1,12 +1,12 @@ -use std::collections::HashSet; +use std::collections::HashMap; +use std::convert::{TryFrom, TryInto}; use std::marker::PhantomData; use zokrates_ast::typed::types::{ConcreteArrayType, IntoType, UBitwidth}; use zokrates_ast::typed::{self, Expr, Typed}; +use zokrates_ast::zir::IntoType as ZirIntoType; use zokrates_ast::zir::{self, Folder, Id, Select}; use zokrates_field::Field; -use std::convert::{TryFrom, TryInto}; - #[derive(Default)] pub struct Flattener { phantom: PhantomData, @@ -460,15 +460,11 @@ impl<'ast, T: Field> Flattener { #[derive(Default)] pub struct ArgumentFinder<'ast, T> { - pub identifiers: HashSet>, + pub identifiers: HashMap, zir::Type>, _phantom: PhantomData, } impl<'ast, T: Field> Folder<'ast, T> for ArgumentFinder<'ast, T> { - fn fold_name(&mut self, n: zir::Identifier<'ast>) -> zir::Identifier<'ast> { - self.identifiers.insert(n.clone()); - n - } fn fold_statement(&mut self, s: zir::ZirStatement<'ast, T>) -> Vec> { match s { zir::ZirStatement::Definition(assignee, expr) => { @@ -491,6 +487,16 @@ impl<'ast, T: Field> Folder<'ast, T> for ArgumentFinder<'ast, T> { s => zir::folder::fold_statement(self, s), } } + + fn fold_identifier_expression + Id<'ast, T>>( + &mut self, + ty: &E::Ty, + e: zir::IdentifierExpression<'ast, E>, + ) -> zir::IdentifierOrExpression<'ast, T, E> { + self.identifiers + .insert(e.id.clone(), ty.clone().into_type()); + zir::IdentifierOrExpression::Identifier(e) + } } fn fold_assembly_statement<'ast, T: Field>( @@ -515,15 +521,17 @@ fn fold_assembly_statement<'ast, T: Field>( .collect(); statements_buffer.reverse(); + let _ = dbg!(&finder.identifiers); + let function = zir::ZirFunction { signature: zir::types::Signature::default() - .inputs(vec![zir::Type::FieldElement; finder.identifiers.len()]) + .inputs(finder.identifiers.values().cloned().collect()) .outputs(a.iter().map(|a| a.get_type()).collect()), arguments: finder .identifiers .into_iter() - .map(|id| zir::Parameter { - id: zir::Variable::field_element(id), + .map(|(id, ty)| zir::Parameter { + id: zir::Variable::with_id_and_type(id, ty), private: false, }) .collect(), @@ -1014,23 +1022,15 @@ fn fold_field_expression<'ast, T: Field>( } typed::FieldElementExpression::LeftShift(box e, box by) => { let e = f.fold_field_expression(statements_buffer, e); + let by = f.fold_uint_expression(statements_buffer, by); - let by = match by.as_inner() { - typed::UExpressionInner::Value(by) => by, - _ => unreachable!("static analysis should have made sure that this is constant"), - }; - - zir::FieldElementExpression::LeftShift(box e, *by as u32) + zir::FieldElementExpression::LeftShift(box e, box by) } typed::FieldElementExpression::RightShift(box e, box by) => { let e = f.fold_field_expression(statements_buffer, e); + let by = f.fold_uint_expression(statements_buffer, by); - let by = match by.as_inner() { - typed::UExpressionInner::Value(by) => by, - _ => unreachable!("static analysis should have made sure that this is constant"), - }; - - zir::FieldElementExpression::RightShift(box e, *by as u32) + zir::FieldElementExpression::RightShift(box e, box by) } typed::FieldElementExpression::Conditional(c) => f .fold_conditional_expression(statements_buffer, c) diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index 645c9126f..1369fc047 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -939,7 +939,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } FieldElementExpression::RightShift(box e, box by) => { let e = self.fold_field_expression(e)?; - let by = dbg!(self.fold_uint_expression(by)?); + let by = self.fold_uint_expression(by)?; match (e, by) { ( e, diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 3753e9b23..8582b33b1 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -301,24 +301,50 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { (e1, e2) => Ok(FieldElementExpression::Or(box e1, box e2)), } } - FieldElementExpression::LeftShift(box e, by) => { + FieldElementExpression::LeftShift(box e, box by) => { let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; match (e, by) { - (e, by) if by == 0u32 => Ok(e), - (FieldElementExpression::Number(n), by) => Ok(FieldElementExpression::Number( + ( + e, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by == 0 => Ok(e), + ( + FieldElementExpression::Number(n), + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) => Ok(FieldElementExpression::Number( T::try_from(n.to_biguint().shl(by as usize)).unwrap(), )), - (e, by) => Ok(FieldElementExpression::LeftShift(box e, by)), + (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), } } - FieldElementExpression::RightShift(box e, by) => { + FieldElementExpression::RightShift(box e, box by) => { let e = self.fold_field_expression(e)?; + let by = self.fold_uint_expression(by)?; match (e, by) { - (e, by) if by == 0u32 => Ok(e), - (FieldElementExpression::Number(n), by) => Ok(FieldElementExpression::Number( + ( + e, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by == 0 => Ok(e), + ( + FieldElementExpression::Number(n), + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) => Ok(FieldElementExpression::Number( T::try_from(n.to_biguint().shr(by as usize)).unwrap(), )), - (e, by) => Ok(FieldElementExpression::RightShift(box e, by)), + (e, by) => Ok(FieldElementExpression::RightShift(box e, box by)), } } e => fold_field_expression(self, e), diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index 9976abe7c..7a063dcb7 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -282,15 +282,17 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>( FieldElementExpression::Xor(box left, box right) } - FieldElementExpression::LeftShift(box e, by) => { + FieldElementExpression::LeftShift(box e, box by) => { let e = f.fold_field_expression(e); + let by = f.fold_uint_expression(by); - FieldElementExpression::LeftShift(box e, by) + FieldElementExpression::LeftShift(box e, box by) } - FieldElementExpression::RightShift(box e, by) => { + FieldElementExpression::RightShift(box e, box by) => { let e = f.fold_field_expression(e); + let by = f.fold_uint_expression(by); - FieldElementExpression::RightShift(box e, by) + FieldElementExpression::RightShift(box e, box by) } FieldElementExpression::Conditional(c) => { match f.fold_conditional_expression(&Type::FieldElement, c) { diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index 54525ab07..b793e4d67 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -71,7 +71,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirFunction<'ast, T> { writeln!(f)?; } - writeln!(f, "}}") + write!(f, "}}") } } @@ -464,8 +464,14 @@ pub enum FieldElementExpression<'ast, T> { Box>, Box>, ), - LeftShift(Box>, u32), - RightShift(Box>, u32), + LeftShift( + Box>, + Box>, + ), + RightShift( + Box>, + Box>, + ), Conditional(ConditionalExpression<'ast, T, FieldElementExpression<'ast, T>>), } diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 0be15b0be..912ad77bb 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -306,15 +306,17 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>( FieldElementExpression::Or(box left, box right) } - FieldElementExpression::LeftShift(box e, by) => { + FieldElementExpression::LeftShift(box e, box by) => { let e = f.fold_field_expression(e)?; + let by = f.fold_uint_expression(by)?; - FieldElementExpression::LeftShift(box e, by) + FieldElementExpression::LeftShift(box e, box by) } - FieldElementExpression::RightShift(box e, by) => { + FieldElementExpression::RightShift(box e, box by) => { let e = f.fold_field_expression(e)?; + let by = f.fold_uint_expression(by)?; - FieldElementExpression::RightShift(box e, by) + FieldElementExpression::RightShift(box e, box by) } FieldElementExpression::Conditional(c) => { match f.fold_conditional_expression(&Type::FieldElement, c)? { diff --git a/zokrates_core_test/tests/tests/assembly/gates/and.json b/zokrates_core_test/tests/tests/assembly/gates/and.json new file mode 100644 index 000000000..9002c6c8a --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/and.json @@ -0,0 +1,46 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["0", "0"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["1", "0"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["0", "1"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["1", "1"] + }, + "output": { + "Ok": { + "value": "1" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/gates/and.zok b/zokrates_core_test/tests/tests/assembly/gates/and.zok new file mode 100644 index 000000000..708e95451 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/and.zok @@ -0,0 +1,7 @@ +def main(field a, field b) -> field { + field mut c = 0; + asm { + c <== a * b; + } + return c; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/gates/not.json b/zokrates_core_test/tests/tests/assembly/gates/not.json new file mode 100644 index 000000000..92ab00e11 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/not.json @@ -0,0 +1,26 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "value": "0" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/gates/not.zok b/zokrates_core_test/tests/tests/assembly/gates/not.zok new file mode 100644 index 000000000..469e30711 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/not.zok @@ -0,0 +1,7 @@ +def main(field inp) -> field { + field mut out = 0; + asm { + out <== 1 + inp - 2*inp; + } + return out; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/gates/or.json b/zokrates_core_test/tests/tests/assembly/gates/or.json new file mode 100644 index 000000000..72cb84223 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/or.json @@ -0,0 +1,46 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["0", "0"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["1", "0"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["0", "1"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["1", "1"] + }, + "output": { + "Ok": { + "value": "1" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/gates/or.zok b/zokrates_core_test/tests/tests/assembly/gates/or.zok new file mode 100644 index 000000000..f5969b3fd --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/gates/or.zok @@ -0,0 +1,7 @@ +def main(field a, field b) -> field { + field mut c = 0; + asm { + c <== a + b - a*b; + } + return c; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/is_equal.json b/zokrates_core_test/tests/tests/assembly/is_equal.json new file mode 100644 index 000000000..597a5ece3 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/is_equal.json @@ -0,0 +1,36 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 3, + "tests": [ + { + "input": { + "values": ["1", "1"] + }, + "output": { + "Ok": { + "value": "1" + } + } + }, + { + "input": { + "values": ["2", "4"] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": ["4", "2"] + }, + "output": { + "Ok": { + "value": "0" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/is_equal.zok b/zokrates_core_test/tests/tests/assembly/is_equal.zok new file mode 100644 index 000000000..2992008aa --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/is_equal.zok @@ -0,0 +1,5 @@ +import "./is_zero.zok"; + +def main(field a, field b) -> field { + return is_zero(b - a); +} \ No newline at end of file diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index 6753866fa..d66784846 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -4,6 +4,7 @@ use zokrates_abi::{Decode, Value}; use zokrates_ast::ir::{ LinComb, ProgIterator, QuadComb, RuntimeError, Solver, Statement, Variable, Witness, }; +use zokrates_ast::zir; use zokrates_field::Field; pub type ExecutionResult = Result, Error>; @@ -168,11 +169,6 @@ impl Interpreter { let res = match solver { Solver::Zir(func) => { use zokrates_ast::zir::result_folder::ResultFolder; - - assert!(func - .arguments - .iter() - .all(|a| a.id._type == zokrates_ast::zir::Type::FieldElement)); assert_eq!(func.arguments.len(), inputs.len()); let constants = func @@ -182,7 +178,23 @@ impl Interpreter { .map(|(a, v)| { ( a.id.id.clone(), - zokrates_ast::zir::FieldElementExpression::Number(v.clone()).into(), + match &a.id._type { + zir::Type::FieldElement => { + zokrates_ast::zir::FieldElementExpression::Number(v.clone()) + .into() + } + zir::Type::Boolean => { + zokrates_ast::zir::BooleanExpression::Value(*v == T::from(1)) + .into() + } + zir::Type::Uint(bitwidth) => { + zokrates_ast::zir::UExpressionInner::Value( + v.to_dec_string().parse::().unwrap(), + ) + .annotate(*bitwidth) + .into() + } + }, ) }) .collect(); From 8349ad1cb6a26417c47cc963b0d2e8daacd8fb8e Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 19:11:30 +0100 Subject: [PATCH 27/94] add changelog --- changelogs/unreleased/1246-dark64 | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/1246-dark64 diff --git a/changelogs/unreleased/1246-dark64 b/changelogs/unreleased/1246-dark64 new file mode 100644 index 000000000..6c45d9a10 --- /dev/null +++ b/changelogs/unreleased/1246-dark64 @@ -0,0 +1 @@ +Introduce constraint generation through assembly blocks \ No newline at end of file From 530dd1d670291bf03992f0ddd36596325a8d9144 Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 19:13:08 +0100 Subject: [PATCH 28/94] remove dbg! --- zokrates_analysis/src/flatten_complex_types.rs | 2 -- zokrates_analysis/src/lib.rs | 1 - 2 files changed, 3 deletions(-) diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index b6bd14593..2d17575e0 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -521,8 +521,6 @@ fn fold_assembly_statement<'ast, T: Field>( .collect(); statements_buffer.reverse(); - let _ = dbg!(&finder.identifiers); - let function = zir::ZirFunction { signature: zir::types::Signature::default() .inputs(finder.identifiers.values().cloned().collect()) diff --git a/zokrates_analysis/src/lib.rs b/zokrates_analysis/src/lib.rs index 3496c8efe..78db874c1 100644 --- a/zokrates_analysis/src/lib.rs +++ b/zokrates_analysis/src/lib.rs @@ -208,7 +208,6 @@ pub fn analyse<'ast, T: Field>( let zir = UintOptimizer::optimize(zir); log::trace!("\n{}", zir); - // validate zir log::debug!("Static analyser: Apply constraint transformations in assembly"); let zir = AssemblyTransformer::transform(zir).map_err(Error::from)?; From 589c3fe9752e5f9ed3aaf44baccba3da47938cba Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 19:18:22 +0100 Subject: [PATCH 29/94] js formatting --- .../tests/tests/assembly/binary_sub.json | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/zokrates_core_test/tests/tests/assembly/binary_sub.json b/zokrates_core_test/tests/tests/assembly/binary_sub.json index d3b343a6e..f4e06cc8c 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_sub.json +++ b/zokrates_core_test/tests/tests/assembly/binary_sub.json @@ -4,7 +4,10 @@ "tests": [ { "input": { - "values": [["1", "1", "1", "1"], ["0", "1", "1", "0"]] + "values": [ + ["1", "1", "1", "1"], + ["0", "1", "1", "0"] + ] }, "output": { "Ok": { @@ -14,7 +17,10 @@ }, { "input": { - "values": [["0", "1", "1", "0"], ["1", "1", "1", "1"]] + "values": [ + ["0", "1", "1", "0"], + ["1", "1", "1", "1"] + ] }, "output": { "Ok": { @@ -24,7 +30,10 @@ }, { "input": { - "values": [["0", "0", "0", "0"], ["1", "1", "1", "1"]] + "values": [ + ["0", "0", "0", "0"], + ["1", "1", "1", "1"] + ] }, "output": { "Ok": { @@ -34,7 +43,10 @@ }, { "input": { - "values": [["1", "1", "1", "1"], ["1", "1", "1", "1"]] + "values": [ + ["1", "1", "1", "1"], + ["1", "1", "1", "1"] + ] }, "output": { "Ok": { From ce008efd320ea0ff182a53ea489d8314428b5136 Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 17 Nov 2022 19:19:57 +0100 Subject: [PATCH 30/94] increase circle ci instance --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0bfef41ee..98c18e57e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -96,7 +96,7 @@ jobs: zokrates_js_build: docker: - image: zokrates/env:latest - resource_class: large + resource_class: xlarge working_directory: ~/project/zokrates_js steps: - checkout: @@ -111,7 +111,7 @@ jobs: zokrates_js_test: docker: - image: zokrates/env:latest - resource_class: large + resource_class: xlarge working_directory: ~/project/zokrates_js steps: - checkout: From 5e3b8ff69063b1a9866f4da2beec0aea2729c3e4 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 21 Nov 2022 17:37:44 +0100 Subject: [PATCH 31/94] add whitespace test and changelog --- changelogs/unreleased/1232-dark64 | 1 + zokrates_core_test/tests/tests/whitespace.zok | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 changelogs/unreleased/1232-dark64 create mode 100644 zokrates_core_test/tests/tests/whitespace.zok diff --git a/changelogs/unreleased/1232-dark64 b/changelogs/unreleased/1232-dark64 new file mode 100644 index 000000000..86c554b4d --- /dev/null +++ b/changelogs/unreleased/1232-dark64 @@ -0,0 +1 @@ +Loosen up whitespace restrictions to allow more formatting styles \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/whitespace.zok b/zokrates_core_test/tests/tests/whitespace.zok new file mode 100644 index 000000000..483688399 --- /dev/null +++ b/zokrates_core_test/tests/tests/whitespace.zok @@ -0,0 +1,21 @@ +from "field" import FIELD_MIN, + FIELD_MAX, + FIELD_SIZE_IN_BITS; + +struct Foo +{ + field a; + field b; +} + +def main( + private Foo foo, + field c +) -> bool +{ + field[2] arr = [ + foo.a, + foo.b + ]; + return arr[0] * arr[1] == c; +} \ No newline at end of file From b8fe979a91d81f59db04441cb146e51a58096815 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 21 Nov 2022 17:39:19 +0100 Subject: [PATCH 32/94] rename pest rule --- zokrates_parser/src/zokrates.pest | 4 ++-- zokrates_pest_ast/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/zokrates_parser/src/zokrates.pest b/zokrates_parser/src/zokrates.pest index 1d5fa9a88..b3de98d53 100644 --- a/zokrates_parser/src/zokrates.pest +++ b/zokrates_parser/src/zokrates.pest @@ -2,8 +2,8 @@ file = { SOI ~ pragma? ~ symbol_declaration* ~ EOI } pragma = { "#pragma" ~ "curve" ~ curve } curve = @{ (ASCII_ALPHANUMERIC | "_") * } -raw_string = @{(!"\"" ~ ANY)*} -quoted_string = ${ "\"" ~ raw_string ~ "\"" } +string = @{(!"\"" ~ ANY)*} +quoted_string = ${ "\"" ~ string ~ "\"" } semicolon = _{";"} symbol_declaration = { (((import_directive | const_definition | type_definition) ~ semicolon) | (ty_struct_definition | function_definition)) } diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 5a7dffb42..f528cb2bd 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -387,7 +387,7 @@ mod ast { } #[derive(Debug, FromPest, PartialEq, Eq, Clone)] - #[pest_ast(rule(Rule::raw_string))] + #[pest_ast(rule(Rule::string))] pub struct RawString<'ast> { #[pest_ast(outer(with(span_into_str)))] pub value: String, From 65ea034520dc0cecc1244d0d6eb861d06d1dcfb2 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 22 Nov 2022 19:45:01 +0100 Subject: [PATCH 33/94] add assembly section to the book --- zokrates_book/src/SUMMARY.md | 1 + zokrates_book/src/language/assembly.md | 107 ++++++++++++++++++ .../tests/tests/assembly/condition.zok | 3 +- 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 zokrates_book/src/language/assembly.md diff --git a/zokrates_book/src/SUMMARY.md b/zokrates_book/src/SUMMARY.md index 298f90438..5d2830cbf 100644 --- a/zokrates_book/src/SUMMARY.md +++ b/zokrates_book/src/SUMMARY.md @@ -16,6 +16,7 @@ - [Comments](language/comments.md) - [Macros](language/macros.md) - [Logging](language/logging.md) + - [Assembly](language/assembly.md) - [Toolbox](toolbox/index.md) - [CLI](toolbox/cli.md) diff --git a/zokrates_book/src/language/assembly.md b/zokrates_book/src/language/assembly.md new file mode 100644 index 000000000..9d7cfcb3b --- /dev/null +++ b/zokrates_book/src/language/assembly.md @@ -0,0 +1,107 @@ +## Assembly + +ZoKrates allows developers to define constraints through assembly blocks. Assembly blocks are considered **unsafe**, as safety and correctness of the resulting arithmetic circuit is in the hands of the developer. Usage of assembly is recommended only in optimization efforts for the experienced developers to minimize constraint count of an arithmetic circuit. + +## Writing assembly + +All constraints must be enclosed within an `asm` block. In an assembly block we can do the following: + +1. Assign to a witness variable using `<--` +2. Define a constraint using `===` + +Assigning a value, in general, should be combined with adding a constraint: + +```zok +def main(field a, field b) { + field mut c = 0; + asm { + c <-- a / b; + a === b * c; + } +} +``` + +> The operator `<--` can be sometimes misused, as this operator does not generate any constraints, resulting in unconstrained variables in the constraint system. + +In some cases we can combine the witness assignment and constraint generation with the `<==` operator: + +```zok +asm { + c <== 1 - a*b; +} +``` + +which is equivalent to: + +```zok +asm { + c <-- 1 - a*b; + c === 1 - a*b; +} +``` + +A constraint can contain arithmetic expressions that are built using multiplication, addition, and other variables or `field` values. Only quadratic expressions are allowed to be included in constraints. Non-quadratic expressions or usage of other arithmetic operators like division or power are not allowed as constraints, but can be used in the witness assignment expression. + +The following code is not allowed: + +```zok +asm { + d === a*b*c; +} +``` + +as the constraint `d === a*b*c` is not quadratic. + +In some cases, ZoKrates will apply minor transformations on the defined constraints in order to meet the correct format: + +```zok +asm { + x * (x - 1) === 0; +} +``` + +will be transformed to: + +```zok +asm { + x === x * x; +} +``` + +## Type casting + +Assembly is a low-level part of the compiler which does not have type safety. In some cases we might want to do zero-cost conversions between `field` and `bool` type. + +### field_to_bool_unsafe + +This call is unsafe because it is the responsibility of the user to constrain the field input: + +```zok +from "EMBED" import field_to_bool_unsafe; + +def main(field x) -> bool { + // we constrain `x` to be 0 or 1 + asm { + x * (x - 1) === 0; + } + // we can treat `x` as `bool` afterwards, as we constrained it properly + // `field_to_bool_unsafe` call does not produce any extra constraints + bool out = field_to_bool_unsafe(x); + return out; +} +``` + +### bool_to_field + +This call is safe as `bool` types are constrained by the compiler: + +```zok +from "EMBED" import bool_to_field; + +def main(bool x) -> field { + // `x` is constrained by the compiler automatically so we can safely + // treat it as `field` with no extra cost + field out = bool_to_field(x); + return out; +} +``` \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/condition.zok b/zokrates_core_test/tests/tests/assembly/condition.zok index 9530ce7a8..05aff5e3e 100644 --- a/zokrates_core_test/tests/tests/assembly/condition.zok +++ b/zokrates_core_test/tests/tests/assembly/condition.zok @@ -1,8 +1,7 @@ def main(field c, field l, field r) -> field { field mut out = 0; asm { - out <-- c != 0 ? l : r; - out - r === c * (l - r); + out <== c * l + (1 - c) * r; } return out; } \ No newline at end of file From fd361d68f380cff86f5630b8e0c9913446eb53de Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 22 Nov 2022 20:32:49 +0100 Subject: [PATCH 34/94] more tests --- zokrates_analysis/src/propagation.rs | 1 + zokrates_ast/src/common/embed.rs | 8 ++++ zokrates_book/src/language/assembly.md | 30 ++------------- .../examples/book/assembly/bool_to_field.zok | 8 ++++ .../examples/book/assembly/division.zok | 7 ++++ .../examples/book/assembly/field_to_bool.zok | 12 ++++++ zokrates_codegen/src/lib.rs | 1 + zokrates_core/src/imports.rs | 4 ++ .../tests/tests/assembly/less_than.json | 36 ++++++++++++++++++ .../tests/tests/assembly/less_than.zok | 14 +++++++ .../tests/tests/embed/bool_to_field.json | 26 +++++++++++++ .../tests/tests/embed/bool_to_field.zok | 6 +++ .../tests/tests/embed/field_to_bool.json | 38 +++++++++++++++++++ .../tests/tests/embed/field_to_bool.zok | 9 +++++ 14 files changed, 173 insertions(+), 27 deletions(-) create mode 100644 zokrates_cli/examples/book/assembly/bool_to_field.zok create mode 100644 zokrates_cli/examples/book/assembly/division.zok create mode 100644 zokrates_cli/examples/book/assembly/field_to_bool.zok create mode 100644 zokrates_core_test/tests/tests/assembly/less_than.json create mode 100644 zokrates_core_test/tests/tests/assembly/less_than.zok create mode 100644 zokrates_core_test/tests/tests/embed/bool_to_field.json create mode 100644 zokrates_core_test/tests/tests/embed/bool_to_field.zok create mode 100644 zokrates_core_test/tests/tests/embed/field_to_bool.json create mode 100644 zokrates_core_test/tests/tests/embed/field_to_bool.zok diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index 1369fc047..f68089215 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -400,6 +400,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { true => { let r: Option> = match embed_call.embed { FlatEmbed::FieldToBoolUnsafe => Ok(None), // todo + FlatEmbed::BoolToField => Ok(None), // todo FlatEmbed::BitArrayLe => Ok(None), // todo FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits( &embed_call.arguments, diff --git a/zokrates_ast/src/common/embed.rs b/zokrates_ast/src/common/embed.rs index 58294142f..3f961cd9a 100644 --- a/zokrates_ast/src/common/embed.rs +++ b/zokrates_ast/src/common/embed.rs @@ -32,6 +32,7 @@ cfg_if::cfg_if! { #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Serialize, Deserialize)] pub enum FlatEmbed { FieldToBoolUnsafe, + BoolToField, BitArrayLe, Unpack, U8ToBits, @@ -54,6 +55,9 @@ impl FlatEmbed { FlatEmbed::FieldToBoolUnsafe => UnresolvedSignature::new() .inputs(vec![UnresolvedType::FieldElement.into()]) .output(UnresolvedType::Boolean.into()), + FlatEmbed::BoolToField => UnresolvedSignature::new() + .inputs(vec![UnresolvedType::Boolean.into()]) + .output(UnresolvedType::FieldElement.into()), FlatEmbed::BitArrayLe => UnresolvedSignature::new() .generics(vec![ConstantGenericNode::mock("N")]) .inputs(vec![ @@ -193,6 +197,9 @@ impl FlatEmbed { FlatEmbed::FieldToBoolUnsafe => DeclarationSignature::new() .inputs(vec![DeclarationType::FieldElement]) .output(DeclarationType::Boolean), + FlatEmbed::BoolToField => DeclarationSignature::new() + .inputs(vec![DeclarationType::Boolean]) + .output(DeclarationType::FieldElement), FlatEmbed::BitArrayLe => DeclarationSignature::new() .generics(vec![Some(DeclarationConstant::Generic( GenericIdentifier::with_name("N").with_index(0), @@ -300,6 +307,7 @@ impl FlatEmbed { pub fn id(&self) -> &'static str { match self { FlatEmbed::FieldToBoolUnsafe => "_FIELD_TO_BOOL_UNSAFE", + FlatEmbed::BoolToField => "_BOOL_TO_FIELD", FlatEmbed::BitArrayLe => "_BIT_ARRAY_LT", FlatEmbed::Unpack => "_UNPACK", FlatEmbed::U8ToBits => "_U8_TO_BITS", diff --git a/zokrates_book/src/language/assembly.md b/zokrates_book/src/language/assembly.md index 9d7cfcb3b..a6782a6d5 100644 --- a/zokrates_book/src/language/assembly.md +++ b/zokrates_book/src/language/assembly.md @@ -12,13 +12,7 @@ All constraints must be enclosed within an `asm` block. In an assembly block we Assigning a value, in general, should be combined with adding a constraint: ```zok -def main(field a, field b) { - field mut c = 0; - asm { - c <-- a / b; - a === b * c; - } -} +{{#include ../../../zokrates_cli/examples/book/assembly/division.zok}} ``` > The operator `<--` can be sometimes misused, as this operator does not generate any constraints, resulting in unconstrained variables in the constraint system. @@ -77,18 +71,7 @@ Assembly is a low-level part of the compiler which does not have type safety. In This call is unsafe because it is the responsibility of the user to constrain the field input: ```zok -from "EMBED" import field_to_bool_unsafe; - -def main(field x) -> bool { - // we constrain `x` to be 0 or 1 - asm { - x * (x - 1) === 0; - } - // we can treat `x` as `bool` afterwards, as we constrained it properly - // `field_to_bool_unsafe` call does not produce any extra constraints - bool out = field_to_bool_unsafe(x); - return out; -} +{{#include ../../../zokrates_cli/examples/book/assembly/field_to_bool.zok}} ``` ### bool_to_field @@ -96,12 +79,5 @@ def main(field x) -> bool { This call is safe as `bool` types are constrained by the compiler: ```zok -from "EMBED" import bool_to_field; - -def main(bool x) -> field { - // `x` is constrained by the compiler automatically so we can safely - // treat it as `field` with no extra cost - field out = bool_to_field(x); - return out; -} +{{#include ../../../zokrates_cli/examples/book/assembly/bool_to_field.zok}} ``` \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/bool_to_field.zok b/zokrates_cli/examples/book/assembly/bool_to_field.zok new file mode 100644 index 000000000..4c1284b03 --- /dev/null +++ b/zokrates_cli/examples/book/assembly/bool_to_field.zok @@ -0,0 +1,8 @@ +from "EMBED" import bool_to_field; + +def main(bool x) -> field { + // `x` is constrained by the compiler automatically so we can safely + // treat it as `field` with no extra cost + field out = bool_to_field(x); + return out; +} \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/division.zok b/zokrates_cli/examples/book/assembly/division.zok new file mode 100644 index 000000000..c38e18ee2 --- /dev/null +++ b/zokrates_cli/examples/book/assembly/division.zok @@ -0,0 +1,7 @@ +def main(field a, field b) { + field mut c = 0; + asm { + c <-- a / b; + a === b * c; + } +} \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/field_to_bool.zok b/zokrates_cli/examples/book/assembly/field_to_bool.zok new file mode 100644 index 000000000..b213b346f --- /dev/null +++ b/zokrates_cli/examples/book/assembly/field_to_bool.zok @@ -0,0 +1,12 @@ +from "EMBED" import field_to_bool_unsafe; + +def main(field x) -> bool { + // we constrain `x` to be 0 or 1 + asm { + x * (x - 1) === 0; + } + // we can treat `x` as `bool` afterwards, as we constrained it properly + // `field_to_bool_unsafe` call does not produce any extra constraints + bool out = field_to_bool_unsafe(x); + return out; +} \ No newline at end of file diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index 4c08dd73c..253173916 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -1050,6 +1050,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { match embed { FlatEmbed::FieldToBoolUnsafe => vec![params.pop().unwrap()], + FlatEmbed::BoolToField => vec![params.pop().unwrap()], FlatEmbed::U8ToBits => self.u_to_bits(params.pop().unwrap(), 8.into()), FlatEmbed::U16ToBits => self.u_to_bits(params.pop().unwrap(), 16.into()), FlatEmbed::U32ToBits => self.u_to_bits(params.pop().unwrap(), 32.into()), diff --git a/zokrates_core/src/imports.rs b/zokrates_core/src/imports.rs index f7fa95f13..4bdf49407 100644 --- a/zokrates_core/src/imports.rs +++ b/zokrates_core/src/imports.rs @@ -151,6 +151,10 @@ impl Importer { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::FieldToBoolUnsafe), }, + "bool_to_field" => SymbolDeclaration { + id: symbol.get_alias(), + symbol: Symbol::Flat(FlatEmbed::BoolToField), + }, "bit_array_le" => SymbolDeclaration { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::BitArrayLe), diff --git a/zokrates_core_test/tests/tests/assembly/less_than.json b/zokrates_core_test/tests/tests/assembly/less_than.json new file mode 100644 index 000000000..91eaaa073 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/less_than.json @@ -0,0 +1,36 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 7, + "tests": [ + { + "input": { + "values": ["2", "2"] + }, + "output": { + "Ok": { + "value": false + } + } + }, + { + "input": { + "values": ["4", "2"] + }, + "output": { + "Ok": { + "value": false + } + } + }, + { + "input": { + "values": ["2", "4"] + }, + "output": { + "Ok": { + "value": true + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/less_than.zok b/zokrates_core_test/tests/tests/assembly/less_than.zok new file mode 100644 index 000000000..8af9235da --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/less_than.zok @@ -0,0 +1,14 @@ +from "EMBED" import field_to_bool_unsafe; +from "field" import FIELD_SIZE_IN_BITS; +from "./bitify" import bitify; + +def less_than(field a, field b) -> bool { + assert(N < FIELD_SIZE_IN_BITS - 1); + field[N + 1] bits = bitify(a + (1f << N) - b); + bool out = field_to_bool_unsafe(1 - bits[N]); + return out; +} + +def main(field a, field b) -> bool { + return less_than::<4>(a, b); +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/embed/bool_to_field.json b/zokrates_core_test/tests/tests/embed/bool_to_field.json new file mode 100644 index 000000000..5e78b2981 --- /dev/null +++ b/zokrates_core_test/tests/tests/embed/bool_to_field.json @@ -0,0 +1,26 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": [false] + }, + "output": { + "Ok": { + "value": "0" + } + } + }, + { + "input": { + "values": [true] + }, + "output": { + "Ok": { + "value": "1" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/embed/bool_to_field.zok b/zokrates_core_test/tests/tests/embed/bool_to_field.zok new file mode 100644 index 000000000..457ac06dc --- /dev/null +++ b/zokrates_core_test/tests/tests/embed/bool_to_field.zok @@ -0,0 +1,6 @@ +from "EMBED" import bool_to_field; + +def main(bool x) -> field { + field out = bool_to_field(x); + return out; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/embed/field_to_bool.json b/zokrates_core_test/tests/tests/embed/field_to_bool.json new file mode 100644 index 000000000..d24af7e06 --- /dev/null +++ b/zokrates_core_test/tests/tests/embed/field_to_bool.json @@ -0,0 +1,38 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["0"] + }, + "output": { + "Ok": { + "value": false + } + } + }, + { + "input": { + "values": ["1"] + }, + "output": { + "Ok": { + "value": true + } + } + }, + { + "input": { + "values": ["2"] + }, + "output": { + "Err": { + "UnsatisfiedConstraint": { + "error": "UserConstraint" + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/embed/field_to_bool.zok b/zokrates_core_test/tests/tests/embed/field_to_bool.zok new file mode 100644 index 000000000..ebf77e9b7 --- /dev/null +++ b/zokrates_core_test/tests/tests/embed/field_to_bool.zok @@ -0,0 +1,9 @@ +from "EMBED" import field_to_bool_unsafe; + +def main(field x) -> bool { + asm { + x * (x - 1) === 0; + } + bool out = field_to_bool_unsafe(x); + return out; +} \ No newline at end of file From bc791e043ac10006b17d2eedbe1132cec8e41fa8 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 22 Nov 2022 21:57:49 +0100 Subject: [PATCH 35/94] update interpreter --- zokrates_interpreter/src/lib.rs | 54 ++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index d66784846..01c9dfb35 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use std::fmt; use zokrates_abi::{Decode, Value}; use zokrates_ast::ir::{ @@ -175,29 +176,40 @@ impl Interpreter { .arguments .iter() .zip(inputs) - .map(|(a, v)| { - ( + .map(|(a, v)| match &a.id._type { + zir::Type::FieldElement => Ok(( a.id.id.clone(), - match &a.id._type { - zir::Type::FieldElement => { - zokrates_ast::zir::FieldElementExpression::Number(v.clone()) - .into() - } - zir::Type::Boolean => { - zokrates_ast::zir::BooleanExpression::Value(*v == T::from(1)) - .into() - } - zir::Type::Uint(bitwidth) => { - zokrates_ast::zir::UExpressionInner::Value( - v.to_dec_string().parse::().unwrap(), - ) - .annotate(*bitwidth) - .into() - } - }, - ) + zokrates_ast::zir::FieldElementExpression::Number(v.clone()).into(), + )), + zir::Type::Boolean => match v { + v if *v == T::from(0) => Ok(( + a.id.id.clone(), + zokrates_ast::zir::BooleanExpression::Value(false).into(), + )), + v if *v == T::from(1) => Ok(( + a.id.id.clone(), + zokrates_ast::zir::BooleanExpression::Value(true).into(), + )), + v => Err(format!("`{}` has unexpected value `{}`", a.id, v)), + }, + zir::Type::Uint(bitwidth) => match v.bits() <= bitwidth.to_usize() as u32 { + true => Ok(( + a.id.id.clone(), + zokrates_ast::zir::UExpressionInner::Value( + v.to_dec_string().parse::().unwrap(), + ) + .annotate(*bitwidth) + .into(), + )), + false => Err(format!( + "`{}` has unexpected bitwidth (got {} but expected {})", + a.id, + v.bits(), + bitwidth + )), + }, }) - .collect(); + .collect::, _>>()?; let mut propagator = zokrates_analysis::ZirPropagator::with_constants(constants); From c73c09e5c2b89703bf1d58fb9d4b8b54ad7c1554 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 23 Nov 2022 20:31:49 +0100 Subject: [PATCH 36/94] fix shifting in zir propagation --- zokrates_analysis/src/zir_propagation.rs | 143 ++++++++++++++++++++++- 1 file changed, 139 insertions(+), 4 deletions(-) diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 8582b33b1..1a026b178 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -1,6 +1,8 @@ +use num::traits::Pow; +use num_bigint::BigUint; use std::collections::HashMap; use std::fmt; -use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr}; +use std::ops::{BitAnd, BitOr, BitXor, Mul, Shr, Sub}; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, Id, @@ -312,15 +314,30 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { .. }, ) if by == 0 => Ok(e), + ( + _, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by as usize >= T::get_required_bits() => { + Ok(FieldElementExpression::Number(T::from(0))) + } ( FieldElementExpression::Number(n), UExpression { inner: UExpressionInner::Value(by), .. }, - ) => Ok(FieldElementExpression::Number( - T::try_from(n.to_biguint().shl(by as usize)).unwrap(), - )), + ) => { + let two = BigUint::from(2usize); + let mask: BigUint = two.pow(T::get_required_bits()).sub(1usize); + + Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().mul(two.pow(by as usize)).bitand(mask)) + .unwrap(), + )) + } (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), } } @@ -335,6 +352,15 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { .. }, ) if by == 0 => Ok(e), + ( + _, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by as usize >= T::get_required_bits() => { + Ok(FieldElementExpression::Number(T::from(0))) + } ( FieldElementExpression::Number(n), UExpression { @@ -948,6 +974,115 @@ mod tests { ); } + #[test] + fn left_shift() { + let mut propagator = ZirPropagator::::default(); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::identifier("a".into()), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::identifier("a".into())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box UExpressionInner::Value(2 as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(8))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(1)), + box UExpressionInner::Value((Bn128Field::get_required_bits() - 1) as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::try_from_dec_str("14474011154664524427946373126085988481658748083205070504932198000989141204992").unwrap())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(3)), + box UExpressionInner::Value((Bn128Field::get_required_bits() - 3) as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::try_from_dec_str("10855508365998393320959779844564491361244061062403802878699148500741855903744").unwrap())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(1)), + box UExpressionInner::Value((Bn128Field::get_required_bits()) as u128) + .annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + } + + #[test] + fn right_shift() { + let mut propagator = ZirPropagator::::default(); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::identifier("a".into()), + box UExpressionInner::Value(0).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::identifier("a".into())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::identifier("a".into()), + box UExpressionInner::Value(Bn128Field::get_required_bits() as u128) + .annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(3)), + box UExpressionInner::Value(1 as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(1))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box UExpressionInner::Value(2 as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box UExpressionInner::Value(4 as u128).annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::max_value()), + box UExpressionInner::Value((Bn128Field::get_required_bits() - 1) as u128) + .annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(1))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::max_value()), + box UExpressionInner::Value(Bn128Field::get_required_bits() as u128) + .annotate(UBitwidth::B32), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + } + #[test] fn if_else() { let mut propagator = ZirPropagator::default(); From 1e07a90ed655fe3074df6dd37461ba0db04885ef Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 23 Nov 2022 20:54:37 +0100 Subject: [PATCH 37/94] add tests to typed propagation --- zokrates_analysis/src/propagation.rs | 141 ++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 4 deletions(-) diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index f68089215..a1c1764f0 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -7,10 +7,12 @@ //! @author Thibaut Schaeffer //! @date 2018 +use num::traits::Pow; +use num_bigint::BigUint; use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; use std::fmt; -use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr}; +use std::ops::{BitAnd, BitOr, BitXor, Mul, Shr, Sub}; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::result_folder::*; use zokrates_ast::typed::types::Type; @@ -926,15 +928,30 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { .. }, ) if by == 0 => Ok(e), + ( + _, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by as usize >= T::get_required_bits() => { + Ok(FieldElementExpression::Number(T::from(0))) + } ( FieldElementExpression::Number(n), UExpression { inner: UExpressionInner::Value(by), .. }, - ) => Ok(FieldElementExpression::Number( - T::try_from(n.to_biguint().shl(by as usize)).unwrap(), - )), + ) => { + let two = BigUint::from(2usize); + let mask: BigUint = two.pow(T::get_required_bits()).sub(1usize); + + Ok(FieldElementExpression::Number( + T::try_from(n.to_biguint().mul(two.pow(by as usize)).bitand(mask)) + .unwrap(), + )) + } (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), } } @@ -949,6 +966,15 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { .. }, ) if by == 0 => Ok(e), + ( + _, + UExpression { + inner: UExpressionInner::Value(by), + .. + }, + ) if by as usize >= T::get_required_bits() => { + Ok(FieldElementExpression::Number(T::from(0))) + } ( FieldElementExpression::Number(n), UExpression { @@ -1462,6 +1488,113 @@ mod tests { ); } + #[test] + fn left_shift() { + let mut constants = Constants::new(); + let mut propagator = Propagator::with_constants(&mut constants); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::identifier("a".into()), + box 0u32.into(), + )), + Ok(FieldElementExpression::identifier("a".into())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box 2u32.into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(8))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(1)), + box ((Bn128Field::get_required_bits() - 1) as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::try_from_dec_str("14474011154664524427946373126085988481658748083205070504932198000989141204992").unwrap())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(3)), + box ((Bn128Field::get_required_bits() - 3) as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::try_from_dec_str("10855508365998393320959779844564491361244061062403802878699148500741855903744").unwrap())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::LeftShift( + box FieldElementExpression::Number(Bn128Field::from(1)), + box (Bn128Field::get_required_bits() as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + } + + #[test] + fn right_shift() { + let mut constants = Constants::new(); + let mut propagator = Propagator::with_constants(&mut constants); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::identifier("a".into()), + box 0u32.into(), + )), + Ok(FieldElementExpression::identifier("a".into())) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::identifier("a".into()), + box (Bn128Field::get_required_bits() as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(3)), + box 1u32.into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(1))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box 2u32.into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::from(2)), + box 4u32.into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::max_value()), + box ((Bn128Field::get_required_bits() - 1) as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(1))) + ); + + assert_eq!( + propagator.fold_field_expression(FieldElementExpression::RightShift( + box FieldElementExpression::Number(Bn128Field::max_value()), + box (Bn128Field::get_required_bits() as u32).into(), + )), + Ok(FieldElementExpression::Number(Bn128Field::from(0))) + ); + } + #[test] fn if_else_true() { let e = FieldElementExpression::conditional( From 8d7e5804dfefc3dd5b7f1d9139d54ba81cd53a05 Mon Sep 17 00:00:00 2001 From: dark64 Date: Fri, 25 Nov 2022 17:54:21 +0100 Subject: [PATCH 38/94] improvements --- zokrates_analysis/src/assembly_transformer.rs | 128 ++++++++++-------- .../src/flatten_complex_types.rs | 21 +++ zokrates_analysis/src/propagation.rs | 12 +- zokrates_analysis/src/zir_propagation.rs | 5 +- zokrates_ast/src/common/embed.rs | 8 -- zokrates_ast/src/common/error.rs | 6 +- zokrates_ast/src/common/solvers.rs | 2 +- zokrates_ast/src/zir/lqc.rs | 7 +- zokrates_ast/src/zir/mod.rs | 3 +- .../examples/book/assembly/bool_to_field.zok | 6 +- .../examples/book/assembly/division.zok | 8 +- .../examples/book/assembly/field_to_bool.zok | 3 +- zokrates_cli/src/bin.rs | 2 +- zokrates_codegen/src/lib.rs | 3 +- zokrates_core/src/imports.rs | 4 - zokrates_core/src/semantics.rs | 24 ++-- .../tests/tests/assembly/binary_check.json | 2 +- .../tests/tests/assembly/bitify.json | 2 +- .../tests/tests/assembly/division.json | 8 +- .../tests/tests/assembly/division.zok | 13 +- .../tests/tests/embed/bool_to_field.json | 26 ---- .../tests/tests/embed/bool_to_field.zok | 6 - .../tests/tests/embed/field_to_bool.json | 2 +- zokrates_test/tests/out_of_range.rs | 8 +- 24 files changed, 156 insertions(+), 153 deletions(-) delete mode 100644 zokrates_core_test/tests/tests/embed/bool_to_field.json delete mode 100644 zokrates_core_test/tests/tests/embed/bool_to_field.zok diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index eb4b8ef5c..3d1e95675 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -1,3 +1,7 @@ +// A static analyser pass to transform user-defined constraints to the form `lin_comb === quad_comb` +// This pass can fail if a non-quadratic constraint is found which cannot be transformed to the expected form + +use crate::ZirPropagator; use std::fmt; use zokrates_ast::zir::lqc::LinQuadComb; use zokrates_ast::zir::result_folder::{fold_field_expression, ResultFolder}; @@ -17,8 +21,7 @@ pub struct AssemblyTransformer; impl AssemblyTransformer { pub fn transform(p: ZirProgram) -> Result, Error> { - let mut f = AssemblyTransformer; - f.fold_program(p) + AssemblyTransformer.fold_program(p) } } @@ -52,7 +55,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { match is_quadratic { true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs)), false => { - let sub = FieldElementExpression::Sub(box lhs.clone(), box rhs.clone()); + let sub = FieldElementExpression::Sub(box lhs, box rhs); let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { Error("Non-quadratic constraints are not allowed".to_string()) })?; @@ -60,72 +63,72 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { let linear = lqc .linear .into_iter() - .filter_map(|(c, i)| match c { - c if c == T::from(0) => None, - c if c == T::from(1) => Some(FieldElementExpression::identifier(i)), - _ => Some(FieldElementExpression::Mult( + .map(|(c, i)| { + FieldElementExpression::Mult( box FieldElementExpression::Number(c), box FieldElementExpression::identifier(i), - )), + ) }) - .reduce(|p, n| FieldElementExpression::Add(box p, box n)) - .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))); - - let lhs = match lqc.constant { - c if c == T::from(0) => linear, - c => FieldElementExpression::Add( - box FieldElementExpression::Number(c), - box linear, - ), - }; + .fold(FieldElementExpression::Number(T::from(0)), |acc, e| { + FieldElementExpression::Add(box acc, box e) + }); + + let lhs = FieldElementExpression::Add( + box FieldElementExpression::Number(lqc.constant), + box linear, + ); let rhs: FieldElementExpression<'ast, T> = if lqc.quadratic.len() > 1 { - let is_common_factor = |id: &Identifier<'ast>, - q: &Vec<( - T, - Identifier<'ast>, - Identifier<'ast>, - )>| { - q.iter().all(|(_, i0, i1)| i0.eq(id) || i1.eq(id)) - }; - - let common_factor: Option> = - lqc.quadratic.iter().find_map(|(_, i0, i1)| { - if is_common_factor(i0, &lqc.quadratic) { - Some(i0.clone()) - } else if is_common_factor(i1, &lqc.quadratic) { - Some(i1.clone()) - } else { - None - } - }); - - match common_factor { - Some(id) => Ok(FieldElementExpression::Mult( + let common_factors = lqc.quadratic.iter().fold( + None, + |acc: Option>, (_, a, b)| { + Some( + acc.map(|factors| { + factors + .into_iter() + .filter(|f| f == a || f == b) + .collect() + }) + .unwrap_or_else(|| vec![a.clone(), b.clone()]), + ) + }, + ); + + match common_factors { + Some(factors) => Ok(FieldElementExpression::Mult( box lqc .quadratic .into_iter() - .filter_map(|(c, i0, i1)| { + .map(|(c, i0, i1)| { let c = T::zero() - c; - let id = if id.eq(&i0) { i1 } else { i0 }; - match c { - c if c == T::from(0) => None, - c if c == T::from(1) => { - Some(FieldElementExpression::identifier(id)) - } - _ => Some(FieldElementExpression::Mult( - box FieldElementExpression::Number(c), - box FieldElementExpression::identifier(id), - )), - } + let i0 = match factors.contains(&i0) { + true => FieldElementExpression::Number(T::from(1)), + false => FieldElementExpression::identifier(i0), + }; + let i1 = match factors.contains(&i1) { + true => FieldElementExpression::Number(T::from(1)), + false => FieldElementExpression::identifier(i1), + }; + FieldElementExpression::Mult( + box FieldElementExpression::Number(c), + box FieldElementExpression::Mult(box i0, box i1), + ) }) - .reduce(|p, n| FieldElementExpression::Add(box p, box n)) - .unwrap_or_else(|| { - FieldElementExpression::Number(T::from(0)) - }), - box FieldElementExpression::identifier(id), + .fold( + FieldElementExpression::Number(T::from(0)), + |acc, e| FieldElementExpression::Add(box acc, box e), + ), + box factors.into_iter().fold( + FieldElementExpression::Number(T::from(1)), + |acc, id| { + FieldElementExpression::Mult( + box acc, + box FieldElementExpression::identifier(id), + ) + }, + ), )), - _ => Err(Error( + None => Err(Error( "Non-quadratic constraints are not allowed".to_string(), )), }? @@ -144,6 +147,15 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { .unwrap_or_else(|| FieldElementExpression::Number(T::from(0))) }; + let mut propagator = ZirPropagator::default(); + let lhs = propagator + .fold_field_expression(lhs) + .map_err(|e| Error(e.to_string()))?; + + let rhs = propagator + .fold_field_expression(rhs) + .map_err(|e| Error(e.to_string()))?; + Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) } } diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 2d17575e0..56bb55c97 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -458,6 +458,27 @@ impl<'ast, T: Field> Flattener { } } +// This finder looks for identifiers that were not defined in some block of statements +// These identifiers are used as function arguments when moving witness assignment expression +// to a zir function. +// +// Example: +// def main(field a, field mut b) -> field { +// asm { +// b <== a * a; +// } +// return b; +// } +// is turned into +// def main(field a, field mut b) -> field { +// asm { +// b <-- (field a) -> field { +// return a * a; +// } +// b == a * a; +// } +// return b; +// } #[derive(Default)] pub struct ArgumentFinder<'ast, T> { pub identifiers: HashMap, zir::Type>, diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index a1c1764f0..e8022ed6f 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -12,7 +12,7 @@ use num_bigint::BigUint; use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; use std::fmt; -use std::ops::{BitAnd, BitOr, BitXor, Mul, Shr, Sub}; +use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Sub}; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::result_folder::*; use zokrates_ast::typed::types::Type; @@ -402,7 +402,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { true => { let r: Option> = match embed_call.embed { FlatEmbed::FieldToBoolUnsafe => Ok(None), // todo - FlatEmbed::BoolToField => Ok(None), // todo FlatEmbed::BitArrayLe => Ok(None), // todo FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits( &embed_call.arguments, @@ -874,6 +873,12 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { T::try_from(n1.to_biguint().bitxor(n2.to_biguint())).unwrap(), )) } + (FieldElementExpression::Number(n), e) + | (e, FieldElementExpression::Number(n)) + if n == T::from(0) => + { + Ok(e) + } (e1, e2) if e1.eq(&e2) => Ok(FieldElementExpression::Number(T::from(0))), (e1, e2) => Ok(FieldElementExpression::Xor(box e1, box e2)), } @@ -948,8 +953,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { let mask: BigUint = two.pow(T::get_required_bits()).sub(1usize); Ok(FieldElementExpression::Number( - T::try_from(n.to_biguint().mul(two.pow(by as usize)).bitand(mask)) - .unwrap(), + T::try_from(n.to_biguint().shl(by as usize).bitand(mask)).unwrap(), )) } (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 1a026b178..298166bf3 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -2,7 +2,7 @@ use num::traits::Pow; use num_bigint::BigUint; use std::collections::HashMap; use std::fmt; -use std::ops::{BitAnd, BitOr, BitXor, Mul, Shr, Sub}; +use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Sub}; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, Id, @@ -334,8 +334,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { let mask: BigUint = two.pow(T::get_required_bits()).sub(1usize); Ok(FieldElementExpression::Number( - T::try_from(n.to_biguint().mul(two.pow(by as usize)).bitand(mask)) - .unwrap(), + T::try_from(n.to_biguint().shl(by as usize).bitand(mask)).unwrap(), )) } (e, by) => Ok(FieldElementExpression::LeftShift(box e, box by)), diff --git a/zokrates_ast/src/common/embed.rs b/zokrates_ast/src/common/embed.rs index 3f961cd9a..58294142f 100644 --- a/zokrates_ast/src/common/embed.rs +++ b/zokrates_ast/src/common/embed.rs @@ -32,7 +32,6 @@ cfg_if::cfg_if! { #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy, PartialOrd, Ord, Serialize, Deserialize)] pub enum FlatEmbed { FieldToBoolUnsafe, - BoolToField, BitArrayLe, Unpack, U8ToBits, @@ -55,9 +54,6 @@ impl FlatEmbed { FlatEmbed::FieldToBoolUnsafe => UnresolvedSignature::new() .inputs(vec![UnresolvedType::FieldElement.into()]) .output(UnresolvedType::Boolean.into()), - FlatEmbed::BoolToField => UnresolvedSignature::new() - .inputs(vec![UnresolvedType::Boolean.into()]) - .output(UnresolvedType::FieldElement.into()), FlatEmbed::BitArrayLe => UnresolvedSignature::new() .generics(vec![ConstantGenericNode::mock("N")]) .inputs(vec![ @@ -197,9 +193,6 @@ impl FlatEmbed { FlatEmbed::FieldToBoolUnsafe => DeclarationSignature::new() .inputs(vec![DeclarationType::FieldElement]) .output(DeclarationType::Boolean), - FlatEmbed::BoolToField => DeclarationSignature::new() - .inputs(vec![DeclarationType::Boolean]) - .output(DeclarationType::FieldElement), FlatEmbed::BitArrayLe => DeclarationSignature::new() .generics(vec![Some(DeclarationConstant::Generic( GenericIdentifier::with_name("N").with_index(0), @@ -307,7 +300,6 @@ impl FlatEmbed { pub fn id(&self) -> &'static str { match self { FlatEmbed::FieldToBoolUnsafe => "_FIELD_TO_BOOL_UNSAFE", - FlatEmbed::BoolToField => "_BOOL_TO_FIELD", FlatEmbed::BitArrayLe => "_BIT_ARRAY_LT", FlatEmbed::Unpack => "_UNPACK", FlatEmbed::U8ToBits => "_U8_TO_BITS", diff --git a/zokrates_ast/src/common/error.rs b/zokrates_ast/src/common/error.rs index 28c209f46..499ac97d4 100644 --- a/zokrates_ast/src/common/error.rs +++ b/zokrates_ast/src/common/error.rs @@ -3,7 +3,7 @@ use std::fmt; #[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)] pub enum RuntimeError { - UserConstraint, + SourceAssemblyConstraint, BellmanConstraint, BellmanOneBinding, BellmanInputBinding, @@ -50,7 +50,7 @@ impl RuntimeError { !matches!( self, - UserConstraint + SourceAssemblyConstraint | SourceAssertion(_) | Inverse | SelectRangeCheck @@ -65,7 +65,7 @@ impl fmt::Display for RuntimeError { use RuntimeError::*; let msg = match self { - UserConstraint => "User constraint is unsatisfied", + SourceAssemblyConstraint => "Source constraint is unsatisfied", BellmanConstraint => "Bellman constraint is unsatisfied", BellmanOneBinding => "Bellman ~one binding is unsatisfied", BellmanInputBinding => "Bellman input binding is unsatisfied", diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index 26247f596..915d9ceb6 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -20,7 +20,7 @@ pub enum Solver<'ast, T> { SnarkVerifyBls12377(usize), } -impl<'ast, T: fmt::Debug + fmt::Display> fmt::Display for Solver<'ast, T> { +impl<'ast, T: fmt::Debug> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Solver::Zir(_) => write!(f, "Zir(..)"), diff --git a/zokrates_ast/src/zir/lqc.rs b/zokrates_ast/src/zir/lqc.rs index 746bdc315..98b1c30ee 100644 --- a/zokrates_ast/src/zir/lqc.rs +++ b/zokrates_ast/src/zir/lqc.rs @@ -1,14 +1,17 @@ use crate::zir::{FieldElementExpression, Identifier}; use zokrates_field::Field; +pub type LinearTerm<'ast, T> = (T, Identifier<'ast>); +pub type QuadraticTerm<'ast, T> = (T, Identifier<'ast>, Identifier<'ast>); + #[derive(Clone, PartialEq, Hash, Eq, Debug, Default)] pub struct LinQuadComb<'ast, T> { // the constant terms pub constant: T, // the linear terms - pub linear: Vec<(T, Identifier<'ast>)>, + pub linear: Vec>, // the quadratic terms - pub quadratic: Vec<(T, Identifier<'ast>, Identifier<'ast>)>, + pub quadratic: Vec>, } impl<'ast, T: Field> std::ops::Add for LinQuadComb<'ast, T> { diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index b793e4d67..ba7a0e3e8 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -166,7 +166,8 @@ pub enum ZirStatement<'ast, T> { FormatString, Vec<(ConcreteType, Vec>)>, ), - Assembly(#[serde(borrow)] Vec>), + #[serde(borrow)] + Assembly(Vec>), } impl<'ast, T: fmt::Display> fmt::Display for ZirStatement<'ast, T> { diff --git a/zokrates_cli/examples/book/assembly/bool_to_field.zok b/zokrates_cli/examples/book/assembly/bool_to_field.zok index 4c1284b03..48f0e0176 100644 --- a/zokrates_cli/examples/book/assembly/bool_to_field.zok +++ b/zokrates_cli/examples/book/assembly/bool_to_field.zok @@ -1,8 +1,6 @@ -from "EMBED" import bool_to_field; - def main(bool x) -> field { // `x` is constrained by the compiler automatically so we can safely - // treat it as `field` with no extra cost - field out = bool_to_field(x); + // convert to `field` with no extra cost + field out = x ? 1 : 0; return out; } \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/division.zok b/zokrates_cli/examples/book/assembly/division.zok index c38e18ee2..b9f65af22 100644 --- a/zokrates_cli/examples/book/assembly/division.zok +++ b/zokrates_cli/examples/book/assembly/division.zok @@ -1,7 +1,11 @@ -def main(field a, field b) { +def main(field a, field b) -> field { field mut c = 0; + field mut invb = 0; asm { - c <-- a / b; + invb <-- b == 0 ? 0 : 1 / b; + invb * b === 1; + c <-- invb * a; a === b * c; } + return c; } \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/field_to_bool.zok b/zokrates_cli/examples/book/assembly/field_to_bool.zok index b213b346f..2e9f05523 100644 --- a/zokrates_cli/examples/book/assembly/field_to_bool.zok +++ b/zokrates_cli/examples/book/assembly/field_to_bool.zok @@ -5,7 +5,8 @@ def main(field x) -> bool { asm { x * (x - 1) === 0; } - // we can treat `x` as `bool` afterwards, as we constrained it properly + // we can convert `x` to `bool` afterwards, as we constrained it properly + // if we failed to constrain `x` to `0` or `1`, the call to `field_to_bool_unsafe` introduces undefined behavior // `field_to_bool_unsafe` call does not produce any extra constraints bool out = field_to_bool_unsafe(x); return out; diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index a2b857a91..a5f8a31f8 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -259,7 +259,7 @@ mod tests { let interpreter = zokrates_interpreter::Interpreter::default(); - let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0u32)]); + let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]); assert!(res.is_err()); } diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index 253173916..ba3b92da0 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -1050,7 +1050,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { match embed { FlatEmbed::FieldToBoolUnsafe => vec![params.pop().unwrap()], - FlatEmbed::BoolToField => vec![params.pop().unwrap()], FlatEmbed::U8ToBits => self.u_to_bits(params.pop().unwrap(), 8.into()), FlatEmbed::U16ToBits => self.u_to_bits(params.pop().unwrap(), 16.into()), FlatEmbed::U32ToBits => self.u_to_bits(params.pop().unwrap(), 32.into()), @@ -2255,7 +2254,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened.push_back(FlatStatement::Condition( lhs, rhs, - RuntimeError::UserConstraint, + RuntimeError::SourceAssemblyConstraint, )); } } diff --git a/zokrates_core/src/imports.rs b/zokrates_core/src/imports.rs index 4bdf49407..f7fa95f13 100644 --- a/zokrates_core/src/imports.rs +++ b/zokrates_core/src/imports.rs @@ -151,10 +151,6 @@ impl Importer { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::FieldToBoolUnsafe), }, - "bool_to_field" => SymbolDeclaration { - id: symbol.get_alias(), - symbol: Symbol::Flat(FlatEmbed::BoolToField), - }, "bit_array_le" => SymbolDeclaration { id: symbol.get_alias(), symbol: Symbol::Flat(FlatEmbed::BitArrayLe), diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index b1ef92866..70bde5997 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1804,10 +1804,9 @@ impl<'ast, T: Field> Checker<'ast, T> { let e = match checked_e { TypedExpression::FieldElement(e) => Ok(e), TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), - _ => Err(ErrorInner { + e => Err(ErrorInner { pos: Some(pos), - message: "Only field element expressions are allowed in the assembly block" - .to_string(), + message: format!("The right hand side of an assembly assignment must be of type field, found {}", e.get_type()) }), }?; @@ -1819,9 +1818,9 @@ impl<'ast, T: Field> Checker<'ast, T> { TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()), TypedAssemblyStatement::Constraint(assignee.into(), e), ]), - _ => Err(ErrorInner { + ty => Err(ErrorInner { pos: Some(pos), - message: "Assignee must be of type `field`".to_string(), + message: format!("Assignee must be of type field, found {}", ty), }), } } @@ -1849,10 +1848,13 @@ impl<'ast, T: Field> Checker<'ast, T> { FieldElementExpression::try_from_int(lhs).unwrap(), FieldElementExpression::try_from_int(rhs).unwrap(), )), - _ => Err(ErrorInner { + (e1, e2) => Err(ErrorInner { pos: Some(pos), - message: "Only field element expressions are allowed in the assembly block" - .to_string(), + message: format!( + "Assembly constraint expected expressions of type field, found {}, {}", + e1.get_type(), + e2.get_type() + ), }), }?; @@ -1873,14 +1875,12 @@ impl<'ast, T: Field> Checker<'ast, T> { Statement::Assembly(statements) => { let mut checked_statements = vec![]; for s in statements { - checked_statements.push( + checked_statements.extend( self.check_assembly_statement(s, module_id, types) .map_err(|e| vec![e])?, ); } - Ok(TypedStatement::Assembly( - checked_statements.into_iter().flatten().collect(), - )) + Ok(TypedStatement::Assembly(checked_statements)) } Statement::Log(l, expressions) => { let l = FormatString::from(l); diff --git a/zokrates_core_test/tests/tests/assembly/binary_check.json b/zokrates_core_test/tests/tests/assembly/binary_check.json index 53912338b..0973db36c 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_check.json +++ b/zokrates_core_test/tests/tests/assembly/binary_check.json @@ -29,7 +29,7 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "UserConstraint" + "error": "SourceAssemblyConstraint" } } } diff --git a/zokrates_core_test/tests/tests/assembly/bitify.json b/zokrates_core_test/tests/tests/assembly/bitify.json index ba04a1e67..19beb2bd3 100644 --- a/zokrates_core_test/tests/tests/assembly/bitify.json +++ b/zokrates_core_test/tests/tests/assembly/bitify.json @@ -48,7 +48,7 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "UserConstraint" + "error": "SourceAssemblyConstraint" } } } diff --git a/zokrates_core_test/tests/tests/assembly/division.json b/zokrates_core_test/tests/tests/assembly/division.json index 7478326fd..9e3e511a2 100644 --- a/zokrates_core_test/tests/tests/assembly/division.json +++ b/zokrates_core_test/tests/tests/assembly/division.json @@ -1,6 +1,6 @@ { "curves": ["Bn128"], - "max_constraint_count": 2, + "max_constraint_count": 3, "tests": [ { "input": { @@ -14,11 +14,13 @@ }, { "input": { - "values": ["4", "0"] + "values": ["0", "0"] }, "output": { "Err": { - "Solver": "Assertion failed: `Division by zero`" + "UnsatisfiedConstraint": { + "error": "SourceAssemblyConstraint" + } } } } diff --git a/zokrates_core_test/tests/tests/assembly/division.zok b/zokrates_core_test/tests/tests/assembly/division.zok index 35669ffd6..b9f65af22 100644 --- a/zokrates_core_test/tests/tests/assembly/division.zok +++ b/zokrates_core_test/tests/tests/assembly/division.zok @@ -1,8 +1,11 @@ -def main(field x, field y) -> field { - field mut z = 0; +def main(field a, field b) -> field { + field mut c = 0; + field mut invb = 0; asm { - z <-- x / y; - z * y === x; + invb <-- b == 0 ? 0 : 1 / b; + invb * b === 1; + c <-- invb * a; + a === b * c; } - return z; + return c; } \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/embed/bool_to_field.json b/zokrates_core_test/tests/tests/embed/bool_to_field.json deleted file mode 100644 index 5e78b2981..000000000 --- a/zokrates_core_test/tests/tests/embed/bool_to_field.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "curves": ["Bn128"], - "max_constraint_count": 2, - "tests": [ - { - "input": { - "values": [false] - }, - "output": { - "Ok": { - "value": "0" - } - } - }, - { - "input": { - "values": [true] - }, - "output": { - "Ok": { - "value": "1" - } - } - } - ] -} diff --git a/zokrates_core_test/tests/tests/embed/bool_to_field.zok b/zokrates_core_test/tests/tests/embed/bool_to_field.zok deleted file mode 100644 index 457ac06dc..000000000 --- a/zokrates_core_test/tests/tests/embed/bool_to_field.zok +++ /dev/null @@ -1,6 +0,0 @@ -from "EMBED" import bool_to_field; - -def main(bool x) -> field { - field out = bool_to_field(x); - return out; -} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/embed/field_to_bool.json b/zokrates_core_test/tests/tests/embed/field_to_bool.json index d24af7e06..b8357755a 100644 --- a/zokrates_core_test/tests/tests/embed/field_to_bool.json +++ b/zokrates_core_test/tests/tests/embed/field_to_bool.json @@ -29,7 +29,7 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "UserConstraint" + "error": "SourceAssemblyConstraint" } } } diff --git a/zokrates_test/tests/out_of_range.rs b/zokrates_test/tests/out_of_range.rs index 781bae761..ea2800252 100644 --- a/zokrates_test/tests/out_of_range.rs +++ b/zokrates_test/tests/out_of_range.rs @@ -42,7 +42,7 @@ fn lt_field() { assert!(interpreter .execute( res.prog(), - &[Bn128Field::from(10000u32), Bn128Field::from(5555u32)] + &[Bn128Field::from(10000), Bn128Field::from(5555)] ) .is_err()); } @@ -78,7 +78,7 @@ fn lt_uint() { assert!(interpreter .execute( res.prog(), - &[Bn128Field::from(10000u32), Bn128Field::from(5555u32)] + &[Bn128Field::from(10000), Bn128Field::from(5555)] ) .is_err()); } @@ -123,7 +123,7 @@ fn unpack256() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(res.prog(), &[Bn128Field::from(0u32)]) + .execute(res.prog(), &[Bn128Field::from(0)]) .is_err()); } @@ -167,6 +167,6 @@ fn unpack256_unchecked() { let interpreter = Interpreter::try_out_of_range(); assert!(interpreter - .execute(res.prog(), &[Bn128Field::from(0u32)]) + .execute(res.prog(), &[Bn128Field::from(0)]) .is_ok()); } From fbfc20c4e62142efcb9ddde886c6629164e38e71 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 28 Nov 2022 20:25:05 +0100 Subject: [PATCH 39/94] improvements 2 --- .../src/flatten_complex_types.rs | 2 +- zokrates_ast/src/untyped/from_ast.rs | 2 +- zokrates_book/src/language/assembly.md | 8 -- .../examples/book/assembly/bool_to_field.zok | 6 - zokrates_core/src/semantics.rs | 103 ++++++------------ .../tests/tests/assembly/binary_sub.zok | 2 + .../tests/tests/assembly/gates/not.zok | 2 +- .../tests/tests/assembly/sha256_maj.json | 61 ++++++++++- .../tests/tests/assembly/sha256_maj.zok | 22 ++-- zokrates_parser/src/zokrates.pest | 5 +- zokrates_pest_ast/src/lib.rs | 25 ++--- 11 files changed, 125 insertions(+), 113 deletions(-) delete mode 100644 zokrates_cli/examples/book/assembly/bool_to_field.zok diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 56bb55c97..6ad4725fd 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -551,7 +551,7 @@ fn fold_assembly_statement<'ast, T: Field>( .into_iter() .map(|(id, ty)| zir::Parameter { id: zir::Variable::with_id_and_type(id, ty), - private: false, + private: true, }) .collect(), statements: statements_buffer, diff --git a/zokrates_ast/src/untyped/from_ast.rs b/zokrates_ast/src/untyped/from_ast.rs index df8b66ea7..88c12d6ce 100644 --- a/zokrates_ast/src/untyped/from_ast.rs +++ b/zokrates_ast/src/untyped/from_ast.rs @@ -353,7 +353,7 @@ impl<'ast> From> for untyped::StatementNode<'ast> untyped::AssemblyStatement::Assignment( a.assignee.into(), a.expression.into(), - matches!(a.operator, pest::AssignmentOperator::AssignConstrain), + matches!(a.operator, pest::AssignmentOperator::AssignConstrain(_)), ) .span(a.span) } diff --git a/zokrates_book/src/language/assembly.md b/zokrates_book/src/language/assembly.md index a6782a6d5..aa37ddab7 100644 --- a/zokrates_book/src/language/assembly.md +++ b/zokrates_book/src/language/assembly.md @@ -72,12 +72,4 @@ This call is unsafe because it is the responsibility of the user to constrain th ```zok {{#include ../../../zokrates_cli/examples/book/assembly/field_to_bool.zok}} -``` - -### bool_to_field - -This call is safe as `bool` types are constrained by the compiler: - -```zok -{{#include ../../../zokrates_cli/examples/book/assembly/bool_to_field.zok}} ``` \ No newline at end of file diff --git a/zokrates_cli/examples/book/assembly/bool_to_field.zok b/zokrates_cli/examples/book/assembly/bool_to_field.zok deleted file mode 100644 index 48f0e0176..000000000 --- a/zokrates_cli/examples/book/assembly/bool_to_field.zok +++ /dev/null @@ -1,6 +0,0 @@ -def main(bool x) -> field { - // `x` is constrained by the compiler automatically so we can safely - // convert to `field` with no extra cost - field out = x ? 1 : 0; - return out; -} \ No newline at end of file diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 70bde5997..f61e07557 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -283,11 +283,12 @@ struct Scope<'ast, T> { impl<'ast, T: Field> Scope<'ast, T> { // insert into the scope and return whether we are shadowing an existing variable - fn insert( + fn insert>>( &mut self, - id: SourceIdentifier<'ast>, + id: I, info: IdentifierInfo<'ast, T, CoreIdentifier<'ast>>, ) -> bool { + let id = id.into(); let existed = self .map .get(&id) @@ -299,12 +300,12 @@ impl<'ast, T: Field> Scope<'ast, T> { } /// get the current version of this variable - fn get( + fn get>>( &self, - id: &SourceIdentifier<'ast>, + id: I, ) -> Option>> { self.map - .get(id) + .get(&id.into()) .and_then(|versions| versions.values().next_back().cloned()) } @@ -700,7 +701,7 @@ impl<'ast, T: Field> Checker<'ast, T> { is_mutable: false, }; assert_eq!(self.scope.level, 0); - assert!(!self.scope.insert(id.into(), info)); + assert!(!self.scope.insert(id, info)); assert!(state .constants .entry(module_id.to_path_buf()) @@ -896,7 +897,7 @@ impl<'ast, T: Field> Checker<'ast, T> { is_mutable: false, }; assert_eq!(self.scope.level, 0); - assert!(!self.scope.insert(id.into(), info)); + assert!(!self.scope.insert(id, info)); state .constants @@ -1084,14 +1085,14 @@ impl<'ast, T: Field> Checker<'ast, T> { Ok(var) } - fn id_in_this_scope(&self, id: SourceIdentifier<'ast>) -> CoreIdentifier<'ast> { + fn id_in_this_scope>>(&self, id: I) -> CoreIdentifier<'ast> { // in the semantic checker, 0 is top level, 1 is function level. For shadowing, we start with 0 at function level // hence the offset of 1 assert!( self.scope.level > 0, "CoreIdentifier cannot be declared in the global scope" ); - CoreIdentifier::from(ShadowedIdentifier::shadow(id, self.scope.level - 1)) + CoreIdentifier::from(ShadowedIdentifier::shadow(id.into(), self.scope.level - 1)) } fn check_function( @@ -1132,18 +1133,12 @@ impl<'ast, T: Field> Checker<'ast, T> { // for declaration signatures, generics cannot be ignored generics.0.insert( generic.clone(), - UExpression::identifier( - self.id_in_this_scope(generic.name().into()).into(), - ) - .annotate(UBitwidth::B32), + UExpression::identifier(self.id_in_this_scope(generic.name()).into()) + .annotate(UBitwidth::B32), ); //we don't have to check for conflicts here, because this was done when checking the signature - self.insert_into_scope( - generic.name().into(), - Type::Uint(UBitwidth::B32), - false, - ); + self.insert_into_scope(generic.name(), Type::Uint(UBitwidth::B32), false); } for (arg, decl_ty) in funct.arguments.into_iter().zip(s.inputs.iter()) { @@ -1162,7 +1157,7 @@ impl<'ast, T: Field> Checker<'ast, T> { } let decl_v = DeclarationVariable::new( - self.id_in_this_scope(arg.id.value.id.into()), + self.id_in_this_scope(arg.id.value.id), decl_ty.clone(), arg.id.value.is_mutable, ); @@ -1179,7 +1174,7 @@ impl<'ast, T: Field> Checker<'ast, T> { ty, is_mutable, }; - match self.scope.insert(id.into(), info) { + match self.scope.insert(id, info) { false => {} true => { errors.push(ErrorInner { @@ -1669,10 +1664,10 @@ impl<'ast, T: Field> Checker<'ast, T> { .map_err(|e| vec![e])?; // insert into the scope and ignore whether shadowing happened - self.insert_into_scope(v.value.id.into(), ty.clone(), v.value.is_mutable); + self.insert_into_scope(v.value.id, ty.clone(), v.value.is_mutable); Ok(Variable::new( - self.id_in_this_scope(v.value.id.into()), + self.id_in_this_scope(v.value.id), ty, v.value.is_mutable, )) @@ -2004,10 +1999,10 @@ impl<'ast, T: Field> Checker<'ast, T> { .map_err(|e| vec![e])?; // insert the lhs into the scope and ignore whether shadowing happened - self.insert_into_scope(var.value.id.into(), var_ty.clone(), var.value.is_mutable); + self.insert_into_scope(var.value.id, var_ty.clone(), var.value.is_mutable); let var = Variable::new( - self.id_in_this_scope(var.value.id.into()), + self.id_in_this_scope(var.value.id), var_ty.clone(), var.value.is_mutable, ); @@ -2140,7 +2135,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = assignee.pos(); // check that the assignee is declared match assignee.value { - Assignee::Identifier(variable_name) => match self.scope.get(&variable_name.into()) { + Assignee::Identifier(variable_name) => match self.scope.get(&*variable_name) { Some(info) => match info.is_mutable { false => Err(ErrorInner { pos: Some(assignee.pos()), @@ -2449,7 +2444,7 @@ impl<'ast, T: Field> Checker<'ast, T> { Expression::BooleanConstant(b) => Ok(BooleanExpression::Value(b).into()), Expression::Identifier(name) => { // check that `id` is defined in the scope - match self.scope.get(&name.into()) { + match self.scope.get(&*name) { Some(info) => { let id = info.id; match info.ty.clone() { @@ -3715,9 +3710,9 @@ impl<'ast, T: Field> Checker<'ast, T> { } } - fn insert_into_scope( + fn insert_into_scope>>( &mut self, - id: SourceIdentifier<'ast>, + id: I, ty: Type<'ast, T>, is_mutable: bool, ) -> bool { @@ -4596,7 +4591,7 @@ mod tests { let mut scope = Scope::default(); scope.insert( - std::borrow::Cow::Borrowed("b"), + "b", IdentifierInfo { id: "b".into(), ty: Type::FieldElement, @@ -4843,19 +4838,12 @@ mod tests { let for_statements_checked = vec![TypedStatement::definition( typed::Variable::uint( - CoreIdentifier::Source(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("a"), - 1, - )), + CoreIdentifier::Source(ShadowedIdentifier::shadow("a".into(), 1)), UBitwidth::B32, ) .into(), UExpression::identifier( - CoreIdentifier::Source(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("i"), - 1, - )) - .into(), + CoreIdentifier::Source(ShadowedIdentifier::shadow("i".into(), 1)).into(), ) .annotate(UBitwidth::B32) .into(), @@ -4864,10 +4852,7 @@ mod tests { let foo_statements_checked = vec![ TypedStatement::For( typed::Variable::uint( - CoreIdentifier::Source(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("i"), - 1, - )), + CoreIdentifier::Source(ShadowedIdentifier::shadow("i".into(), 1)), UBitwidth::B32, ), 0u32.into(), @@ -5413,14 +5398,7 @@ mod tests { &TypeMap::new(), ); assert!(s2_checked.is_ok()); - assert_eq!( - checker - .scope - .get(&std::borrow::Cow::Borrowed("a")) - .unwrap() - .ty, - DeclarationType::Boolean - ); + assert_eq!(checker.scope.get("a").unwrap().ty, DeclarationType::Boolean); } #[test] @@ -5478,10 +5456,7 @@ mod tests { let expected = vec![ TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("a"), - 0, - )), + CoreIdentifier::from(ShadowedIdentifier::shadow("a".into(), 0)), Type::FieldElement, true, ) @@ -5490,10 +5465,7 @@ mod tests { ), TypedStatement::For( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("i"), - 1, - )), + CoreIdentifier::from(ShadowedIdentifier::shadow("i".into(), 1)), Type::Uint(UBitwidth::B32), false, ), @@ -5502,10 +5474,7 @@ mod tests { vec![ TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("a"), - 0, - )), + CoreIdentifier::from(ShadowedIdentifier::shadow("a".into(), 0)), Type::FieldElement, true, ) @@ -5514,10 +5483,7 @@ mod tests { ), TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("a"), - 1, - )), + CoreIdentifier::from(ShadowedIdentifier::shadow("a".into(), 1)), Type::FieldElement, false, ) @@ -5528,10 +5494,7 @@ mod tests { ), TypedStatement::definition( typed::Variable::new( - CoreIdentifier::from(ShadowedIdentifier::shadow( - std::borrow::Cow::Borrowed("a"), - 0, - )), + CoreIdentifier::from(ShadowedIdentifier::shadow("a".into(), 0)), Type::FieldElement, true, ) diff --git a/zokrates_core_test/tests/tests/assembly/binary_sub.zok b/zokrates_core_test/tests/tests/assembly/binary_sub.zok index 58a60072b..88d60780d 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_sub.zok +++ b/zokrates_core_test/tests/tests/assembly/binary_sub.zok @@ -1,3 +1,5 @@ +// Subtraction of two binary numbers (comprising only two digits, 0 and 1) +// Precondition: caller has to ensure `a` and `b` are constrained by a binary check def bin_sub(field[N] a, field[N] b) -> field[N] { field mut lin = 2**N; field mut lout = 0; diff --git a/zokrates_core_test/tests/tests/assembly/gates/not.zok b/zokrates_core_test/tests/tests/assembly/gates/not.zok index 469e30711..fa7cdd76e 100644 --- a/zokrates_core_test/tests/tests/assembly/gates/not.zok +++ b/zokrates_core_test/tests/tests/assembly/gates/not.zok @@ -1,7 +1,7 @@ def main(field inp) -> field { field mut out = 0; asm { - out <== 1 + inp - 2*inp; + out <== 1 - inp; } return out; } \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/sha256_maj.json b/zokrates_core_test/tests/tests/assembly/sha256_maj.json index a2b04fe80..f67b210a6 100644 --- a/zokrates_core_test/tests/tests/assembly/sha256_maj.json +++ b/zokrates_core_test/tests/tests/assembly/sha256_maj.json @@ -1,5 +1,62 @@ { "curves": ["Bn128"], - "max_constraint_count": 2, - "tests": [] + "max_constraint_count": 6, + "tests": [ + { + "input": { + "values": [ + ["0", "1"], + ["1", "0"], + ["1", "1"] + ] + }, + "output": { + "Ok": { + "value": ["1", "1"] + } + } + }, + { + "input": { + "values": [ + ["1", "0"], + ["1", "0"], + ["1", "0"] + ] + }, + "output": { + "Ok": { + "value": ["1", "0"] + } + } + }, + { + "input": { + "values": [ + ["1", "0"], + ["0", "1"], + ["0", "0"] + ] + }, + "output": { + "Ok": { + "value": ["0", "0"] + } + } + }, + { + "input": { + "values": [ + ["1", "0"], + ["1", "0"], + ["1", "0"] + ] + }, + "output": { + "Ok": { + "value": ["1", "0"] + } + } + } + ] } diff --git a/zokrates_core_test/tests/tests/assembly/sha256_maj.zok b/zokrates_core_test/tests/tests/assembly/sha256_maj.zok index ecd5b87d8..9d3f7d4e1 100644 --- a/zokrates_core_test/tests/tests/assembly/sha256_maj.zok +++ b/zokrates_core_test/tests/tests/assembly/sha256_maj.zok @@ -1,9 +1,17 @@ -// Maj function for sha256 -// (a & b) ^ (a & c) ^ (b & c) -def main(field a, field b, field c) { - field mut out = 0; - field bc = b * c; - asm { - out <== a * (b + c - 2*bc) + bc; +// Maj function for sha256 => (a & b) ^ (a & c) ^ (b & c) +// Precondition: caller has to ensure inputs are constrained by a binary check +def maj(field[N] a, field[N] b, field[N] c) -> field[N] { + field[N] mut out = [0; N]; + field[N] mut bc = [0; N]; + for u32 i in 0..N { + asm { + bc[i] <== b[i] * c[i]; + out[i] <== a[i] * (b[i] + c[i] - 2*bc[i]) + bc[i]; + } } + return out; +} + +def main(field[2] a, field[2] b, field[2] c) -> field[2] { + return maj(a, b, c); } \ No newline at end of file diff --git a/zokrates_parser/src/zokrates.pest b/zokrates_parser/src/zokrates.pest index f6ca4e43d..af4998e09 100644 --- a/zokrates_parser/src/zokrates.pest +++ b/zokrates_parser/src/zokrates.pest @@ -68,11 +68,12 @@ assertion_statement = {"assert" ~ "(" ~ expression ~ ("," ~ quoted_string)? ~ ") op_asm_assign = @{"<--"} op_asm_assign_constrain = @{"<=="} +op_asm = { op_asm_assign | op_asm_assign_constrain } -asm_assignment = { assignee ~ (op_asm_assign | op_asm_assign_constrain) ~ expression } +asm_assignment = { assignee ~ op_asm ~ expression } asm_constraint = { expression ~ "===" ~ expression } -asm_statement_inner = { (asm_assignment | asm_constraint) ~ semicolon ~ NEWLINE* } +asm_statement_inner = { (asm_assignment | asm_constraint) ~ semicolon } asm_statement = { "asm" ~ "{" ~ NEWLINE* ~ asm_statement_inner* ~ NEWLINE* ~ "}" } typed_identifier_or_assignee = { typed_identifier | assignee } diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 9f37a90bc..c5ce66c23 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -433,25 +433,20 @@ mod ast { pub span: Span<'ast>, } - #[derive(Debug, PartialEq, Eq, Clone)] + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::op_asm))] pub enum AssignmentOperator { - Assign, - AssignConstrain, + Assign(AssignOperator), + AssignConstrain(AssignConstrainOperator), } - impl<'ast> FromPest<'ast> for AssignmentOperator { - type Rule = Rule; - type FatalError = Void; + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::op_asm_assign))] + pub struct AssignOperator; - fn from_pest(pest: &mut Pairs<'ast, Rule>) -> Result> { - let pair = pest.next().ok_or(::from_pest::ConversionError::NoMatch)?; - match pair.as_rule() { - Rule::op_asm_assign => Ok(AssignmentOperator::Assign), - Rule::op_asm_assign_constrain => Ok(AssignmentOperator::AssignConstrain), - _ => Err(ConversionError::NoMatch), - } - } - } + #[derive(Debug, FromPest, PartialEq, Clone)] + #[pest_ast(rule(Rule::op_asm_assign_constrain))] + pub struct AssignConstrainOperator; #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::asm_assignment))] From 33a3043fe499cdcb64334fe5a0d62574dec3542b Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 29 Nov 2022 17:26:27 +0100 Subject: [PATCH 40/94] implement propagation for assembly blocks. wip --- zokrates_analysis/src/assembly_transformer.rs | 8 +- .../src/flatten_complex_types.rs | 7 +- zokrates_analysis/src/propagation.rs | 118 +++++++++++++----- zokrates_analysis/src/reducer/shallow_ssa.rs | 4 +- zokrates_analysis/src/zir_propagation.rs | 68 ++++++++-- zokrates_ast/src/typed/folder.rs | 15 ++- zokrates_ast/src/typed/result_folder.rs | 18 ++- zokrates_ast/src/zir/folder.rs | 14 +-- zokrates_ast/src/zir/mod.rs | 15 +-- zokrates_ast/src/zir/result_folder.rs | 20 +-- zokrates_codegen/src/lib.rs | 16 +-- zokrates_core/src/semantics.rs | 4 +- .../propagation/array_write_constant.json | 17 +++ .../propagation/array_write_constant.zok | 9 ++ .../propagation/array_write_variable.json | 18 +++ .../propagation/array_write_variable.zok | 9 ++ .../assembly/propagation/definition.json | 5 + .../tests/assembly/propagation/definition.zok | 8 ++ .../tests/assembly/propagation/empty.json | 5 + .../tests/assembly/propagation/empty.zok | 5 + .../assembly/propagation/redefinition.json | 6 + .../assembly/propagation/redefinition.zok | 10 ++ zokrates_pest_ast/src/lib.rs | 6 +- 23 files changed, 302 insertions(+), 103 deletions(-) create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.zok create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.zok create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/definition.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/definition.zok create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/empty.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/empty.zok create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/redefinition.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/redefinition.zok diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index 3d1e95675..43999c329 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -31,9 +31,9 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { fn fold_assembly_statement( &mut self, s: ZirAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { match s { - ZirAssemblyStatement::Assignment(_, _) => Ok(s), + ZirAssemblyStatement::Assignment(_, _) => Ok(vec![s]), ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = self.fold_field_expression(lhs)?; let rhs = self.fold_field_expression(rhs)?; @@ -53,7 +53,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { }; match is_quadratic { - true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs)), + true => Ok(vec![ZirAssemblyStatement::Constraint(lhs, rhs)]), false => { let sub = FieldElementExpression::Sub(box lhs, box rhs); let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { @@ -156,7 +156,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { .fold_field_expression(rhs) .map_err(|e| Error(e.to_string()))?; - Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) + Ok(vec![ZirAssemblyStatement::Constraint(lhs, rhs)]) } } } diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 6ad4725fd..4c10cf0ab 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -528,7 +528,10 @@ fn fold_assembly_statement<'ast, T: Field>( match s { typed::TypedAssemblyStatement::Assignment(a, e) => { let mut statements_buffer: Vec> = vec![]; - let a = f.fold_assignee(a); + let mut a = f.fold_assignee(a); + assert_eq!(a.len(), 1); + let a = a.pop().unwrap(); + assert_eq!(a.get_type(), zir::Type::FieldElement); let e = f.fold_field_expression(&mut statements_buffer, e); statements_buffer.push(zir::ZirStatement::Return(vec![ zir::ZirExpression::FieldElement(e), @@ -545,7 +548,7 @@ fn fold_assembly_statement<'ast, T: Field>( let function = zir::ZirFunction { signature: zir::types::Signature::default() .inputs(finder.identifiers.values().cloned().collect()) - .outputs(a.iter().map(|a| a.get_type()).collect()), + .outputs(vec![a.get_type()]), arguments: finder .identifiers .into_iter() diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index e8022ed6f..e41fa7d0f 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -212,42 +212,102 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { ) } + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> Result>, Self::Error> { + match s { + TypedAssemblyStatement::Assignment(assignee, expr) => { + let assignee = self.fold_assignee(assignee)?; + let expr = self.fold_field_expression(expr)?; + + let expr = TypedExpression::from(expr); + + if expr.is_constant() { + match assignee { + TypedAssignee::Identifier(var) => { + let expr = expr.into_canonical_constant(); + + assert!(self.constants.insert(var.id, expr).is_none()); + + Ok(vec![]) + } + assignee => match self.try_get_constant_mut(&assignee) { + Ok((_, c)) => { + *c = expr.into_canonical_constant(); + Ok(vec![]) + } + Err(v) => match self.constants.remove(&v.id) { + // invalidate the cache for this identifier, and define the latest + // version of the constant in the program, if any + Some(c) => Ok(vec![ + TypedAssemblyStatement::Assignment(v.clone().into(), c.into()), + TypedAssemblyStatement::Assignment(assignee, expr.into()), + ]), + None => Ok(vec![TypedAssemblyStatement::Assignment( + assignee, + expr.into(), + )]), + }, + }, + } + } else { + // the expression being assigned is not constant, invalidate the cache + let v = self + .try_get_constant_mut(&assignee) + .map(|(v, _)| v) + .unwrap_or_else(|v| v); + + match self.constants.remove(&v.id) { + Some(c) => Ok(vec![ + TypedAssemblyStatement::Assignment(v.clone().into(), c.into()), + TypedAssemblyStatement::Assignment(assignee, expr.into()), + ]), + None => Ok(vec![TypedAssemblyStatement::Assignment( + assignee, + expr.into(), + )]), + } + } + } + TypedAssemblyStatement::Constraint(left, right) => { + let left = self.fold_field_expression(left)?; + let right = self.fold_field_expression(right)?; + + // a bit hacky, but we use a fake boolean expression to check this + let is_equal = + BooleanExpression::FieldEq(EqExpression::new(left.clone(), right.clone())); + let is_equal = self.fold_boolean_expression(is_equal)?; + + match is_equal { + BooleanExpression::Value(true) => Ok(vec![]), + BooleanExpression::Value(false) => Err(Error::AssertionFailed(format!( + "In asm block: `{} !== {}`", + left, right + ))), + _ => Ok(vec![TypedAssemblyStatement::Constraint(left, right)]), + } + } + } + } + fn fold_statement( &mut self, s: TypedStatement<'ast, T>, ) -> Result>, Error> { match s { TypedStatement::Assembly(statements) => { - let mut assembly_statement_buffer = vec![]; - let mut statement_buffer = vec![]; - - for s in statements { - match self.fold_assembly_statement(s)? { - TypedAssemblyStatement::Assignment(assignee, expr) => { - // invalidate the cache - let v = self - .try_get_constant_mut(&assignee) - .map(|(v, _)| v) - .unwrap_or_else(|v| v); - - match self.constants.remove(&v.id) { - Some(c) => { - statement_buffer.push(TypedStatement::Definition( - v.clone().into(), - c.into(), - )); - } - None => {} - } - assembly_statement_buffer - .push(TypedAssemblyStatement::Assignment(assignee, expr)); - } - s => assembly_statement_buffer.push(s), - } + let statements: Vec<_> = statements + .into_iter() + .map(|s| self.fold_assembly_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); + match statements.len() { + 0 => Ok(vec![]), + _ => Ok(vec![TypedStatement::Assembly(statements)]), } - - statement_buffer.push(TypedStatement::Assembly(assembly_statement_buffer)); - Ok(statement_buffer) } // propagation to the defined variable if rhs is a constant TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => { diff --git a/zokrates_analysis/src/reducer/shallow_ssa.rs b/zokrates_analysis/src/reducer/shallow_ssa.rs index 48199e860..585622486 100644 --- a/zokrates_analysis/src/reducer/shallow_ssa.rs +++ b/zokrates_analysis/src/reducer/shallow_ssa.rs @@ -127,7 +127,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { fn fold_assembly_statement( &mut self, s: TypedAssemblyStatement<'ast, T>, - ) -> TypedAssemblyStatement<'ast, T> { + ) -> Vec> { match s { TypedAssemblyStatement::Assignment(a, e) => { let e = self.fold_field_expression(e); @@ -138,7 +138,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { } a => fold_assignee(self, a), }; - TypedAssemblyStatement::Assignment(a, e) + vec![TypedAssemblyStatement::Assignment(a, e)] } s => fold_assembly_statement(self, s), } diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 298166bf3..e8b1cad5e 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -60,18 +60,55 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { fn fold_assembly_statement( &mut self, s: ZirAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { match s { - ZirAssemblyStatement::Assignment(assignees, function) => { - for a in &assignees { - self.constants.remove(&a.id); + ZirAssemblyStatement::Assignment(assignee, function) => { + let function = self.fold_function(function)?; + + if function.statements.len() == 1 { + let value = match &function.statements.last().unwrap() { + ZirStatement::Return(values) => { + assert_eq!(values.len(), 1); + match values[0].clone() { + ZirExpression::FieldElement(FieldElementExpression::Number(v)) => { + Some(v) + } + _ => None, + } + } + _ => None, + }; + + match value { + Some(v) => { + self.constants + .insert(assignee.id, FieldElementExpression::Number(v).into()); + Ok(vec![]) + } + None => Ok(vec![ZirAssemblyStatement::Assignment(assignee, function)]), + } + } else { + Ok(vec![ZirAssemblyStatement::Assignment(assignee, function)]) + } + } + ZirAssemblyStatement::Constraint(left, right) => { + let left = self.fold_field_expression(left)?; + let right = self.fold_field_expression(right)?; + + // a bit hacky, but we use a fake boolean expression to check this + let is_equal = BooleanExpression::FieldEq(box left.clone(), box right.clone()); + let is_equal = self.fold_boolean_expression(is_equal)?; + + match is_equal { + BooleanExpression::Value(true) => Ok(vec![]), + BooleanExpression::Value(false) => { + Err(Error::AssertionFailed(RuntimeError::SourceAssertion( + format!("In asm block: `{} !== {}`", left, right), + ))) + } + _ => Ok(vec![ZirAssemblyStatement::Constraint(left, right)]), } - Ok(ZirAssemblyStatement::Assignment( - assignees, - self.fold_function(function)?, - )) } - s => fold_assembly_statement(self, s), } } @@ -147,6 +184,19 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { self.fold_expression_list(list)?, )]) } + ZirStatement::Assembly(statements) => { + let statements: Vec<_> = statements + .into_iter() + .map(|s| self.fold_assembly_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); + match statements.len() { + 0 => Ok(vec![]), + _ => Ok(vec![ZirStatement::Assembly(statements)]), + } + } _ => fold_statement(self, s), } } diff --git a/zokrates_ast/src/typed/folder.rs b/zokrates_ast/src/typed/folder.rs index d2996ab2f..06f03f617 100644 --- a/zokrates_ast/src/typed/folder.rs +++ b/zokrates_ast/src/typed/folder.rs @@ -263,7 +263,7 @@ pub trait Folder<'ast, T: Field>: Sized { fn fold_assembly_statement( &mut self, s: TypedAssemblyStatement<'ast, T>, - ) -> TypedAssemblyStatement<'ast, T> { + ) -> Vec> { fold_assembly_statement(self, s) } @@ -525,15 +525,18 @@ pub fn fold_definition_rhs<'ast, T: Field, F: Folder<'ast, T>>( pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, s: TypedAssemblyStatement<'ast, T>, -) -> TypedAssemblyStatement<'ast, T> { +) -> Vec> { match s { TypedAssemblyStatement::Assignment(a, e) => { - TypedAssemblyStatement::Assignment(f.fold_assignee(a), f.fold_field_expression(e)) + vec![TypedAssemblyStatement::Assignment( + f.fold_assignee(a), + f.fold_field_expression(e), + )] } - TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( + TypedAssemblyStatement::Constraint(lhs, rhs) => vec![TypedAssemblyStatement::Constraint( f.fold_field_expression(lhs), f.fold_field_expression(rhs), - ), + )], } } @@ -564,7 +567,7 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( TypedStatement::Assembly(statements) => TypedStatement::Assembly( statements .into_iter() - .map(|s| f.fold_assembly_statement(s)) + .flat_map(|s| f.fold_assembly_statement(s)) .collect(), ), s => s, diff --git a/zokrates_ast/src/typed/result_folder.rs b/zokrates_ast/src/typed/result_folder.rs index b054779e0..852cfe7d3 100644 --- a/zokrates_ast/src/typed/result_folder.rs +++ b/zokrates_ast/src/typed/result_folder.rs @@ -389,7 +389,7 @@ pub trait ResultFolder<'ast, T: Field>: Sized { fn fold_assembly_statement( &mut self, s: TypedAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { fold_assembly_statement(self, s) } @@ -526,15 +526,18 @@ pub trait ResultFolder<'ast, T: Field>: Sized { pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( f: &mut F, s: TypedAssemblyStatement<'ast, T>, -) -> Result, F::Error> { +) -> Result>, F::Error> { Ok(match s { TypedAssemblyStatement::Assignment(a, e) => { - TypedAssemblyStatement::Assignment(f.fold_assignee(a)?, f.fold_field_expression(e)?) + vec![TypedAssemblyStatement::Assignment( + f.fold_assignee(a)?, + f.fold_field_expression(e)?, + )] } - TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( + TypedAssemblyStatement::Constraint(lhs, rhs) => vec![TypedAssemblyStatement::Constraint( f.fold_field_expression(lhs)?, f.fold_field_expression(rhs)?, - ), + )], }) } @@ -572,7 +575,10 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( statements .into_iter() .map(|s| f.fold_assembly_statement(s)) - .collect::, _>>()?, + .collect::, _>>()? + .into_iter() + .flatten() + .collect(), ), s => s, }; diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index 7a063dcb7..f00eca8fe 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -59,7 +59,7 @@ pub trait Folder<'ast, T: Field>: Sized { fn fold_assembly_statement( &mut self, s: ZirAssemblyStatement<'ast, T>, - ) -> ZirAssemblyStatement<'ast, T> { + ) -> Vec> { fold_assembly_statement(self, s) } @@ -145,17 +145,17 @@ pub trait Folder<'ast, T: Field>: Sized { pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( f: &mut F, s: ZirAssemblyStatement<'ast, T>, -) -> ZirAssemblyStatement<'ast, T> { +) -> Vec> { match s { - ZirAssemblyStatement::Assignment(assignees, function) => { - let assignees = assignees.into_iter().map(|a| f.fold_assignee(a)).collect(); + ZirAssemblyStatement::Assignment(assignee, function) => { + let assignees = f.fold_assignee(assignee); let function = f.fold_function(function); - ZirAssemblyStatement::Assignment(assignees, function) + vec![ZirAssemblyStatement::Assignment(assignees, function)] } ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = f.fold_field_expression(lhs); let rhs = f.fold_field_expression(rhs); - ZirAssemblyStatement::Constraint(lhs, rhs) + vec![ZirAssemblyStatement::Constraint(lhs, rhs)] } } } @@ -201,7 +201,7 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( ZirStatement::Assembly(statements) => ZirStatement::Assembly( statements .into_iter() - .map(|s| f.fold_assembly_statement(s)) + .flat_map(|s| f.fold_assembly_statement(s)) .collect(), ), }; diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index ba7a0e3e8..71b121e76 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -119,10 +119,7 @@ impl RuntimeError { #[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum ZirAssemblyStatement<'ast, T> { - Assignment( - #[serde(borrow)] Vec>, - ZirFunction<'ast, T>, - ), + Assignment(#[serde(borrow)] ZirAssignee<'ast>, ZirFunction<'ast, T>), Constraint( FieldElementExpression<'ast, T>, FieldElementExpression<'ast, T>, @@ -133,15 +130,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ZirAssemblyStatement::Assignment(ref lhs, ref rhs) => { - write!( - f, - "{} <-- {}", - lhs.iter() - .map(|a| a.id.to_string()) - .collect::>() - .join(", "), - rhs - ) + write!(f, "{} <-- {}", lhs, rhs) } ZirAssemblyStatement::Constraint(ref lhs, ref rhs) => { write!(f, "{} === {}", lhs, rhs) diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 912ad77bb..70a349013 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -64,7 +64,7 @@ pub trait ResultFolder<'ast, T: Field>: Sized { fn fold_assembly_statement( &mut self, s: ZirAssemblyStatement<'ast, T>, - ) -> Result, Self::Error> { + ) -> Result>, Self::Error> { fold_assembly_statement(self, s) } @@ -162,20 +162,17 @@ pub trait ResultFolder<'ast, T: Field>: Sized { pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( f: &mut F, s: ZirAssemblyStatement<'ast, T>, -) -> Result, F::Error> { +) -> Result>, F::Error> { Ok(match s { - ZirAssemblyStatement::Assignment(assignees, function) => { - let assignees = assignees - .into_iter() - .map(|a| f.fold_assignee(a)) - .collect::, _>>()?; + ZirAssemblyStatement::Assignment(assignee, function) => { + let assignee = f.fold_assignee(assignee)?; let function = f.fold_function(function)?; - ZirAssemblyStatement::Assignment(assignees, function) + vec![ZirAssemblyStatement::Assignment(assignee, function)] } ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = f.fold_field_expression(lhs)?; let rhs = f.fold_field_expression(rhs)?; - ZirAssemblyStatement::Constraint(lhs, rhs) + vec![ZirAssemblyStatement::Constraint(lhs, rhs)] } }) } @@ -238,7 +235,10 @@ pub fn fold_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( let statements = statements .into_iter() .map(|s| f.fold_assembly_statement(s)) - .collect::, _>>()?; + .collect::, _>>()? + .into_iter() + .flatten() + .collect(); ZirStatement::Assembly(statements) } }; diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index ba3b92da0..1c11a66cd 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -2229,16 +2229,12 @@ impl<'ast, T: Field> Flattener<'ast, T> { stat: ZirAssemblyStatement<'ast, T>, ) { match stat { - ZirAssemblyStatement::Assignment(assignees, function) => { - let outputs: Vec = assignees - .iter() - .map(|a| { - self.layout - .get(&a.id) - .cloned() - .unwrap_or_else(|| self.use_variable(a)) - }) - .collect(); + ZirAssemblyStatement::Assignment(assignee, function) => { + let outputs: Vec = vec![self + .layout + .get(&assignee.id) + .cloned() + .unwrap_or_else(|| self.use_variable(&assignee))]; let inputs: Vec> = function .arguments .iter() diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index f61e07557..d72599032 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -2135,7 +2135,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = assignee.pos(); // check that the assignee is declared match assignee.value { - Assignee::Identifier(variable_name) => match self.scope.get(&*variable_name) { + Assignee::Identifier(variable_name) => match self.scope.get(variable_name) { Some(info) => match info.is_mutable { false => Err(ErrorInner { pos: Some(assignee.pos()), @@ -2444,7 +2444,7 @@ impl<'ast, T: Field> Checker<'ast, T> { Expression::BooleanConstant(b) => Ok(BooleanExpression::Value(b).into()), Expression::Identifier(name) => { // check that `id` is defined in the scope - match self.scope.get(&*name) { + match self.scope.get(name) { Some(info) => { let id = info.id; match info.ty.clone() { diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json new file mode 100644 index 000000000..9cfa458aa --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json @@ -0,0 +1,17 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 0, + "tests": [ + { + "input": { + "values": [ + ] + }, + "output": { + "Ok": { + "value": ["0", "2"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.zok b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.zok new file mode 100644 index 000000000..6ced6eabb --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.zok @@ -0,0 +1,9 @@ +def main() -> field[2] { + field[2] mut a = [1, 2]; + u32 i = 0; + asm { + a[i] <-- 0; + a[i] === 0; + } + return a; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json new file mode 100644 index 000000000..69207f66e --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json @@ -0,0 +1,18 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 1, + "tests": [ + { + "input": { + "values": [ + "42" + ] + }, + "output": { + "Ok": { + "value": ["42", "2"] + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.zok b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.zok new file mode 100644 index 000000000..e114e85be --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.zok @@ -0,0 +1,9 @@ +def main(field v) -> field[2] { + field[2] mut a = [1, 2]; + u32 i = 0; + asm { + a[i] <-- v; + a[i] === v; + } + return a; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/definition.json b/zokrates_core_test/tests/tests/assembly/propagation/definition.json new file mode 100644 index 000000000..a0d26ab7d --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/definition.json @@ -0,0 +1,5 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 0, + "tests": [] +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/definition.zok b/zokrates_core_test/tests/tests/assembly/propagation/definition.zok new file mode 100644 index 000000000..f63743a83 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/definition.zok @@ -0,0 +1,8 @@ +def main() { + field mut a = 0; + asm { + a <-- 1; + a === 1; + } + return; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/empty.json b/zokrates_core_test/tests/tests/assembly/propagation/empty.json new file mode 100644 index 000000000..a0d26ab7d --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/empty.json @@ -0,0 +1,5 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 0, + "tests": [] +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/empty.zok b/zokrates_core_test/tests/tests/assembly/propagation/empty.zok new file mode 100644 index 000000000..33152ccc4 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/empty.zok @@ -0,0 +1,5 @@ +def main() { + asm { + } + return; +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/redefinition.json b/zokrates_core_test/tests/tests/assembly/propagation/redefinition.json new file mode 100644 index 000000000..9e5c69de7 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/redefinition.json @@ -0,0 +1,6 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 0, + "tests": [] +} + \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/redefinition.zok b/zokrates_core_test/tests/tests/assembly/propagation/redefinition.zok new file mode 100644 index 000000000..5643e5274 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/redefinition.zok @@ -0,0 +1,10 @@ +def main() { + field mut a = 0; + field mut b = 0; + asm { + a <-- 1; + b <-- a; + b === 1; + } + return; +} \ No newline at end of file diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index c5ce66c23..65268b304 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -433,18 +433,18 @@ mod ast { pub span: Span<'ast>, } - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm))] pub enum AssignmentOperator { Assign(AssignOperator), AssignConstrain(AssignConstrainOperator), } - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm_assign))] pub struct AssignOperator; - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm_assign_constrain))] pub struct AssignConstrainOperator; From eca34960f064200e8ea80f5a1e804f1f9e6f8b1b Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 29 Nov 2022 19:01:15 +0100 Subject: [PATCH 41/94] add tests for assembly transformer and lqc --- zokrates_analysis/src/assembly_transformer.rs | 270 +++++++++++++++--- zokrates_ast/src/zir/lqc.rs | 152 ++++++++++ .../tests/tests/assembly/less_than.zok | 2 +- 3 files changed, 384 insertions(+), 40 deletions(-) diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index 3d1e95675..3b0a4d3bb 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -4,7 +4,7 @@ use crate::ZirPropagator; use std::fmt; use zokrates_ast::zir::lqc::LinQuadComb; -use zokrates_ast::zir::result_folder::{fold_field_expression, ResultFolder}; +use zokrates_ast::zir::result_folder::ResultFolder; use zokrates_ast::zir::{FieldElementExpression, Id, Identifier, ZirAssemblyStatement, ZirProgram}; use zokrates_field::Field; @@ -79,9 +79,10 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { ); let rhs: FieldElementExpression<'ast, T> = if lqc.quadratic.len() > 1 { - let common_factors = lqc.quadratic.iter().fold( - None, - |acc: Option>, (_, a, b)| { + let common_factor = lqc + .quadratic + .iter() + .fold(None, |acc: Option>, (_, a, b)| { Some( acc.map(|factors| { factors @@ -91,42 +92,35 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { }) .unwrap_or_else(|| vec![a.clone(), b.clone()]), ) - }, - ); + }) + .and_then(|mut v| v.pop()); - match common_factors { - Some(factors) => Ok(FieldElementExpression::Mult( + match common_factor { + Some(factor) => Ok(FieldElementExpression::Mult( box lqc .quadratic .into_iter() .map(|(c, i0, i1)| { let c = T::zero() - c; - let i0 = match factors.contains(&i0) { - true => FieldElementExpression::Number(T::from(1)), - false => FieldElementExpression::identifier(i0), - }; - let i1 = match factors.contains(&i1) { - true => FieldElementExpression::Number(T::from(1)), - false => FieldElementExpression::identifier(i1), + let e = match (i0, i1) { + (i0, i1) if factor.eq(&i0) => { + FieldElementExpression::identifier(i1) + } + (i0, i1) if factor.eq(&i1) => { + FieldElementExpression::identifier(i0) + } + _ => unreachable!(), }; FieldElementExpression::Mult( box FieldElementExpression::Number(c), - box FieldElementExpression::Mult(box i0, box i1), + box e, ) }) .fold( FieldElementExpression::Number(T::from(0)), |acc, e| FieldElementExpression::Add(box acc, box e), ), - box factors.into_iter().fold( - FieldElementExpression::Number(T::from(1)), - |acc, id| { - FieldElementExpression::Mult( - box acc, - box FieldElementExpression::identifier(id), - ) - }, - ), + box FieldElementExpression::identifier(factor), )), None => Err(Error( "Non-quadratic constraints are not allowed".to_string(), @@ -162,20 +156,218 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { } } } +} - fn fold_field_expression( - &mut self, - e: FieldElementExpression<'ast, T>, - ) -> Result, Self::Error> { - match e { - FieldElementExpression::And(_, _) - | FieldElementExpression::Or(_, _) - | FieldElementExpression::Xor(_, _) - | FieldElementExpression::LeftShift(_, _) - | FieldElementExpression::RightShift(_, _) => Err(Error( - format!("Found bitwise operation in expression `{}` of type `field` (only allowed in assembly assignment statement)", e) - )), - e => fold_field_expression(self, e), - } +#[cfg(test)] +mod tests { + use super::*; + use zokrates_field::Bn128Field; + + #[test] + fn quadratic() { + // x === a * b; + let lhs = FieldElementExpression::::identifier("x".into()); + let rhs = FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ); + + let expected = ZirAssemblyStatement::Constraint( + FieldElementExpression::identifier("x".into()), + FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + ); + let result = AssemblyTransformer + .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .unwrap(); + + assert_eq!(result, expected); + } + + #[test] + fn non_quadratic() { + // x === ((a * b) * c); + let lhs = FieldElementExpression::::identifier("x".into()); + let rhs = FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + box FieldElementExpression::identifier("c".into()), + ); + + let result = + AssemblyTransformer.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)); + + assert!(result.is_err()); + } + + #[test] + fn transform() { + // x === 1 - a * b; --> (-1) + x === (((-1) * a) * b); + let lhs = FieldElementExpression::identifier("x".into()); + let rhs = FieldElementExpression::Sub( + box FieldElementExpression::Number(Bn128Field::from(1)), + box FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + ); + + let expected = ZirAssemblyStatement::Constraint( + FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(-1)), + box FieldElementExpression::identifier("x".into()), + ), + FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-1)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("b".into()), + ), + ); + + let result = AssemblyTransformer + .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .unwrap(); + + assert_eq!(result, expected); + } + + #[test] + fn factorize() { + // x === (a * b) + (b * c); --> x === ((a + c) * b); + let lhs = FieldElementExpression::::identifier("x".into()); + let rhs = FieldElementExpression::Add( + box FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::identifier("b".into()), + box FieldElementExpression::identifier("c".into()), + ), + ); + + let expected = ZirAssemblyStatement::Constraint( + FieldElementExpression::identifier("x".into()), + FieldElementExpression::Mult( + box FieldElementExpression::Add( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("c".into()), + ), + box FieldElementExpression::identifier("b".into()), + ), + ); + let result = AssemblyTransformer + .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .unwrap(); + + assert_eq!(result, expected); + } + + #[test] + fn transform_complex() { + // mid = b*c; + // x === a+b+c - 2*a*b - 2*a*c - 2*mid + 4*a*mid; // x === a ^ b ^ c + // --> + // ((((x + ((-1)*a)) + ((-1)*b)) + ((-1)*c)) + (2*mid)) === (((((-2)*b) + ((-2)*c)) + (4*mid)) * a); + let lhs = FieldElementExpression::::identifier("x".into()); + let rhs = FieldElementExpression::Add( + box FieldElementExpression::Sub( + box FieldElementExpression::Sub( + box FieldElementExpression::Sub( + box FieldElementExpression::Add( + box FieldElementExpression::Add( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + box FieldElementExpression::identifier("c".into()), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("b".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("c".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("mid".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(4)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("mid".into()), + ), + ); + + let lhs_expected = FieldElementExpression::Add( + box FieldElementExpression::Add( + box FieldElementExpression::Add( + box FieldElementExpression::Add( + box FieldElementExpression::identifier("x".into()), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-1)), + box FieldElementExpression::identifier("a".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-1)), + box FieldElementExpression::identifier("b".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-1)), + box FieldElementExpression::identifier("c".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("mid".into()), + ), + ); + + let rhs_expected = FieldElementExpression::Mult( + box FieldElementExpression::Add( + box FieldElementExpression::Add( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-2)), + box FieldElementExpression::identifier("b".into()), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(-2)), + box FieldElementExpression::identifier("c".into()), + ), + ), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(4)), + box FieldElementExpression::identifier("mid".into()), + ), + ), + box FieldElementExpression::identifier("a".into()), + ); + + let expected = ZirAssemblyStatement::Constraint(lhs_expected, rhs_expected); + let result = AssemblyTransformer + .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .unwrap(); + + assert_eq!(result, expected); } } diff --git a/zokrates_ast/src/zir/lqc.rs b/zokrates_ast/src/zir/lqc.rs index 98b1c30ee..121b2a396 100644 --- a/zokrates_ast/src/zir/lqc.rs +++ b/zokrates_ast/src/zir/lqc.rs @@ -133,3 +133,155 @@ impl<'ast, T: Field> TryFrom> for LinQuadComb<'a } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::zir::Id; + use zokrates_field::Bn128Field; + + #[test] + fn add() { + // (2 + 2*a) + let a = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + )) + .unwrap(); + + // (2 + 2*a*b) + let b = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("b".into()), + ), + )) + .unwrap(); + + // (2 + 2*a) + (2 + 2*a*b) => 4 + 2*a + 2*a*b + let c = a + b; + + assert_eq!(c.constant, Bn128Field::from(4)); + assert_eq!( + c.linear, + vec![ + (Bn128Field::from(2), "a".into()), + (Bn128Field::from(0), "a".into()), + (Bn128Field::from(0), "b".into()) + ] + ); + assert_eq!( + c.quadratic, + vec![(Bn128Field::from(2), "a".into(), "b".into())] + ); + } + + #[test] + fn sub() { + // (2 + 2*a) + let a = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + )) + .unwrap(); + + // (2 + 2*a*b) + let b = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + box FieldElementExpression::identifier("b".into()), + ), + )) + .unwrap(); + + // (2 + 2*a) - (2 + 2*a*b) => 0 + 2*a + (-2)*a*b + let c = a - b; + + assert_eq!(c.constant, Bn128Field::from(0)); + assert_eq!( + c.linear, + vec![ + (Bn128Field::from(2), "a".into()), + (Bn128Field::from(0), "a".into()), + (Bn128Field::from(0), "b".into()) + ] + ); + assert_eq!( + c.quadratic, + vec![(Bn128Field::from(-2), "a".into(), "b".into())] + ); + } + + #[test] + fn mult() { + // (2 + 2*a) + let a = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("a".into()), + ), + )) + .unwrap(); + + // (2 + 2*b) + let b = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::identifier("b".into()), + ), + )) + .unwrap(); + + // (2 + 2*a) * (2 + 2*b) => 4 + 4*b + 4*a + 4*a*b + let c = a.try_mul(b).unwrap(); + + assert_eq!(c.constant, Bn128Field::from(4)); + assert_eq!( + c.linear, + vec![ + (Bn128Field::from(4), "a".into()), + (Bn128Field::from(4), "b".into()), + ] + ); + assert_eq!( + c.quadratic, + vec![(Bn128Field::from(4), "a".into(), "b".into())] + ); + } + + #[test] + fn mult_degree_error() { + // 2*a*b + let a = LinQuadComb::try_from(FieldElementExpression::Add( + box FieldElementExpression::Number(Bn128Field::from(2)), + box FieldElementExpression::Mult( + box FieldElementExpression::identifier("a".into()), + box FieldElementExpression::identifier("b".into()), + ), + )) + .unwrap(); + + // 2*a*b + let b = a.clone(); + + // (2*a*b) * (2*a*b) would result in a higher degree than expected + let c = a.try_mul(b); + assert!(c.is_err()); + } +} diff --git a/zokrates_core_test/tests/tests/assembly/less_than.zok b/zokrates_core_test/tests/tests/assembly/less_than.zok index 8af9235da..1810f6a1d 100644 --- a/zokrates_core_test/tests/tests/assembly/less_than.zok +++ b/zokrates_core_test/tests/tests/assembly/less_than.zok @@ -4,7 +4,7 @@ from "./bitify" import bitify; def less_than(field a, field b) -> bool { assert(N < FIELD_SIZE_IN_BITS - 1); - field[N + 1] bits = bitify(a + (1f << N) - b); + field[N + 1] bits = bitify(a + 2**N - b); bool out = field_to_bool_unsafe(1 - bits[N]); return out; } From 1e4d453f8b4a15b6bd5e152014c180c72c19e3ed Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 30 Nov 2022 13:40:44 +0100 Subject: [PATCH 42/94] improvements 3 --- zokrates_analysis/src/assembly_transformer.rs | 74 +++++++++++++------ .../src/flatten_complex_types.rs | 7 +- zokrates_analysis/src/propagation.rs | 29 ++++++-- zokrates_ast/src/common/error.rs | 23 ++++-- zokrates_ast/src/common/metadata.rs | 34 +++++++++ zokrates_ast/src/common/mod.rs | 2 + zokrates_ast/src/common/solvers.rs | 15 +++- zokrates_ast/src/typed/folder.rs | 11 ++- zokrates_ast/src/typed/mod.rs | 34 +++------ zokrates_ast/src/typed/result_folder.rs | 11 ++- zokrates_ast/src/untyped/position.rs | 3 +- zokrates_ast/src/zir/folder.rs | 4 +- zokrates_ast/src/zir/mod.rs | 13 ++-- zokrates_ast/src/zir/result_folder.rs | 4 +- zokrates_codegen/src/lib.rs | 4 +- zokrates_core/src/semantics.rs | 23 ++++-- .../tests/tests/assembly/binary_check.json | 10 ++- .../tests/tests/assembly/bitify.json | 10 ++- .../tests/tests/assembly/division.json | 10 ++- .../tests/tests/assert_array_equality.json | 8 +- .../tests/tests/assert_one.json | 8 +- .../tests/tests/embed/field_to_bool.json | 10 ++- .../conditional_bound_throw_no_isolation.json | 24 +++++- .../panics/deep_branch_no_isolation.json | 8 +- .../tests/tests/panics/loop_bound.json | 8 +- .../tests/tests/panics/panic_isolation.json | 8 +- .../tests/panics/panic_no_isolation.json | 8 +- .../tests/tests/range_check/assert_ge.json | 16 +++- .../tests/tests/range_check/assert_gt.json | 24 +++++- .../range_check/assert_gt_big_constant.json | 16 +++- .../tests/tests/range_check/assert_le.json | 16 +++- .../tests/tests/range_check/assert_lt.json | 16 +++- .../range_check/assert_lt_big_constant.json | 8 +- .../tests/tests/range_check/assert_lt_u8.json | 16 +++- zokrates_pest_ast/src/lib.rs | 4 +- 35 files changed, 402 insertions(+), 117 deletions(-) create mode 100644 zokrates_ast/src/common/metadata.rs diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index 3b0a4d3bb..48f9932ed 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -34,7 +34,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { ) -> Result, Self::Error> { match s { ZirAssemblyStatement::Assignment(_, _) => Ok(s), - ZirAssemblyStatement::Constraint(lhs, rhs) => { + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => { let lhs = self.fold_field_expression(lhs)?; let rhs = self.fold_field_expression(rhs)?; @@ -53,7 +53,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { }; match is_quadratic { - true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs)), + true => Ok(ZirAssemblyStatement::Constraint(lhs, rhs, metadata)), false => { let sub = FieldElementExpression::Sub(box lhs, box rhs); let mut lqc = LinQuadComb::try_from(sub.clone()).map_err(|_| { @@ -82,18 +82,26 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { let common_factor = lqc .quadratic .iter() - .fold(None, |acc: Option>, (_, a, b)| { - Some( - acc.map(|factors| { - factors - .into_iter() - .filter(|f| f == a || f == b) - .collect() - }) - .unwrap_or_else(|| vec![a.clone(), b.clone()]), - ) + .scan(None, |state: &mut Option>, (_, a, b)| { + // short circuit if we do not have any common factors anymore + if *state == Some(vec![]) { + None + } else { + match state { + // only keep factors found in this term + Some(factors) => { + factors.retain(|&x| x == a || x == b); + } + // initialisation step, start with the two factors in the first term + None => { + *state = Some(vec![a, b]); + } + }; + state.clone() + } }) - .and_then(|mut v| v.pop()); + .last() + .and_then(|mut v| v.pop().cloned()); match common_factor { Some(factor) => Ok(FieldElementExpression::Mult( @@ -150,7 +158,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { .fold_field_expression(rhs) .map_err(|e| Error(e.to_string()))?; - Ok(ZirAssemblyStatement::Constraint(lhs, rhs)) + Ok(ZirAssemblyStatement::Constraint(lhs, rhs, metadata)) } } } @@ -161,6 +169,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { #[cfg(test)] mod tests { use super::*; + use zokrates_ast::common::SourceMetadata; use zokrates_field::Bn128Field; #[test] @@ -178,9 +187,14 @@ mod tests { box FieldElementExpression::identifier("a".into()), box FieldElementExpression::identifier("b".into()), ), + SourceMetadata::default(), ); let result = AssemblyTransformer - .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .fold_assembly_statement(ZirAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::default(), + )) .unwrap(); assert_eq!(result, expected); @@ -198,8 +212,11 @@ mod tests { box FieldElementExpression::identifier("c".into()), ); - let result = - AssemblyTransformer.fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)); + let result = AssemblyTransformer.fold_assembly_statement(ZirAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::default(), + )); assert!(result.is_err()); } @@ -228,10 +245,15 @@ mod tests { ), box FieldElementExpression::identifier("b".into()), ), + SourceMetadata::default(), ); let result = AssemblyTransformer - .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .fold_assembly_statement(ZirAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::default(), + )) .unwrap(); assert_eq!(result, expected); @@ -261,9 +283,14 @@ mod tests { ), box FieldElementExpression::identifier("b".into()), ), + SourceMetadata::default(), ); let result = AssemblyTransformer - .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .fold_assembly_statement(ZirAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::default(), + )) .unwrap(); assert_eq!(result, expected); @@ -363,9 +390,14 @@ mod tests { box FieldElementExpression::identifier("a".into()), ); - let expected = ZirAssemblyStatement::Constraint(lhs_expected, rhs_expected); + let expected = + ZirAssemblyStatement::Constraint(lhs_expected, rhs_expected, SourceMetadata::default()); let result = AssemblyTransformer - .fold_assembly_statement(ZirAssemblyStatement::Constraint(lhs, rhs)) + .fold_assembly_statement(ZirAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::default(), + )) .unwrap(); assert_eq!(result, expected); diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 6ad4725fd..d03810278 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -559,10 +559,10 @@ fn fold_assembly_statement<'ast, T: Field>( zir::ZirAssemblyStatement::Assignment(a, function) } - typed::TypedAssemblyStatement::Constraint(lhs, rhs) => { + typed::TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => { let lhs = f.fold_field_expression(statements_buffer, lhs); let rhs = f.fold_field_expression(statements_buffer, rhs); - zir::ZirAssemblyStatement::Constraint(lhs, rhs) + zir::ZirAssemblyStatement::Constraint(lhs, rhs, metadata) } } } @@ -596,10 +596,11 @@ fn fold_statement<'ast, T: Field>( let e = f.fold_boolean_expression(statements_buffer, e); let error = match error { typed::RuntimeError::SourceAssertion(metadata) => { - zir::RuntimeError::SourceAssertion(metadata.to_string()) + zir::RuntimeError::SourceAssertion(metadata) } typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck, typed::RuntimeError::DivisionByZero => zir::RuntimeError::DivisionByZero, + _ => unreachable!(), }; vec![zir::ZirStatement::Assertion(e, error)] } diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index e8022ed6f..0756831ba 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -25,7 +25,7 @@ pub type Constants<'ast, T> = HashMap, TypedExpression<'ast, T> pub enum Error { Type(String), AssertionFailed(String), - ValueTooLarge(String), + InvalidValue(String), OutOfBounds(u128, u128), } @@ -34,7 +34,7 @@ impl fmt::Display for Error { match self { Error::Type(s) => write!(f, "{}", s), Error::AssertionFailed(s) => write!(f, "{}", s), - Error::ValueTooLarge(s) => write!(f, "{}", s), + Error::InvalidValue(s) => write!(f, "{}", s), Error::OutOfBounds(index, size) => write!( f, "Out of bounds index ({} >= {}) found during static analysis", @@ -401,8 +401,27 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { match embed_call.arguments.iter().all(|a| a.is_constant()) { true => { let r: Option> = match embed_call.embed { - FlatEmbed::FieldToBoolUnsafe => Ok(None), // todo - FlatEmbed::BitArrayLe => Ok(None), // todo + FlatEmbed::BitArrayLe => Ok(None), // todo + FlatEmbed::FieldToBoolUnsafe => { + match FieldElementExpression::try_from_typed( + embed_call.arguments[0].clone(), + ) { + Ok(FieldElementExpression::Number(n)) if n == T::from(0) => { + Ok(Some(BooleanExpression::Value(false).into())) + } + Ok(FieldElementExpression::Number(n)) if n == T::from(1) => { + Ok(Some(BooleanExpression::Value(true).into())) + } + Ok(FieldElementExpression::Number(n)) => { + Err(Error::InvalidValue(format!( + "Cannot call `{}` with value `{}`: should be 0 or 1", + embed_call.embed.id(), + n + ))) + } + _ => Ok(None), + } + } FlatEmbed::U64FromBits => Ok(Some(process_u_from_bits( &embed_call.arguments, UBitwidth::B64, @@ -460,7 +479,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } if acc != T::zero() { - Err(Error::ValueTooLarge(format!( + Err(Error::InvalidValue(format!( "Cannot unpack `{}` to `{}`: value is too large", num, assignee.get_type() diff --git a/zokrates_ast/src/common/error.rs b/zokrates_ast/src/common/error.rs index 499ac97d4..82a201881 100644 --- a/zokrates_ast/src/common/error.rs +++ b/zokrates_ast/src/common/error.rs @@ -1,9 +1,10 @@ +use crate::common::SourceMetadata; use serde::{Deserialize, Serialize}; use std::fmt; +use std::fmt::Write; #[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)] pub enum RuntimeError { - SourceAssemblyConstraint, BellmanConstraint, BellmanOneBinding, BellmanInputBinding, @@ -26,7 +27,8 @@ pub enum RuntimeError { Euclidean, ShaXor, Division, - SourceAssertion(String), + SourceAssertion(SourceMetadata), + SourceAssemblyConstraint(SourceMetadata), ArgumentBitness, SelectRangeCheck, } @@ -34,7 +36,9 @@ pub enum RuntimeError { impl From for RuntimeError { fn from(error: crate::zir::RuntimeError) -> Self { match error { - crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s), + crate::zir::RuntimeError::SourceAssertion(metadata) => { + RuntimeError::SourceAssertion(metadata) + } crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck, crate::zir::RuntimeError::DivisionByZero => RuntimeError::Inverse, crate::zir::RuntimeError::IncompleteDynamicRange => { @@ -50,7 +54,7 @@ impl RuntimeError { !matches!( self, - SourceAssemblyConstraint + SourceAssemblyConstraint(_) | SourceAssertion(_) | Inverse | SelectRangeCheck @@ -64,8 +68,8 @@ impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use RuntimeError::*; + let mut buf = String::new(); let msg = match self { - SourceAssemblyConstraint => "Source constraint is unsatisfied", BellmanConstraint => "Bellman constraint is unsatisfied", BellmanOneBinding => "Bellman ~one binding is unsatisfied", BellmanInputBinding => "Bellman input binding is unsatisfied", @@ -90,7 +94,14 @@ impl fmt::Display for RuntimeError { Euclidean => "Euclidean check failed", ShaXor => "Internal Sha check failed", Division => "Division check failed", - SourceAssertion(m) => m.as_str(), + SourceAssertion(m) => { + write!(&mut buf, "Assertion failed at {}", m).unwrap(); + buf.as_str() + } + SourceAssemblyConstraint(m) => { + write!(&mut buf, "Unsatisfied constraint at {}", m).unwrap(); + buf.as_str() + } ArgumentBitness => "Argument bitness check failed", SelectRangeCheck => "Out of bounds array access", }; diff --git a/zokrates_ast/src/common/metadata.rs b/zokrates_ast/src/common/metadata.rs new file mode 100644 index 000000000..efe9d235e --- /dev/null +++ b/zokrates_ast/src/common/metadata.rs @@ -0,0 +1,34 @@ +use crate::untyped::Position; +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Clone, Debug, PartialEq, Hash, Eq, Default, PartialOrd, Ord, Serialize, Deserialize)] +pub struct SourceMetadata { + pub file: String, + pub position: Position, + pub message: Option, +} + +impl SourceMetadata { + pub fn new(file: String, position: Position) -> Self { + Self { + file, + position, + message: None, + } + } + pub fn message(mut self, message: Option) -> Self { + self.message = message; + self + } +} + +impl fmt::Display for SourceMetadata { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}:{}", self.file, self.position)?; + match &self.message { + Some(m) => write!(f, ": \"{}\"", m), + None => write!(f, ""), + } + } +} diff --git a/zokrates_ast/src/common/mod.rs b/zokrates_ast/src/common/mod.rs index 95a3245fd..13d23bfdb 100644 --- a/zokrates_ast/src/common/mod.rs +++ b/zokrates_ast/src/common/mod.rs @@ -1,12 +1,14 @@ pub mod embed; mod error; mod format_string; +mod metadata; mod parameter; mod solvers; mod variable; pub use self::embed::FlatEmbed; pub use self::error::RuntimeError; +pub use self::metadata::SourceMetadata; pub use self::parameter::Parameter; pub use self::solvers::Solver; pub use self::variable::Variable; diff --git a/zokrates_ast/src/common/solvers.rs b/zokrates_ast/src/common/solvers.rs index 915d9ceb6..9b4f5c900 100644 --- a/zokrates_ast/src/common/solvers.rs +++ b/zokrates_ast/src/common/solvers.rs @@ -20,11 +20,22 @@ pub enum Solver<'ast, T> { SnarkVerifyBls12377(usize), } -impl<'ast, T: fmt::Debug> fmt::Display for Solver<'ast, T> { +impl<'ast, T> fmt::Display for Solver<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { + Solver::ConditionEq => write!(f, "ConditionEq"), + Solver::Bits(n) => write!(f, "Bits({})", n), + Solver::Div => write!(f, "Div"), + Solver::Xor => write!(f, "Xor"), + Solver::Or => write!(f, "Or"), + Solver::ShaAndXorAndXorAnd => write!(f, "ShaAndXorAndXorAnd"), + Solver::ShaCh => write!(f, "ShaCh"), + Solver::EuclideanDiv => write!(f, "EuclideanDiv"), Solver::Zir(_) => write!(f, "Zir(..)"), - _ => write!(f, "{:?}", self), + #[cfg(feature = "bellman")] + Solver::Sha256Round => write!(f, "Sha256Round"), + #[cfg(feature = "ark")] + Solver::SnarkVerifyBls12377(n) => write!(f, "SnarkVerifyBls12377({})", n), } } } diff --git a/zokrates_ast/src/typed/folder.rs b/zokrates_ast/src/typed/folder.rs index d2996ab2f..d76407873 100644 --- a/zokrates_ast/src/typed/folder.rs +++ b/zokrates_ast/src/typed/folder.rs @@ -530,10 +530,13 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( TypedAssemblyStatement::Assignment(a, e) => { TypedAssemblyStatement::Assignment(f.fold_assignee(a), f.fold_field_expression(e)) } - TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( - f.fold_field_expression(lhs), - f.fold_field_expression(rhs), - ), + TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => { + TypedAssemblyStatement::Constraint( + f.fold_field_expression(lhs), + f.fold_field_expression(rhs), + metadata, + ) + } } } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index fb05ca71c..46b11faa8 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -27,9 +27,7 @@ pub use self::types::{ UBitwidth, }; use self::types::{ConcreteArrayType, ConcreteStructType}; - use crate::typed::types::{ConcreteGenericsAssignment, IntoType}; -use crate::untyped::Position; pub use self::variable::{ConcreteVariable, DeclarationVariable, GVariable, Variable}; use std::marker::PhantomData; @@ -38,7 +36,7 @@ use std::path::{Path, PathBuf}; pub use crate::typed::integer::IntExpression; pub use crate::typed::uint::{bitwidth, UExpression, UExpressionInner, UMetadata}; -use crate::common::{FlatEmbed, FormatString}; +use crate::common::{FlatEmbed, FormatString, SourceMetadata}; use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; @@ -569,26 +567,10 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> { } } -#[derive(Clone, Debug, PartialEq, Hash, Eq, Default, PartialOrd, Ord)] -pub struct AssertionMetadata { - pub file: String, - pub position: Position, - pub message: Option, -} - -impl fmt::Display for AssertionMetadata { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Assertion failed at {}:{}", self.file, self.position)?; - match &self.message { - Some(m) => write!(f, ": \"{}\"", m), - None => write!(f, ""), - } - } -} - #[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)] pub enum RuntimeError { - SourceAssertion(AssertionMetadata), + SourceAssertion(SourceMetadata), + SourceAssemblyConstraint(SourceMetadata), SelectRangeCheck, DivisionByZero, } @@ -596,7 +578,12 @@ pub enum RuntimeError { impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata), + RuntimeError::SourceAssertion(metadata) => { + write!(f, "Assertion failed at {}", metadata) + } + RuntimeError::SourceAssemblyConstraint(metadata) => { + write!(f, "Unsatisfied constraint at {}", metadata) + } RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::DivisionByZero => write!(f, "Division by zero"), } @@ -683,6 +670,7 @@ pub enum TypedAssemblyStatement<'ast, T> { Constraint( FieldElementExpression<'ast, T>, FieldElementExpression<'ast, T>, + SourceMetadata, ), } @@ -692,7 +680,7 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssemblyStatement<'ast, T> { TypedAssemblyStatement::Assignment(ref lhs, ref rhs) => { write!(f, "{} <-- {}", lhs, rhs) } - TypedAssemblyStatement::Constraint(ref lhs, ref rhs) => { + TypedAssemblyStatement::Constraint(ref lhs, ref rhs, _) => { write!(f, "{} === {}", lhs, rhs) } } diff --git a/zokrates_ast/src/typed/result_folder.rs b/zokrates_ast/src/typed/result_folder.rs index b054779e0..5f99a6efa 100644 --- a/zokrates_ast/src/typed/result_folder.rs +++ b/zokrates_ast/src/typed/result_folder.rs @@ -531,10 +531,13 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( TypedAssemblyStatement::Assignment(a, e) => { TypedAssemblyStatement::Assignment(f.fold_assignee(a)?, f.fold_field_expression(e)?) } - TypedAssemblyStatement::Constraint(lhs, rhs) => TypedAssemblyStatement::Constraint( - f.fold_field_expression(lhs)?, - f.fold_field_expression(rhs)?, - ), + TypedAssemblyStatement::Constraint(lhs, rhs, metadata) => { + TypedAssemblyStatement::Constraint( + f.fold_field_expression(lhs)?, + f.fold_field_expression(rhs)?, + metadata, + ) + } }) } diff --git a/zokrates_ast/src/untyped/position.rs b/zokrates_ast/src/untyped/position.rs index 12394209a..786055551 100644 --- a/zokrates_ast/src/untyped/position.rs +++ b/zokrates_ast/src/untyped/position.rs @@ -1,6 +1,7 @@ +use serde::{Deserialize, Serialize}; use std::fmt; -#[derive(Clone, PartialEq, Eq, Copy, Hash, Default, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Copy, Hash, Default, PartialOrd, Ord, Serialize, Deserialize)] pub struct Position { pub line: usize, pub col: usize, diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index 7a063dcb7..37fb040f7 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -152,10 +152,10 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( let function = f.fold_function(function); ZirAssemblyStatement::Assignment(assignees, function) } - ZirAssemblyStatement::Constraint(lhs, rhs) => { + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => { let lhs = f.fold_field_expression(lhs); let rhs = f.fold_field_expression(rhs); - ZirAssemblyStatement::Constraint(lhs, rhs) + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) } } } diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index ba7a0e3e8..da821fe96 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -11,7 +11,7 @@ mod variable; pub use self::parameter::Parameter; pub use self::types::{Type, UBitwidth}; pub use self::variable::Variable; -use crate::common::{FlatEmbed, FormatString}; +use crate::common::{FlatEmbed, FormatString, SourceMetadata}; use crate::typed::ConcreteType; pub use crate::zir::uint::{ShouldReduce, UExpression, UExpressionInner, UMetadata}; @@ -94,7 +94,7 @@ pub type ZirAssignee<'ast> = Variable<'ast>; #[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)] pub enum RuntimeError { - SourceAssertion(String), + SourceAssertion(SourceMetadata), SelectRangeCheck, DivisionByZero, IncompleteDynamicRange, @@ -103,7 +103,9 @@ pub enum RuntimeError { impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RuntimeError::SourceAssertion(message) => write!(f, "{}", message), + RuntimeError::SourceAssertion(metadata) => { + write!(f, "Assertion failed at {}", metadata) + } RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::DivisionByZero => write!(f, "Division by zero"), RuntimeError::IncompleteDynamicRange => write!(f, "Dynamic comparison is incomplete"), @@ -113,7 +115,7 @@ impl fmt::Display for RuntimeError { impl RuntimeError { pub fn mock() -> Self { - RuntimeError::SourceAssertion(String::default()) + RuntimeError::SourceAssertion(SourceMetadata::default()) } } @@ -126,6 +128,7 @@ pub enum ZirAssemblyStatement<'ast, T> { Constraint( FieldElementExpression<'ast, T>, FieldElementExpression<'ast, T>, + SourceMetadata, ), } @@ -143,7 +146,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { rhs ) } - ZirAssemblyStatement::Constraint(ref lhs, ref rhs) => { + ZirAssemblyStatement::Constraint(ref lhs, ref rhs, _) => { write!(f, "{} === {}", lhs, rhs) } } diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 912ad77bb..dfad6e418 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -172,10 +172,10 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( let function = f.fold_function(function)?; ZirAssemblyStatement::Assignment(assignees, function) } - ZirAssemblyStatement::Constraint(lhs, rhs) => { + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => { let lhs = f.fold_field_expression(lhs)?; let rhs = f.fold_field_expression(rhs)?; - ZirAssemblyStatement::Constraint(lhs, rhs) + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) } }) } diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index ba3b92da0..6a0325fe8 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -2248,13 +2248,13 @@ impl<'ast, T: Field> Flattener<'ast, T> { let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs); statements_flattened.push_back(FlatStatement::Directive(directive)); } - ZirAssemblyStatement::Constraint(lhs, rhs) => { + ZirAssemblyStatement::Constraint(lhs, rhs, metadata) => { let lhs = self.flatten_field_expression(statements_flattened, lhs); let rhs = self.flatten_field_expression(statements_flattened, rhs); statements_flattened.push_back(FlatStatement::Condition( lhs, rhs, - RuntimeError::SourceAssemblyConstraint, + RuntimeError::SourceAssemblyConstraint(metadata), )); } } diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index f61e07557..922d06c39 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -8,7 +8,7 @@ use num_bigint::BigUint; use std::collections::{btree_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}; use std::fmt; use std::path::PathBuf; -use zokrates_ast::common::FormatString; +use zokrates_ast::common::{FormatString, SourceMetadata}; use zokrates_ast::typed::types::{GGenericsAssignment, GTupleType, GenericsAssignment}; use zokrates_ast::typed::SourceIdentifier; use zokrates_ast::typed::*; @@ -1811,7 +1811,11 @@ impl<'ast, T: Field> Checker<'ast, T> { match assignee.get_type() { Type::FieldElement => Ok(vec![ TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()), - TypedAssemblyStatement::Constraint(assignee.into(), e), + TypedAssemblyStatement::Constraint( + assignee.into(), + e, + SourceMetadata::new(module_id.display().to_string(), pos.0), + ), ]), ty => Err(ErrorInner { pos: Some(pos), @@ -1853,7 +1857,11 @@ impl<'ast, T: Field> Checker<'ast, T> { }), }?; - Ok(vec![TypedAssemblyStatement::Constraint(lhs, rhs)]) + Ok(vec![TypedAssemblyStatement::Constraint( + lhs, + rhs, + SourceMetadata::new(module_id.display().to_string(), pos.0), + )]) } } } @@ -2097,11 +2105,10 @@ impl<'ast, T: Field> Checker<'ast, T> { match e { TypedExpression::Boolean(e) => Ok(TypedStatement::Assertion( e, - RuntimeError::SourceAssertion(AssertionMetadata { - file: module_id.display().to_string(), - position: pos.0, - message, - }), + RuntimeError::SourceAssertion( + SourceMetadata::new(module_id.display().to_string(), pos.0) + .message(message), + ), )), e => Err(ErrorInner { pos: Some(pos), diff --git a/zokrates_core_test/tests/tests/assembly/binary_check.json b/zokrates_core_test/tests/tests/assembly/binary_check.json index 0973db36c..01df2d425 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_check.json +++ b/zokrates_core_test/tests/tests/assembly/binary_check.json @@ -29,7 +29,15 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "SourceAssemblyConstraint" + "error": { + "SourceAssemblyConstraint": { + "file": "tests/tests/assembly/binary_check.zok", + "position": { + "line": 3, + "col": 9 + } + } + } } } } diff --git a/zokrates_core_test/tests/tests/assembly/bitify.json b/zokrates_core_test/tests/tests/assembly/bitify.json index 19beb2bd3..392b9cce6 100644 --- a/zokrates_core_test/tests/tests/assembly/bitify.json +++ b/zokrates_core_test/tests/tests/assembly/bitify.json @@ -48,7 +48,15 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "SourceAssemblyConstraint" + "error": { + "SourceAssemblyConstraint": { + "file": "tests/tests/assembly/bitify.zok", + "position": { + "line": 14, + "col": 9 + } + } + } } } } diff --git a/zokrates_core_test/tests/tests/assembly/division.json b/zokrates_core_test/tests/tests/assembly/division.json index 9e3e511a2..5041b3a0a 100644 --- a/zokrates_core_test/tests/tests/assembly/division.json +++ b/zokrates_core_test/tests/tests/assembly/division.json @@ -19,7 +19,15 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "SourceAssemblyConstraint" + "error": { + "SourceAssemblyConstraint": { + "file": "tests/tests/assembly/division.zok", + "position": { + "line": 6, + "col": 9 + } + } + } } } } diff --git a/zokrates_core_test/tests/tests/assert_array_equality.json b/zokrates_core_test/tests/tests/assert_array_equality.json index 783f433b0..0abafed8d 100644 --- a/zokrates_core_test/tests/tests/assert_array_equality.json +++ b/zokrates_core_test/tests/tests/assert_array_equality.json @@ -22,7 +22,13 @@ "left": "0", "right": "1", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/assert_array_equality.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/assert_array_equality.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/assert_one.json b/zokrates_core_test/tests/tests/assert_one.json index ff1b80946..d11e4e1b7 100644 --- a/zokrates_core_test/tests/tests/assert_one.json +++ b/zokrates_core_test/tests/tests/assert_one.json @@ -12,7 +12,13 @@ "left": "0", "right": "1", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/assert_one.zok:2:2" + "SourceAssertion": { + "file": "./tests/tests/assert_one.zok", + "position": { + "line": 2, + "col": 2 + } + } } } } diff --git a/zokrates_core_test/tests/tests/embed/field_to_bool.json b/zokrates_core_test/tests/tests/embed/field_to_bool.json index b8357755a..d0f8980d8 100644 --- a/zokrates_core_test/tests/tests/embed/field_to_bool.json +++ b/zokrates_core_test/tests/tests/embed/field_to_bool.json @@ -29,7 +29,15 @@ "output": { "Err": { "UnsatisfiedConstraint": { - "error": "SourceAssemblyConstraint" + "error": { + "SourceAssemblyConstraint": { + "file": "tests/tests/embed/field_to_bool.zok", + "position": { + "line": 5, + "col": 9 + } + } + } } } } diff --git a/zokrates_core_test/tests/tests/panics/conditional_bound_throw_no_isolation.json b/zokrates_core_test/tests/tests/panics/conditional_bound_throw_no_isolation.json index 820ffbeb1..a9ebff5d6 100644 --- a/zokrates_core_test/tests/tests/panics/conditional_bound_throw_no_isolation.json +++ b/zokrates_core_test/tests/tests/panics/conditional_bound_throw_no_isolation.json @@ -12,7 +12,13 @@ "left": "0", "right": "1", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/panics/conditional_bound_throw.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -28,7 +34,13 @@ "left": "1", "right": "0", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/panics/conditional_bound_throw.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -44,7 +56,13 @@ "left": "2", "right": "0", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/conditional_bound_throw.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/panics/conditional_bound_throw.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/panics/deep_branch_no_isolation.json b/zokrates_core_test/tests/tests/panics/deep_branch_no_isolation.json index 1a10b3853..430a2c180 100644 --- a/zokrates_core_test/tests/tests/panics/deep_branch_no_isolation.json +++ b/zokrates_core_test/tests/tests/panics/deep_branch_no_isolation.json @@ -12,7 +12,13 @@ "left": "0", "right": "1", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/deep_branch.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/panics/deep_branch.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/panics/loop_bound.json b/zokrates_core_test/tests/tests/panics/loop_bound.json index 5caf89e0a..b70feec4b 100644 --- a/zokrates_core_test/tests/tests/panics/loop_bound.json +++ b/zokrates_core_test/tests/tests/panics/loop_bound.json @@ -12,7 +12,13 @@ "left": "0", "right": "1", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/loop_bound.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/panics/loop_bound.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/panics/panic_isolation.json b/zokrates_core_test/tests/tests/panics/panic_isolation.json index 434b45823..b928bcd17 100644 --- a/zokrates_core_test/tests/tests/panics/panic_isolation.json +++ b/zokrates_core_test/tests/tests/panics/panic_isolation.json @@ -15,7 +15,13 @@ "left": "1", "right": "21888242871839275222246405745257275088548364400416034343698204186575808495577", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:22:5" + "SourceAssertion": { + "file": "./tests/tests/panics/panic_isolation.zok", + "position": { + "line": 22, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/panics/panic_no_isolation.json b/zokrates_core_test/tests/tests/panics/panic_no_isolation.json index 349358227..107f79cd4 100644 --- a/zokrates_core_test/tests/tests/panics/panic_no_isolation.json +++ b/zokrates_core_test/tests/tests/panics/panic_no_isolation.json @@ -15,7 +15,13 @@ "left": "1", "right": "0", "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/panics/panic_isolation.zok:17:5" + "SourceAssertion": { + "file": "./tests/tests/panics/panic_isolation.zok", + "position": { + "line": 17, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_ge.json b/zokrates_core_test/tests/tests/range_check/assert_ge.json index 9cd01522f..21f8219b0 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_ge.json +++ b/zokrates_core_test/tests/tests/range_check/assert_ge.json @@ -11,7 +11,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_ge.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -25,7 +31,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_ge.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_ge.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt.json b/zokrates_core_test/tests/tests/range_check/assert_gt.json index ea3314b06..7e800f8bb 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_gt.json +++ b/zokrates_core_test/tests/tests/range_check/assert_gt.json @@ -11,7 +11,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_gt.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -25,7 +31,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_gt.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -39,7 +51,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_gt.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json index 0d92e7b45..37df775ca 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json +++ b/zokrates_core_test/tests/tests/range_check/assert_gt_big_constant.json @@ -11,7 +11,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_gt_big_constant.zok", + "position": { + "line": 4, + "col": 5 + } + } } } } @@ -27,7 +33,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_gt_big_constant.zok:4:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_gt_big_constant.zok", + "position": { + "line": 4, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_le.json b/zokrates_core_test/tests/tests/range_check/assert_le.json index 27502fdc9..694379525 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_le.json +++ b/zokrates_core_test/tests/tests/range_check/assert_le.json @@ -31,7 +31,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_le.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -45,7 +51,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_le.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_le.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt.json b/zokrates_core_test/tests/tests/range_check/assert_lt.json index bdaee03b4..05c0e90eb 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_lt.json +++ b/zokrates_core_test/tests/tests/range_check/assert_lt.json @@ -31,7 +31,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_lt.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -45,7 +51,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_lt.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json index 9baeb5aa3..2d3b1b107 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json +++ b/zokrates_core_test/tests/tests/range_check/assert_lt_big_constant.json @@ -35,7 +35,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_big_constant.zok:4:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_lt_big_constant.zok", + "position": { + "line": 4, + "col": 5 + } + } } } } diff --git a/zokrates_core_test/tests/tests/range_check/assert_lt_u8.json b/zokrates_core_test/tests/tests/range_check/assert_lt_u8.json index 3c2107c4c..cad68703b 100644 --- a/zokrates_core_test/tests/tests/range_check/assert_lt_u8.json +++ b/zokrates_core_test/tests/tests/range_check/assert_lt_u8.json @@ -31,7 +31,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_u8.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_lt_u8.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } @@ -45,7 +51,13 @@ "Err": { "UnsatisfiedConstraint": { "error": { - "SourceAssertion": "Assertion failed at ./tests/tests/range_check/assert_lt_u8.zok:2:5" + "SourceAssertion": { + "file": "./tests/tests/range_check/assert_lt_u8.zok", + "position": { + "line": 2, + "col": 5 + } + } } } } diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index c5ce66c23..8eb0124ba 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -440,11 +440,11 @@ mod ast { AssignConstrain(AssignConstrainOperator), } - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm_assign))] pub struct AssignOperator; - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm_assign_constrain))] pub struct AssignConstrainOperator; From eca20870e14ba768ae8e85d555732503f0925037 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 30 Nov 2022 14:23:15 +0100 Subject: [PATCH 43/94] remove unnecessary variant on runtime error --- zokrates_analysis/src/flatten_complex_types.rs | 1 - zokrates_ast/src/typed/mod.rs | 4 ---- 2 files changed, 5 deletions(-) diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index d03810278..2cfe2caeb 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -600,7 +600,6 @@ fn fold_statement<'ast, T: Field>( } typed::RuntimeError::SelectRangeCheck => zir::RuntimeError::SelectRangeCheck, typed::RuntimeError::DivisionByZero => zir::RuntimeError::DivisionByZero, - _ => unreachable!(), }; vec![zir::ZirStatement::Assertion(e, error)] } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 46b11faa8..9dc32b4bd 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -570,7 +570,6 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssignee<'ast, T> { #[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)] pub enum RuntimeError { SourceAssertion(SourceMetadata), - SourceAssemblyConstraint(SourceMetadata), SelectRangeCheck, DivisionByZero, } @@ -581,9 +580,6 @@ impl fmt::Display for RuntimeError { RuntimeError::SourceAssertion(metadata) => { write!(f, "Assertion failed at {}", metadata) } - RuntimeError::SourceAssemblyConstraint(metadata) => { - write!(f, "Unsatisfied constraint at {}", metadata) - } RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::DivisionByZero => write!(f, "Division by zero"), } From 226b65288a59c7a15af3d48c4b72c0551e5f5de7 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 30 Nov 2022 14:57:41 +0100 Subject: [PATCH 44/94] fix formatting --- zokrates_analysis/src/propagation.rs | 11 ++++++----- zokrates_analysis/src/zir_propagation.rs | 2 +- zokrates_ast/src/typed/mod.rs | 8 +++----- zokrates_ast/src/zir/mod.rs | 8 +++----- zokrates_pest_ast/src/lib.rs | 2 +- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index 0756831ba..e065804ac 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -570,15 +570,16 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } } } - TypedStatement::Assertion(e, ty) => { + TypedStatement::Assertion(e, err) => { let e_str = e.to_string(); let expr = self.fold_boolean_expression(e)?; match expr { - BooleanExpression::Value(false) => { - Err(Error::AssertionFailed(format!("{}: ({})", ty, e_str))) - } + BooleanExpression::Value(false) => Err(Error::AssertionFailed(format!( + "Assertion failed `{}` ({})", + e_str, err + ))), BooleanExpression::Value(true) => Ok(vec![]), - _ => Ok(vec![TypedStatement::Assertion(expr, ty)]), + _ => Ok(vec![TypedStatement::Assertion(expr, err)]), } } s @ TypedStatement::PushCallLog(..) => Ok(vec![s]), diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 298166bf3..c44cbd146 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -35,7 +35,7 @@ impl fmt::Display for Error { Error::DivisionByZero => { write!(f, "Division by zero detected in zir during static analysis",) } - Error::AssertionFailed(err) => write!(f, "Assertion failed: `{}`", err), + Error::AssertionFailed(err) => write!(f, "Assertion failed ({})", err), } } } diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index 9dc32b4bd..1911dd2c4 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -577,9 +577,7 @@ pub enum RuntimeError { impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RuntimeError::SourceAssertion(metadata) => { - write!(f, "Assertion failed at {}", metadata) - } + RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata), RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::DivisionByZero => write!(f, "Division by zero"), } @@ -674,10 +672,10 @@ impl<'ast, T: fmt::Display> fmt::Display for TypedAssemblyStatement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { TypedAssemblyStatement::Assignment(ref lhs, ref rhs) => { - write!(f, "{} <-- {}", lhs, rhs) + write!(f, "{} <-- {};", lhs, rhs) } TypedAssemblyStatement::Constraint(ref lhs, ref rhs, _) => { - write!(f, "{} === {}", lhs, rhs) + write!(f, "{} === {};", lhs, rhs) } } } diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index da821fe96..bc58efc65 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -103,9 +103,7 @@ pub enum RuntimeError { impl fmt::Display for RuntimeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - RuntimeError::SourceAssertion(metadata) => { - write!(f, "Assertion failed at {}", metadata) - } + RuntimeError::SourceAssertion(metadata) => write!(f, "{}", metadata), RuntimeError::SelectRangeCheck => write!(f, "Range check on array access"), RuntimeError::DivisionByZero => write!(f, "Division by zero"), RuntimeError::IncompleteDynamicRange => write!(f, "Dynamic comparison is incomplete"), @@ -138,7 +136,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { ZirAssemblyStatement::Assignment(ref lhs, ref rhs) => { write!( f, - "{} <-- {}", + "{} <-- {};", lhs.iter() .map(|a| a.id.to_string()) .collect::>() @@ -147,7 +145,7 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { ) } ZirAssemblyStatement::Constraint(ref lhs, ref rhs, _) => { - write!(f, "{} === {}", lhs, rhs) + write!(f, "{} === {};", lhs, rhs) } } } diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 8eb0124ba..65268b304 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -433,7 +433,7 @@ mod ast { pub span: Span<'ast>, } - #[derive(Debug, FromPest, PartialEq, Clone)] + #[derive(Debug, FromPest, PartialEq, Eq, Clone)] #[pest_ast(rule(Rule::op_asm))] pub enum AssignmentOperator { Assign(AssignOperator), From 46e80743b3f1446332e31793621325faebe5b9f7 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 30 Nov 2022 22:41:28 +0100 Subject: [PATCH 45/94] make tests pass, introduce ir blocks, try optimising directive outputs --- zokrates_analysis/src/assembly_transformer.rs | 4 ++ .../src/flatten_complex_types.rs | 13 ++--- zokrates_analysis/src/propagation.rs | 15 ++---- zokrates_analysis/src/reducer/shallow_ssa.rs | 2 +- zokrates_analysis/src/zir_propagation.rs | 52 ++++++++++--------- zokrates_ast/src/flat/folder.rs | 6 +++ zokrates_ast/src/flat/mod.rs | 14 +++++ zokrates_ast/src/ir/clean.rs | 31 +++++++++++ zokrates_ast/src/ir/folder.rs | 6 +++ zokrates_ast/src/ir/from_flat.rs | 3 ++ zokrates_ast/src/ir/mod.rs | 10 ++++ zokrates_ast/src/ir/smtlib2.rs | 1 + zokrates_ast/src/ir/visitor.rs | 5 ++ zokrates_ast/src/typed/folder.rs | 2 +- zokrates_ast/src/typed/mod.rs | 2 +- zokrates_ast/src/typed/result_folder.rs | 2 +- zokrates_ast/src/zir/folder.rs | 4 +- zokrates_ast/src/zir/mod.rs | 48 ++++++++++++++++- zokrates_ast/src/zir/result_folder.rs | 9 ++-- zokrates_circom/src/r1cs.rs | 2 + zokrates_codegen/src/lib.rs | 21 +++++--- zokrates_core/src/compile.rs | 5 +- zokrates_core/src/optimizer/redefinition.rs | 47 ++++++++++++++--- zokrates_core/src/semantics.rs | 7 ++- .../propagation/array_write_constant.json | 2 +- .../propagation/array_write_variable.json | 2 +- .../assembly/propagation/write_variable.json | 18 +++++++ .../assembly/propagation/write_variable.zok | 8 +++ zokrates_interpreter/src/lib.rs | 1 + 29 files changed, 267 insertions(+), 75 deletions(-) create mode 100644 zokrates_ast/src/ir/clean.rs create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/write_variable.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/write_variable.zok diff --git a/zokrates_analysis/src/assembly_transformer.rs b/zokrates_analysis/src/assembly_transformer.rs index 43999c329..b53699ec5 100644 --- a/zokrates_analysis/src/assembly_transformer.rs +++ b/zokrates_analysis/src/assembly_transformer.rs @@ -39,6 +39,10 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for AssemblyTransformer { let rhs = self.fold_field_expression(rhs)?; let (is_quadratic, lhs, rhs) = match (lhs, rhs) { + ( + lhs @ FieldElementExpression::Identifier(..), + rhs @ FieldElementExpression::Identifier(..), + ) => (true, lhs, rhs), (FieldElementExpression::Mult(x, y), other) | (other, FieldElementExpression::Mult(x, y)) if other.is_linear() => diff --git a/zokrates_analysis/src/flatten_complex_types.rs b/zokrates_analysis/src/flatten_complex_types.rs index 4c10cf0ab..b279f93c9 100644 --- a/zokrates_analysis/src/flatten_complex_types.rs +++ b/zokrates_analysis/src/flatten_complex_types.rs @@ -528,14 +528,9 @@ fn fold_assembly_statement<'ast, T: Field>( match s { typed::TypedAssemblyStatement::Assignment(a, e) => { let mut statements_buffer: Vec> = vec![]; - let mut a = f.fold_assignee(a); - assert_eq!(a.len(), 1); - let a = a.pop().unwrap(); - assert_eq!(a.get_type(), zir::Type::FieldElement); - let e = f.fold_field_expression(&mut statements_buffer, e); - statements_buffer.push(zir::ZirStatement::Return(vec![ - zir::ZirExpression::FieldElement(e), - ])); + let a = f.fold_assignee(a); + let e = f.fold_expression(&mut statements_buffer, e); + statements_buffer.push(zir::ZirStatement::Return(e)); let mut finder = ArgumentFinder::default(); let mut statements_buffer: Vec> = statements_buffer @@ -548,7 +543,7 @@ fn fold_assembly_statement<'ast, T: Field>( let function = zir::ZirFunction { signature: zir::types::Signature::default() .inputs(finder.identifiers.values().cloned().collect()) - .outputs(vec![a.get_type()]), + .outputs(a.iter().map(|a| a.get_type()).collect()), arguments: finder .identifiers .into_iter() diff --git a/zokrates_analysis/src/propagation.rs b/zokrates_analysis/src/propagation.rs index e41fa7d0f..944e7a147 100644 --- a/zokrates_analysis/src/propagation.rs +++ b/zokrates_analysis/src/propagation.rs @@ -176,13 +176,6 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { } } - fn fold_function( - &mut self, - f: TypedFunction<'ast, T>, - ) -> Result, Error> { - fold_function(self, f) - } - fn fold_conditional_expression< E: Expr<'ast, T> + Conditional<'ast, T> + PartialEq + ResultFold<'ast, T>, >( @@ -219,9 +212,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { match s { TypedAssemblyStatement::Assignment(assignee, expr) => { let assignee = self.fold_assignee(assignee)?; - let expr = self.fold_field_expression(expr)?; - - let expr = TypedExpression::from(expr); + let expr = self.fold_expression(expr)?; if expr.is_constant() { match assignee { @@ -241,8 +232,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Propagator<'ast, 'a, T> { // invalidate the cache for this identifier, and define the latest // version of the constant in the program, if any Some(c) => Ok(vec![ - TypedAssemblyStatement::Assignment(v.clone().into(), c.into()), - TypedAssemblyStatement::Assignment(assignee, expr.into()), + TypedAssemblyStatement::Assignment(v.clone().into(), c), + TypedAssemblyStatement::Assignment(assignee, expr), ]), None => Ok(vec![TypedAssemblyStatement::Assignment( assignee, diff --git a/zokrates_analysis/src/reducer/shallow_ssa.rs b/zokrates_analysis/src/reducer/shallow_ssa.rs index 585622486..e479b3778 100644 --- a/zokrates_analysis/src/reducer/shallow_ssa.rs +++ b/zokrates_analysis/src/reducer/shallow_ssa.rs @@ -130,7 +130,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { ) -> Vec> { match s { TypedAssemblyStatement::Assignment(a, e) => { - let e = self.fold_field_expression(e); + let e = self.fold_expression(e); let a = match a { TypedAssignee::Identifier(v) => { let v = self.issue_next_ssa_variable(v); diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index e8b1cad5e..011992b64 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -5,8 +5,8 @@ use std::fmt; use std::ops::{BitAnd, BitOr, BitXor, Shl, Shr, Sub}; use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ - result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Expr, Id, - IdentifierExpression, IdentifierOrExpression, SelectExpression, SelectOrExpression, + result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Constant, Expr, + Id, IdentifierExpression, IdentifierOrExpression, SelectExpression, SelectOrExpression, ZirAssemblyStatement, }; use zokrates_ast::zir::{ @@ -62,33 +62,37 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { s: ZirAssemblyStatement<'ast, T>, ) -> Result>, Self::Error> { match s { - ZirAssemblyStatement::Assignment(assignee, function) => { - let function = self.fold_function(function)?; + ZirAssemblyStatement::Assignment(assignees, function) => { + let assignees: Vec<_> = assignees + .into_iter() + .map(|a| self.fold_assignee(a)) + .collect::>()?; - if function.statements.len() == 1 { - let value = match &function.statements.last().unwrap() { - ZirStatement::Return(values) => { - assert_eq!(values.len(), 1); - match values[0].clone() { - ZirExpression::FieldElement(FieldElementExpression::Number(v)) => { - Some(v) - } - _ => None, - } - } - _ => None, - }; + let function = self.fold_function(function)?; - match value { - Some(v) => { - self.constants - .insert(assignee.id, FieldElementExpression::Number(v).into()); + match &function.statements.last().unwrap() { + ZirStatement::Return(values) => { + if values.iter().all(|v| v.is_constant()) { + self.constants.extend( + assignees + .into_iter() + .zip(values.into_iter()) + .map(|(a, v)| (a.id, v.clone())), + ); Ok(vec![]) + } else { + assignees.iter().for_each(|a| { + self.constants.remove(&a.id); + }); + Ok(vec![ZirAssemblyStatement::Assignment(assignees, function)]) } - None => Ok(vec![ZirAssemblyStatement::Assignment(assignee, function)]), } - } else { - Ok(vec![ZirAssemblyStatement::Assignment(assignee, function)]) + _ => { + assignees.iter().for_each(|a| { + self.constants.remove(&a.id); + }); + Ok(vec![ZirAssemblyStatement::Assignment(assignees, function)]) + } } } ZirAssemblyStatement::Constraint(left, right) => { diff --git a/zokrates_ast/src/flat/folder.rs b/zokrates_ast/src/flat/folder.rs index 5f8b4e394..ce50d7dac 100644 --- a/zokrates_ast/src/flat/folder.rs +++ b/zokrates_ast/src/flat/folder.rs @@ -54,6 +54,12 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( s: FlatStatement<'ast, T>, ) -> Vec> { match s { + FlatStatement::Block(statements) => vec![FlatStatement::Block( + statements + .into_iter() + .flat_map(|s| f.fold_statement(s)) + .collect(), + )], FlatStatement::Condition(left, right, error) => vec![FlatStatement::Condition( f.fold_expression(left), f.fold_expression(right), diff --git a/zokrates_ast/src/flat/mod.rs b/zokrates_ast/src/flat/mod.rs index cf38e5537..015e670a5 100644 --- a/zokrates_ast/src/flat/mod.rs +++ b/zokrates_ast/src/flat/mod.rs @@ -82,6 +82,7 @@ impl<'ast, T: Field> fmt::Display for FlatFunction<'ast, T> { #[derive(Clone, PartialEq, Eq, Debug)] pub enum FlatStatement<'ast, T> { + Block(Vec>), Condition(FlatExpression, FlatExpression, RuntimeError), Definition(Variable, FlatExpression), Directive(FlatDirective<'ast, T>), @@ -91,6 +92,13 @@ pub enum FlatStatement<'ast, T> { impl<'ast, T: Field> fmt::Display for FlatStatement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { + FlatStatement::Block(ref statements) => { + writeln!(f, "{{")?; + for s in statements { + writeln!(f, "{}", s)?; + } + writeln!(f, "}}") + } FlatStatement::Definition(ref lhs, ref rhs) => write!(f, "{} = {}", lhs, rhs), FlatStatement::Condition(ref lhs, ref rhs, ref message) => { write!(f, "{} == {} // {}", lhs, rhs, message) @@ -122,6 +130,12 @@ impl<'ast, T: Field> FlatStatement<'ast, T> { substitution: &'ast HashMap, ) -> FlatStatement { match self { + FlatStatement::Block(statements) => FlatStatement::Block( + statements + .into_iter() + .map(|s| s.apply_substitution(substitution)) + .collect(), + ), FlatStatement::Definition(id, x) => FlatStatement::Definition( *id.apply_substitution(substitution), x.apply_substitution(substitution), diff --git a/zokrates_ast/src/ir/clean.rs b/zokrates_ast/src/ir/clean.rs new file mode 100644 index 000000000..b4fb8f445 --- /dev/null +++ b/zokrates_ast/src/ir/clean.rs @@ -0,0 +1,31 @@ +use super::folder::Folder; +use super::{ProgIterator, Statement}; +use zokrates_field::Field; + +#[derive(Default)] +pub struct Cleaner; + +impl<'ast, T: Field, I: IntoIterator>> ProgIterator<'ast, T, I> { + pub fn clean(self) -> ProgIterator<'ast, T, impl IntoIterator>> { + ProgIterator { + arguments: self.arguments, + return_count: self.return_count, + statements: self + .statements + .into_iter() + .flat_map(|s| Cleaner::default().fold_statement(s)), + } + } +} + +impl<'ast, T: Field> Folder<'ast, T> for Cleaner { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { + match s { + Statement::Block(statements) => statements + .into_iter() + .flat_map(|s| self.fold_statement(s)) + .collect(), + s => vec![s], + } + } +} diff --git a/zokrates_ast/src/ir/folder.rs b/zokrates_ast/src/ir/folder.rs index 6d1c20b9d..6e67c15de 100644 --- a/zokrates_ast/src/ir/folder.rs +++ b/zokrates_ast/src/ir/folder.rs @@ -58,6 +58,12 @@ pub fn fold_statement<'ast, T: Field, F: Folder<'ast, T>>( s: Statement<'ast, T>, ) -> Vec> { match s { + Statement::Block(statements) => vec![Statement::Block( + statements + .into_iter() + .flat_map(|s| f.fold_statement(s)) + .collect(), + )], Statement::Constraint(quad, lin, message) => vec![Statement::Constraint( f.fold_quadratic_combination(quad), f.fold_linear_combination(lin), diff --git a/zokrates_ast/src/ir/from_flat.rs b/zokrates_ast/src/ir/from_flat.rs index 35acad348..875463df3 100644 --- a/zokrates_ast/src/ir/from_flat.rs +++ b/zokrates_ast/src/ir/from_flat.rs @@ -55,6 +55,9 @@ impl From> for LinComb { impl<'ast, T: Field> From> for Statement<'ast, T> { fn from(flat_statement: FlatStatement<'ast, T>) -> Statement<'ast, T> { match flat_statement { + FlatStatement::Block(statements) => { + Statement::Block(statements.into_iter().map(|s| Statement::from(s)).collect()) + } FlatStatement::Condition(linear, quadratic, message) => match quadratic { FlatExpression::Mult(box lhs, box rhs) => Statement::Constraint( QuadComb::from_linear_combinations(lhs.into(), rhs.into()), diff --git a/zokrates_ast/src/ir/mod.rs b/zokrates_ast/src/ir/mod.rs index 03c393056..78b48f808 100644 --- a/zokrates_ast/src/ir/mod.rs +++ b/zokrates_ast/src/ir/mod.rs @@ -8,6 +8,7 @@ use std::hash::Hash; use zokrates_field::Field; mod check; +mod clean; mod expression; pub mod folder; pub mod from_flat; @@ -29,6 +30,8 @@ pub use self::witness::Witness; #[derive(Debug, Serialize, Deserialize, Clone, Derivative)] #[derivative(Hash, PartialEq, Eq)] pub enum Statement<'ast, T> { + #[serde(skip)] + Block(Vec>), Constraint( QuadComb, LinComb, @@ -82,6 +85,13 @@ impl<'ast, T: Field> fmt::Display for Directive<'ast, T> { impl<'ast, T: Field> fmt::Display for Statement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { + Statement::Block(ref statements) => { + writeln!(f, "{{")?; + for s in statements { + writeln!(f, "{}", s)?; + } + write!(f, "}}") + } Statement::Constraint(ref quad, ref lin, ref error) => write!( f, "{} == {}{}", diff --git a/zokrates_ast/src/ir/smtlib2.rs b/zokrates_ast/src/ir/smtlib2.rs index 1a80c8749..bc1188518 100644 --- a/zokrates_ast/src/ir/smtlib2.rs +++ b/zokrates_ast/src/ir/smtlib2.rs @@ -78,6 +78,7 @@ fn format_prefix_op_smtlib2( impl<'ast, T: Field> SMTLib2 for Statement<'ast, T> { fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { + Statement::Block(..) => unreachable!(), Statement::Constraint(ref quad, ref lin, _) => { write!(f, "(= (mod ")?; quad.to_smtlib2(f)?; diff --git a/zokrates_ast/src/ir/visitor.rs b/zokrates_ast/src/ir/visitor.rs index 6d8ffc00f..d3894ca6b 100644 --- a/zokrates_ast/src/ir/visitor.rs +++ b/zokrates_ast/src/ir/visitor.rs @@ -53,6 +53,11 @@ pub fn visit_module>(f: &mut F, p: &Prog) { pub fn visit_statement>(f: &mut F, s: &Statement) { match s { + Statement::Block(statements) => { + for s in statements { + f.visit_statement(s); + } + } Statement::Constraint(quad, lin, error) => { f.visit_quadratic_combination(quad); f.visit_linear_combination(lin); diff --git a/zokrates_ast/src/typed/folder.rs b/zokrates_ast/src/typed/folder.rs index 06f03f617..393bfad56 100644 --- a/zokrates_ast/src/typed/folder.rs +++ b/zokrates_ast/src/typed/folder.rs @@ -530,7 +530,7 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( TypedAssemblyStatement::Assignment(a, e) => { vec![TypedAssemblyStatement::Assignment( f.fold_assignee(a), - f.fold_field_expression(e), + f.fold_expression(e), )] } TypedAssemblyStatement::Constraint(lhs, rhs) => vec![TypedAssemblyStatement::Constraint( diff --git a/zokrates_ast/src/typed/mod.rs b/zokrates_ast/src/typed/mod.rs index fb05ca71c..d16d5b8f5 100644 --- a/zokrates_ast/src/typed/mod.rs +++ b/zokrates_ast/src/typed/mod.rs @@ -679,7 +679,7 @@ impl<'ast, T: fmt::Display> fmt::Display for DefinitionRhs<'ast, T> { #[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)] pub enum TypedAssemblyStatement<'ast, T> { - Assignment(TypedAssignee<'ast, T>, FieldElementExpression<'ast, T>), + Assignment(TypedAssignee<'ast, T>, TypedExpression<'ast, T>), Constraint( FieldElementExpression<'ast, T>, FieldElementExpression<'ast, T>, diff --git a/zokrates_ast/src/typed/result_folder.rs b/zokrates_ast/src/typed/result_folder.rs index 852cfe7d3..086014a23 100644 --- a/zokrates_ast/src/typed/result_folder.rs +++ b/zokrates_ast/src/typed/result_folder.rs @@ -531,7 +531,7 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( TypedAssemblyStatement::Assignment(a, e) => { vec![TypedAssemblyStatement::Assignment( f.fold_assignee(a)?, - f.fold_field_expression(e)?, + f.fold_expression(e)?, )] } TypedAssemblyStatement::Constraint(lhs, rhs) => vec![TypedAssemblyStatement::Constraint( diff --git a/zokrates_ast/src/zir/folder.rs b/zokrates_ast/src/zir/folder.rs index f00eca8fe..d553f85d5 100644 --- a/zokrates_ast/src/zir/folder.rs +++ b/zokrates_ast/src/zir/folder.rs @@ -147,8 +147,8 @@ pub fn fold_assembly_statement<'ast, T: Field, F: Folder<'ast, T>>( s: ZirAssemblyStatement<'ast, T>, ) -> Vec> { match s { - ZirAssemblyStatement::Assignment(assignee, function) => { - let assignees = f.fold_assignee(assignee); + ZirAssemblyStatement::Assignment(assignees, function) => { + let assignees = assignees.into_iter().map(|a| f.fold_assignee(a)).collect(); let function = f.fold_function(function); vec![ZirAssemblyStatement::Assignment(assignees, function)] } diff --git a/zokrates_ast/src/zir/mod.rs b/zokrates_ast/src/zir/mod.rs index 71b121e76..46ffd0428 100644 --- a/zokrates_ast/src/zir/mod.rs +++ b/zokrates_ast/src/zir/mod.rs @@ -119,7 +119,10 @@ impl RuntimeError { #[derive(Clone, PartialEq, Hash, Eq, Debug, Serialize, Deserialize)] pub enum ZirAssemblyStatement<'ast, T> { - Assignment(#[serde(borrow)] ZirAssignee<'ast>, ZirFunction<'ast, T>), + Assignment( + #[serde(borrow)] Vec>, + ZirFunction<'ast, T>, + ), Constraint( FieldElementExpression<'ast, T>, FieldElementExpression<'ast, T>, @@ -130,7 +133,15 @@ impl<'ast, T: fmt::Display> fmt::Display for ZirAssemblyStatement<'ast, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { ZirAssemblyStatement::Assignment(ref lhs, ref rhs) => { - write!(f, "{} <-- {}", lhs, rhs) + write!( + f, + "{} <-- {}", + lhs.iter() + .map(|a| a.to_string()) + .collect::>() + .join(", "), + rhs + ) } ZirAssemblyStatement::Constraint(ref lhs, ref rhs) => { write!(f, "{} === {}", lhs, rhs) @@ -901,3 +912,36 @@ impl IntoType for UBitwidth { Type::Uint(self) } } + +pub trait Constant: Sized { + // return whether this is constant + fn is_constant(&self) -> bool; +} + +impl<'ast, T: Field> Constant for ZirExpression<'ast, T> { + fn is_constant(&self) -> bool { + match self { + ZirExpression::FieldElement(e) => e.is_constant(), + ZirExpression::Boolean(e) => e.is_constant(), + ZirExpression::Uint(e) => e.is_constant(), + } + } +} + +impl<'ast, T: Field> Constant for FieldElementExpression<'ast, T> { + fn is_constant(&self) -> bool { + matches!(self, FieldElementExpression::Number(..)) + } +} + +impl<'ast, T: Field> Constant for BooleanExpression<'ast, T> { + fn is_constant(&self) -> bool { + matches!(self, BooleanExpression::Value(..)) + } +} + +impl<'ast, T: Field> Constant for UExpression<'ast, T> { + fn is_constant(&self) -> bool { + matches!(self.as_inner(), UExpressionInner::Value(..)) + } +} diff --git a/zokrates_ast/src/zir/result_folder.rs b/zokrates_ast/src/zir/result_folder.rs index 70a349013..1527701b2 100644 --- a/zokrates_ast/src/zir/result_folder.rs +++ b/zokrates_ast/src/zir/result_folder.rs @@ -164,10 +164,13 @@ pub fn fold_assembly_statement<'ast, T: Field, F: ResultFolder<'ast, T>>( s: ZirAssemblyStatement<'ast, T>, ) -> Result>, F::Error> { Ok(match s { - ZirAssemblyStatement::Assignment(assignee, function) => { - let assignee = f.fold_assignee(assignee)?; + ZirAssemblyStatement::Assignment(assignees, function) => { + let assignees = assignees + .into_iter() + .map(|a| f.fold_assignee(a)) + .collect::>()?; let function = f.fold_function(function)?; - vec![ZirAssemblyStatement::Assignment(assignee, function)] + vec![ZirAssemblyStatement::Assignment(assignees, function)] } ZirAssemblyStatement::Constraint(lhs, rhs) => { let lhs = f.fold_field_expression(lhs)?; diff --git a/zokrates_circom/src/r1cs.rs b/zokrates_circom/src/r1cs.rs index 8bdab0ac0..854bc0eab 100644 --- a/zokrates_circom/src/r1cs.rs +++ b/zokrates_circom/src/r1cs.rs @@ -72,6 +72,7 @@ pub fn r1cs_program(prog: Prog) -> (Vec, usize, Vec Some((quad, lin)), Statement::Directive(..) => None, + Statement::Block(..) => unreachable!(), Statement::Log(..) => None, }) { for (k, _) in &quad.left.0 { @@ -95,6 +96,7 @@ pub fn r1cs_program(prog: Prog) -> (Vec, usize, Vec Some((quad, lin)), + Statement::Block(..) => unreachable!(), Statement::Directive(..) => None, Statement::Log(..) => None, }) { diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index 1c11a66cd..7e9faae8a 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -1156,6 +1156,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { // add all flattened statements, adapt return statements let statements = funct.statements.into_iter().map(|stat| match stat { + FlatStatement::Block(..) => unreachable!(), FlatStatement::Definition(var, rhs) => { let new_var = self.use_sym(); replacement_map.insert(var, new_var); @@ -2229,12 +2230,16 @@ impl<'ast, T: Field> Flattener<'ast, T> { stat: ZirAssemblyStatement<'ast, T>, ) { match stat { - ZirAssemblyStatement::Assignment(assignee, function) => { - let outputs: Vec = vec![self - .layout - .get(&assignee.id) - .cloned() - .unwrap_or_else(|| self.use_variable(&assignee))]; + ZirAssemblyStatement::Assignment(assignees, function) => { + let outputs: Vec = assignees + .into_iter() + .map(|assignee| { + self.layout + .get(&assignee.id) + .cloned() + .unwrap_or_else(|| self.use_variable(&assignee)) + }) + .collect(); let inputs: Vec> = function .arguments .iter() @@ -2269,9 +2274,11 @@ impl<'ast, T: Field> Flattener<'ast, T> { ) { match stat { ZirStatement::Assembly(statements) => { + let mut block_statements = VecDeque::new(); for s in statements { - self.flatten_assembly_statement(statements_flattened, s); + self.flatten_assembly_statement(&mut block_statements, s); } + statements_flattened.push_back(FlatStatement::Block(block_statements.into())); } ZirStatement::Return(exprs) => { #[allow(clippy::needless_collect)] diff --git a/zokrates_core/src/compile.rs b/zokrates_core/src/compile.rs index 89261d76b..0c7583fa2 100644 --- a/zokrates_core/src/compile.rs +++ b/zokrates_core/src/compile.rs @@ -199,8 +199,11 @@ pub fn compile<'ast, T: Field, E: Into>( log::debug!("Optimise IR"); let optimized_ir_prog = optimize(ir_prog); + // clean (remove blocks) + let clean_ir_prog = optimized_ir_prog.clean(); + Ok(CompilationArtifacts { - prog: optimized_ir_prog, + prog: clean_ir_prog, abi, }) } diff --git a/zokrates_core/src/optimizer/redefinition.rs b/zokrates_core/src/optimizer/redefinition.rs index 8f0e24474..2d340913c 100644 --- a/zokrates_core/src/optimizer/redefinition.rs +++ b/zokrates_core/src/optimizer/redefinition.rs @@ -52,7 +52,7 @@ pub struct RedefinitionOptimizer { pub ignore: HashSet, } -impl RedefinitionOptimizer { +impl RedefinitionOptimizer { pub fn init<'ast, I: IntoIterator>>( p: &ProgIterator<'ast, T, I>, ) -> Self { @@ -66,10 +66,12 @@ impl RedefinitionOptimizer { .collect(), } } -} -impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer { - fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { + fn fold_statement<'ast>( + &mut self, + s: Statement<'ast, T>, + aggressive: bool, + ) -> Vec> { match s { Statement::Constraint(quad, lin, message) => { let quad = self.fold_quadratic_combination(quad); @@ -163,9 +165,11 @@ impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer { .unwrap_or_else(|q| q) }) .collect(); - // to prevent the optimiser from replacing variables introduced by directives, add them to the ignored set - for o in d.outputs.iter().cloned() { - self.ignore.insert(o); + if !aggressive { + // to prevent the optimiser from replacing variables introduced by directives, add them to the ignored set + for o in d.outputs.iter().cloned() { + self.ignore.insert(o); + } } vec![Statement::Directive(Directive { inputs, ..d })] } @@ -174,6 +178,35 @@ impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer { s => fold_statement(self, s), } } +} + +impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer { + fn fold_statement(&mut self, s: Statement<'ast, T>) -> Vec> { + match s { + Statement::Block(statements) => { + // optimize aggressively and clean up in a second pass + let statements: Vec<_> = statements + .into_iter() + .flat_map(|s| self.fold_statement(s, true)) + .collect(); + + // clean up + let statements = statements + .into_iter() + .filter(|s| match s { + // we remove a directive iff it has a single output and this output is in the substitution map, meaning it was propagated + Statement::Directive(d) => { + d.outputs.len() > 1 || self.substitution.contains_key(&d.outputs[0]) + } + _ => true, + }) + .collect(); + + vec![Statement::Block(statements)] + } + s => self.fold_statement(s, false), + } + } fn fold_linear_combination(&mut self, lc: LinComb) -> LinComb { match lc diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index d72599032..9a7c4ac56 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1810,7 +1810,10 @@ impl<'ast, T: Field> Checker<'ast, T> { let e = FieldElementExpression::block(vec![], e); match assignee.get_type() { Type::FieldElement => Ok(vec![ - TypedAssemblyStatement::Assignment(assignee.clone(), e.clone()), + TypedAssemblyStatement::Assignment( + assignee.clone(), + e.clone().into(), + ), TypedAssemblyStatement::Constraint(assignee.into(), e), ]), ty => Err(ErrorInner { @@ -1821,7 +1824,7 @@ impl<'ast, T: Field> Checker<'ast, T> { } false => { let e = FieldElementExpression::block(vec![], e); - Ok(vec![TypedAssemblyStatement::Assignment(assignee, e)]) + Ok(vec![TypedAssemblyStatement::Assignment(assignee, e.into())]) } } } diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json index 9cfa458aa..2071634a8 100644 --- a/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_constant.json @@ -1,6 +1,6 @@ { "curves": ["Bn128"], - "max_constraint_count": 0, + "max_constraint_count": 2, "tests": [ { "input": { diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json index 69207f66e..8ac81f241 100644 --- a/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_write_variable.json @@ -1,6 +1,6 @@ { "curves": ["Bn128"], - "max_constraint_count": 1, + "max_constraint_count": 2, "tests": [ { "input": { diff --git a/zokrates_core_test/tests/tests/assembly/propagation/write_variable.json b/zokrates_core_test/tests/tests/assembly/propagation/write_variable.json new file mode 100644 index 000000000..a7220a6db --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/write_variable.json @@ -0,0 +1,18 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 1, + "tests": [ + { + "input": { + "values": [ + "42" + ] + }, + "output": { + "Ok": { + "value": "42" + } + } + } + ] +} \ No newline at end of file diff --git a/zokrates_core_test/tests/tests/assembly/propagation/write_variable.zok b/zokrates_core_test/tests/tests/assembly/propagation/write_variable.zok new file mode 100644 index 000000000..9585140ab --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/write_variable.zok @@ -0,0 +1,8 @@ +def main(field v) -> field { + field mut a = 0; + asm { + a <-- v; + a === v; + } + return a; +} \ No newline at end of file diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index 01c9dfb35..f33ab3de4 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -55,6 +55,7 @@ impl Interpreter { for statement in program.statements.into_iter() { match statement { + Statement::Block(..) => unreachable!(), Statement::Constraint(quad, lin, error) => match lin.is_assignee(&witness) { true => { let val = evaluate_quad(&witness, &quad).unwrap(); From e95cef8e90d5a680c2645bdc544c097447bd2c2f Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 1 Dec 2022 21:07:42 +0100 Subject: [PATCH 46/94] validate expressions, add more tests --- .../src/constant_argument_checker.rs | 62 +--------- zokrates_analysis/src/expression_validator.rs | 107 ++++++++++++++++++ zokrates_analysis/src/lib.rs | 24 +++- .../src/variable_write_remover.rs | 56 +++++++-- zokrates_ast/src/typed/integer.rs | 18 +++ .../assembly/bitwise_op_in_constraint.zok | 6 + .../assembly/variable_index_assignment.zok | 6 + .../variable_exponent_in_pow.zok | 3 + zokrates_core/src/semantics.rs | 59 ++++------ .../tests/tests/field_bitwise_op.json | 15 +++ .../tests/tests/field_bitwise_op.zok | 4 + 11 files changed, 252 insertions(+), 108 deletions(-) create mode 100644 zokrates_analysis/src/expression_validator.rs create mode 100644 zokrates_cli/examples/compile_errors/assembly/bitwise_op_in_constraint.zok create mode 100644 zokrates_cli/examples/compile_errors/assembly/variable_index_assignment.zok create mode 100644 zokrates_cli/examples/compile_errors/variable_exponent_in_pow.zok create mode 100644 zokrates_core_test/tests/tests/field_bitwise_op.json create mode 100644 zokrates_core_test/tests/tests/field_bitwise_op.zok diff --git a/zokrates_analysis/src/constant_argument_checker.rs b/zokrates_analysis/src/constant_argument_checker.rs index 5d5429b51..485cf9181 100644 --- a/zokrates_analysis/src/constant_argument_checker.rs +++ b/zokrates_analysis/src/constant_argument_checker.rs @@ -1,9 +1,7 @@ use std::fmt; use zokrates_ast::common::FlatEmbed; use zokrates_ast::typed::{ - result_folder::ResultFolder, - result_folder::{fold_field_expression, fold_statement, fold_uint_expression_inner}, - Constant, EmbedCall, FieldElementExpression, TypedStatement, UBitwidth, UExpressionInner, + result_folder::fold_statement, result_folder::ResultFolder, Constant, EmbedCall, TypedStatement, }; use zokrates_ast::typed::{DefinitionRhs, TypedProgram}; use zokrates_field::Field; @@ -71,62 +69,4 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ConstantArgumentChecker { s => fold_statement(self, s), } } - - fn fold_field_expression( - &mut self, - e: FieldElementExpression<'ast, T>, - ) -> Result, Self::Error> { - match e { - FieldElementExpression::Pow(box e, box exp) => { - let e = self.fold_field_expression(e)?; - let exp = self.fold_uint_expression(exp)?; - - match exp.as_inner() { - UExpressionInner::Value(_) => Ok(FieldElementExpression::Pow(box e, box exp)), - exp => Err(Error(format!( - "Found non-constant exponent in pow expression `{}**{}`", - e, - exp.clone().annotate(UBitwidth::B32) - ))), - } - } - e => fold_field_expression(self, e), - } - } - - fn fold_uint_expression_inner( - &mut self, - bitwidth: UBitwidth, - e: UExpressionInner<'ast, T>, - ) -> Result, Error> { - match e { - UExpressionInner::LeftShift(box e, box by) => { - let e = self.fold_uint_expression(e)?; - let by = self.fold_uint_expression(by)?; - - match by.as_inner() { - UExpressionInner::Value(_) => Ok(UExpressionInner::LeftShift(box e, box by)), - by => Err(Error(format!( - "Cannot shift by a variable value, found `{} << {}`", - e, - by.clone().annotate(UBitwidth::B32) - ))), - } - } - UExpressionInner::RightShift(box e, box by) => { - let e = self.fold_uint_expression(e)?; - let by = self.fold_uint_expression(by)?; - - match by.as_inner() { - UExpressionInner::Value(_) => Ok(UExpressionInner::RightShift(box e, box by)), - by => Err(Error(format!( - "Cannot shift by a variable value, found `{} >> {}`", - e, - by.clone().annotate(UBitwidth::B32) - ))), - } - } - e => fold_uint_expression_inner(self, bitwidth, e), - } - } } diff --git a/zokrates_analysis/src/expression_validator.rs b/zokrates_analysis/src/expression_validator.rs new file mode 100644 index 000000000..3ed46b02c --- /dev/null +++ b/zokrates_analysis/src/expression_validator.rs @@ -0,0 +1,107 @@ +use std::fmt; +use zokrates_ast::typed::result_folder::{ + fold_assembly_statement, fold_field_expression, fold_uint_expression_inner, ResultFolder, +}; +use zokrates_ast::typed::{ + FieldElementExpression, TypedAssemblyStatement, TypedProgram, UBitwidth, UExpressionInner, +}; +use zokrates_field::Field; + +#[derive(Debug, PartialEq, Eq)] +pub struct Error(String); + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +pub struct ExpressionValidator; + +impl ExpressionValidator { + pub fn validate(p: TypedProgram) -> Result, Error> { + ExpressionValidator.fold_program(p) + } +} + +impl<'ast, T: Field> ResultFolder<'ast, T> for ExpressionValidator { + type Error = Error; + + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + match s { + // we allow more dynamic expressions in witness generation + TypedAssemblyStatement::Assignment(_, _) => Ok(s), + s => fold_assembly_statement(self, s), + } + } + + fn fold_field_expression( + &mut self, + e: FieldElementExpression<'ast, T>, + ) -> Result, Self::Error> { + match e { + // these should have been propagated away + FieldElementExpression::And(_, _) + | FieldElementExpression::Or(_, _) + | FieldElementExpression::Xor(_, _) + | FieldElementExpression::LeftShift(_, _) + | FieldElementExpression::RightShift(_, _) => Err(Error(format!( + "Found non-constant bitwise operation in field element expression `{}`", + e + ))), + FieldElementExpression::Pow(box e, box exp) => { + let e = self.fold_field_expression(e)?; + let exp = self.fold_uint_expression(exp)?; + + match exp.as_inner() { + UExpressionInner::Value(_) => Ok(FieldElementExpression::Pow(box e, box exp)), + exp => Err(Error(format!( + "Found non-constant exponent in power expression `{}**{}`", + e, + exp.clone().annotate(UBitwidth::B32) + ))), + } + } + e => fold_field_expression(self, e), + } + } + + fn fold_uint_expression_inner( + &mut self, + bitwidth: UBitwidth, + e: UExpressionInner<'ast, T>, + ) -> Result, Error> { + match e { + UExpressionInner::LeftShift(box e, box by) => { + let e = self.fold_uint_expression(e)?; + let by = self.fold_uint_expression(by)?; + + match by.as_inner() { + UExpressionInner::Value(_) => Ok(UExpressionInner::LeftShift(box e, box by)), + by => Err(Error(format!( + "Cannot shift by a variable value, found `{} << {}`", + e, + by.clone().annotate(UBitwidth::B32) + ))), + } + } + UExpressionInner::RightShift(box e, box by) => { + let e = self.fold_uint_expression(e)?; + let by = self.fold_uint_expression(by)?; + + match by.as_inner() { + UExpressionInner::Value(_) => Ok(UExpressionInner::RightShift(box e, box by)), + by => Err(Error(format!( + "Cannot shift by a variable value, found `{} >> {}`", + e, + by.clone().annotate(UBitwidth::B32) + ))), + } + } + e => fold_uint_expression_inner(self, bitwidth, e), + } + } +} diff --git a/zokrates_analysis/src/lib.rs b/zokrates_analysis/src/lib.rs index 78db874c1..8d198a305 100644 --- a/zokrates_analysis/src/lib.rs +++ b/zokrates_analysis/src/lib.rs @@ -13,6 +13,7 @@ mod condition_redefiner; mod constant_argument_checker; mod constant_resolver; mod dead_code; +mod expression_validator; mod flat_propagation; mod flatten_complex_types; mod log_ignorer; @@ -40,6 +41,7 @@ use self::variable_write_remover::VariableWriteRemover; use crate::assembly_transformer::AssemblyTransformer; use crate::constant_resolver::ConstantResolver; use crate::dead_code::DeadCodeEliminator; +use crate::expression_validator::ExpressionValidator; use crate::panic_extractor::PanicExtractor; pub use crate::zir_propagation::ZirPropagator; use std::fmt; @@ -56,6 +58,8 @@ pub enum Error { NonConstantArgument(self::constant_argument_checker::Error), OutOfBounds(self::out_of_bounds::Error), Assembly(self::assembly_transformer::Error), + VariableIndex(self::variable_write_remover::Error), + InvalidExpression(self::expression_validator::Error), } impl From for Error { @@ -94,6 +98,18 @@ impl From for Error { } } +impl From for Error { + fn from(e: variable_write_remover::Error) -> Self { + Error::VariableIndex(e) + } +} + +impl From for Error { + fn from(e: expression_validator::Error) -> Self { + Error::InvalidExpression(e) + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { @@ -103,6 +119,8 @@ impl fmt::Display for Error { Error::NonConstantArgument(e) => write!(f, "{}", e), Error::OutOfBounds(e) => write!(f, "{}", e), Error::Assembly(e) => write!(f, "{}", e), + Error::VariableIndex(e) => write!(f, "{}", e), + Error::InvalidExpression(e) => write!(f, "{}", e), } } } @@ -151,6 +169,10 @@ pub fn analyse<'ast, T: Field>( let r = StructConcretizer::concretize(r); log::trace!("\n{}", r); + // validate expressions + log::debug!("Static analyser: Validate expressions"); + let r = ExpressionValidator::validate(r).map_err(Error::from)?; + // generate abi log::debug!("Static analyser: Generate abi"); let abi = r.abi(); @@ -167,7 +189,7 @@ pub fn analyse<'ast, T: Field>( // remove assignment to variable index log::debug!("Static analyser: Remove variable index"); - let r = VariableWriteRemover::apply(r); + let r = VariableWriteRemover::apply(r).map_err(Error::from)?; log::trace!("\n{}", r); // detect non constant shifts and constant lt bounds diff --git a/zokrates_analysis/src/variable_write_remover.rs b/zokrates_analysis/src/variable_write_remover.rs index 7d88336cc..525b808ec 100644 --- a/zokrates_analysis/src/variable_write_remover.rs +++ b/zokrates_analysis/src/variable_write_remover.rs @@ -5,11 +5,22 @@ //! @date 2018 use std::collections::HashSet; -use zokrates_ast::typed::folder::*; +use std::fmt; +use zokrates_ast::typed::result_folder::ResultFolder; +use zokrates_ast::typed::result_folder::*; use zokrates_ast::typed::types::{MemberId, Type}; use zokrates_ast::typed::*; use zokrates_field::Field; +#[derive(Debug)] +pub struct Error(String); + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + pub struct VariableWriteRemover; impl<'ast> VariableWriteRemover { @@ -17,7 +28,7 @@ impl<'ast> VariableWriteRemover { VariableWriteRemover } - pub fn apply(p: TypedProgram) -> TypedProgram { + pub fn apply(p: TypedProgram) -> Result, Error> { let mut remover = VariableWriteRemover::new(); remover.fold_program(p) } @@ -452,14 +463,35 @@ fn is_constant(assignee: &TypedAssignee) -> bool { } } -impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover { - fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec> { +impl<'ast, T: Field> ResultFolder<'ast, T> for VariableWriteRemover { + type Error = Error; + + fn fold_assembly_statement( + &mut self, + s: TypedAssemblyStatement<'ast, T>, + ) -> Result, Self::Error> { + match s { + TypedAssemblyStatement::Assignment(a, e) if is_constant(&a) => { + Ok(TypedAssemblyStatement::Assignment(a, e)) + } + TypedAssemblyStatement::Assignment(a, _) => Err(Error(format!( + "Cannot assign to an assignee with a variable index `{}`", + a + ))), + s => Ok(s), + } + } + + fn fold_statement( + &mut self, + s: TypedStatement<'ast, T>, + ) -> Result>, Self::Error> { match s { TypedStatement::Definition(assignee, DefinitionRhs::Expression(expr)) => { - let expr = self.fold_expression(expr); + let expr = self.fold_expression(expr)?; if is_constant(&assignee) { - vec![TypedStatement::definition(assignee, expr)] + Ok(vec![TypedStatement::definition(assignee, expr)]) } else { // Note: here we redefine the whole object, ideally we would only redefine some of it // Example: `a[0][i] = 42` we redefine `a` but we could redefine just `a[0]` @@ -486,28 +518,28 @@ impl<'ast, T: Field> Folder<'ast, T> for VariableWriteRemover { .into(), }; - let base = self.fold_expression(base); + let base = self.fold_expression(base)?; let indices = indices .into_iter() .map(|a| match a { Access::Select(box i) => { - Access::Select(box self.fold_uint_expression(i)) + Ok(Access::Select(box self.fold_uint_expression(i)?)) } - a => a, + a => Ok(a), }) - .collect(); + .collect::>()?; let mut range_checks = HashSet::new(); let e = Self::choose_many(base, indices, expr, &mut range_checks); - range_checks + Ok(range_checks .into_iter() .chain(std::iter::once(TypedStatement::definition( TypedAssignee::Identifier(variable), e, ))) - .collect() + .collect()) } } s => fold_statement(self, s), diff --git a/zokrates_ast/src/typed/integer.rs b/zokrates_ast/src/typed/integer.rs index 4af5de121..df613edbf 100644 --- a/zokrates_ast/src/typed/integer.rs +++ b/zokrates_ast/src/typed/integer.rs @@ -446,6 +446,24 @@ impl<'ast, T: Field> FieldElementExpression<'ast, T> { box Self::try_from_int(e1)?, box Self::try_from_int(e2)?, )), + IntExpression::And(box e1, box e2) => Ok(Self::And( + box Self::try_from_int(e1)?, + box Self::try_from_int(e2)?, + )), + IntExpression::Or(box e1, box e2) => Ok(Self::Or( + box Self::try_from_int(e1)?, + box Self::try_from_int(e2)?, + )), + IntExpression::Xor(box e1, box e2) => Ok(Self::Xor( + box Self::try_from_int(e1)?, + box Self::try_from_int(e2)?, + )), + IntExpression::LeftShift(box e1, box e2) => { + Ok(Self::LeftShift(box Self::try_from_int(e1)?, box e2)) + } + IntExpression::RightShift(box e1, box e2) => { + Ok(Self::RightShift(box Self::try_from_int(e1)?, box e2)) + } IntExpression::Pos(box e) => Ok(Self::Pos(box Self::try_from_int(e)?)), IntExpression::Neg(box e) => Ok(Self::Neg(box Self::try_from_int(e)?)), IntExpression::Conditional(c) => Ok(Self::Conditional(ConditionalExpression::new( diff --git a/zokrates_cli/examples/compile_errors/assembly/bitwise_op_in_constraint.zok b/zokrates_cli/examples/compile_errors/assembly/bitwise_op_in_constraint.zok new file mode 100644 index 000000000..3b54fa1ff --- /dev/null +++ b/zokrates_cli/examples/compile_errors/assembly/bitwise_op_in_constraint.zok @@ -0,0 +1,6 @@ +def main(field mut a, u32 i) { + asm { + a <-- a << i; // bitwise operations are allowed in witness generation + a === a << i; // but not in constraints + } +} \ No newline at end of file diff --git a/zokrates_cli/examples/compile_errors/assembly/variable_index_assignment.zok b/zokrates_cli/examples/compile_errors/assembly/variable_index_assignment.zok new file mode 100644 index 000000000..ceed47f65 --- /dev/null +++ b/zokrates_cli/examples/compile_errors/assembly/variable_index_assignment.zok @@ -0,0 +1,6 @@ +def main(field[2] mut a, u32 i) -> field[2] { + asm { + a[i] <== 42; // assigning to a variable index is not allowed in assembly + } + return a; +} \ No newline at end of file diff --git a/zokrates_cli/examples/compile_errors/variable_exponent_in_pow.zok b/zokrates_cli/examples/compile_errors/variable_exponent_in_pow.zok new file mode 100644 index 000000000..14586fadd --- /dev/null +++ b/zokrates_cli/examples/compile_errors/variable_exponent_in_pow.zok @@ -0,0 +1,3 @@ +def main(field a, u32 b) -> field { + return a**b; +} \ No newline at end of file diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index 922d06c39..67605d58d 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -1794,16 +1794,15 @@ impl<'ast, T: Field> Checker<'ast, T> { match stat.value { AssemblyStatement::Assignment(assignee, expression, constrained) => { let assignee = self.check_assignee(assignee, module_id, types)?; - let checked_e = self.check_expression(expression, module_id, types)?; + let e = self.check_expression(expression, module_id, types)?; - let e = match checked_e { - TypedExpression::FieldElement(e) => Ok(e), - TypedExpression::Int(e) => Ok(FieldElementExpression::try_from_int(e).unwrap()), - e => Err(ErrorInner { - pos: Some(pos), - message: format!("The right hand side of an assembly assignment must be of type field, found {}", e.get_type()) - }), - }?; + let e = FieldElementExpression::try_from_typed(e).map_err(|e| ErrorInner { + pos: Some(pos), + message: format!( + "Expected right hand side of an assembly assignment to be of type field, found {}", + e.get_type(), + ), + })?; match constrained { true => { @@ -1833,29 +1832,21 @@ impl<'ast, T: Field> Checker<'ast, T> { let lhs = self.check_expression(lhs, module_id, types)?; let rhs = self.check_expression(rhs, module_id, types)?; - let (lhs, rhs) = match (lhs, rhs) { - (TypedExpression::FieldElement(lhs), TypedExpression::FieldElement(rhs)) => { - Ok((lhs, rhs)) - } - (TypedExpression::FieldElement(lhs), TypedExpression::Int(rhs)) => { - Ok((lhs, FieldElementExpression::try_from_int(rhs).unwrap())) - } - (TypedExpression::Int(lhs), TypedExpression::FieldElement(rhs)) => { - Ok((FieldElementExpression::try_from_int(lhs).unwrap(), rhs)) - } - (TypedExpression::Int(lhs), TypedExpression::Int(rhs)) => Ok(( - FieldElementExpression::try_from_int(lhs).unwrap(), - FieldElementExpression::try_from_int(rhs).unwrap(), - )), - (e1, e2) => Err(ErrorInner { - pos: Some(pos), - message: format!( - "Assembly constraint expected expressions of type field, found {}, {}", - e1.get_type(), - e2.get_type() - ), - }), - }?; + let lhs = FieldElementExpression::try_from_typed(lhs).map_err(|e| ErrorInner { + pos: Some(pos), + message: format!( + "Expected left hand side of a constraint to be of type field, found {}", + e.get_type(), + ), + })?; + + let rhs = FieldElementExpression::try_from_typed(rhs).map_err(|e| ErrorInner { + pos: Some(pos), + message: format!( + "Expected right hand side of a constraint to be of type field, found {}", + e.get_type(), + ), + })?; Ok(vec![TypedAssemblyStatement::Constraint( lhs, @@ -2142,7 +2133,7 @@ impl<'ast, T: Field> Checker<'ast, T> { let pos = assignee.pos(); // check that the assignee is declared match assignee.value { - Assignee::Identifier(variable_name) => match self.scope.get(&*variable_name) { + Assignee::Identifier(variable_name) => match self.scope.get(variable_name) { Some(info) => match info.is_mutable { false => Err(ErrorInner { pos: Some(assignee.pos()), @@ -2451,7 +2442,7 @@ impl<'ast, T: Field> Checker<'ast, T> { Expression::BooleanConstant(b) => Ok(BooleanExpression::Value(b).into()), Expression::Identifier(name) => { // check that `id` is defined in the scope - match self.scope.get(&*name) { + match self.scope.get(name) { Some(info) => { let id = info.id; match info.ty.clone() { diff --git a/zokrates_core_test/tests/tests/field_bitwise_op.json b/zokrates_core_test/tests/tests/field_bitwise_op.json new file mode 100644 index 000000000..62ed50d55 --- /dev/null +++ b/zokrates_core_test/tests/tests/field_bitwise_op.json @@ -0,0 +1,15 @@ +{ + "max_constraint_count": 1, + "tests": [ + { + "input": { + "values": [] + }, + "output": { + "Ok": { + "value": "2" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/field_bitwise_op.zok b/zokrates_core_test/tests/tests/field_bitwise_op.zok new file mode 100644 index 000000000..cecae79cf --- /dev/null +++ b/zokrates_core_test/tests/tests/field_bitwise_op.zok @@ -0,0 +1,4 @@ +def main() -> field { + field a = 1 << 2; // constant bitwise operations are allowed as they get propagated away + return a; +} \ No newline at end of file From ca6b3688dc1cf3105be182b279487c125d24baa5 Mon Sep 17 00:00:00 2001 From: dark64 Date: Fri, 2 Dec 2022 16:09:51 +0100 Subject: [PATCH 47/94] fix tests --- zokrates_ast/src/typed/integer.rs | 5 ----- zokrates_core_test/tests/tests/field_bitwise_op.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/zokrates_ast/src/typed/integer.rs b/zokrates_ast/src/typed/integer.rs index df613edbf..507ce9174 100644 --- a/zokrates_ast/src/typed/integer.rs +++ b/zokrates_ast/src/typed/integer.rs @@ -861,11 +861,6 @@ mod tests { let should_error = vec![ BigUint::parse_bytes(b"99999999999999999999999999999999999999999999999999999999999999999999999999999999999", 10).unwrap().into(), - IntExpression::xor(n.clone(), n.clone()), - IntExpression::or(n.clone(), n.clone()), - IntExpression::and(n.clone(), n.clone()), - IntExpression::left_shift(n.clone(), i.clone()), - IntExpression::right_shift(n.clone(), i.clone()), IntExpression::not(n.clone()), ]; diff --git a/zokrates_core_test/tests/tests/field_bitwise_op.json b/zokrates_core_test/tests/tests/field_bitwise_op.json index 62ed50d55..2960fe4c8 100644 --- a/zokrates_core_test/tests/tests/field_bitwise_op.json +++ b/zokrates_core_test/tests/tests/field_bitwise_op.json @@ -7,7 +7,7 @@ }, "output": { "Ok": { - "value": "2" + "value": "4" } } } From 9f900ad11f601d1372b70b5a8005f3b47d61c728 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 5 Dec 2022 21:45:37 +0100 Subject: [PATCH 48/94] struct asm test --- .../propagation/struct_write_variable.json | 23 +++++++++++++++++++ .../propagation/struct_write_variable.zok | 12 ++++++++++ 2 files changed, 35 insertions(+) create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.zok diff --git a/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.json b/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.json new file mode 100644 index 000000000..95caa1b2d --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.json @@ -0,0 +1,23 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 4, + "tests": [ + { + "input": { + "values": [ + { + "a": ["0", "0"] + }, + "42" + ] + }, + "output": { + "Ok": { + "value": { + "a": ["42", "84"] + } + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.zok b/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.zok new file mode 100644 index 000000000..f1fa62f53 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/struct_write_variable.zok @@ -0,0 +1,12 @@ +struct Foo { + field[2] a; +} + +def main(Foo mut foo, field v) -> Foo { + u32 i = 0; + asm { + foo.a[i] <== v; + foo.a[i + 1] <== foo.a[i] * 2; + } + return foo; +} \ No newline at end of file From 0cdcedd9de59983c54e88bbb849c684b2ea1313b Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 12 Dec 2022 16:28:16 +0100 Subject: [PATCH 49/94] allow user-provided randomness in setup --- Cargo.lock | 5 ++- zokrates_ark/src/gm17.rs | 12 +++--- zokrates_ark/src/groth16.rs | 12 +++--- zokrates_ark/src/marlin.rs | 14 ++----- zokrates_bellman/Cargo.toml | 4 +- zokrates_bellman/src/groth16.rs | 20 ++++++---- zokrates_bellman/src/lib.rs | 37 +++++++++++-------- zokrates_book/src/toolbox/trusted_setup.md | 2 +- .../mpc_tutorial/{circuit.zok => program.zok} | 0 .../examples/book/mpc_tutorial/test.sh | 4 +- zokrates_cli/src/bin.rs | 1 + zokrates_cli/src/common.rs | 21 +++++++++++ zokrates_cli/src/ops/generate_proof.rs | 18 ++++++++- zokrates_cli/src/ops/mpc/beacon.rs | 11 +++--- zokrates_cli/src/ops/mpc/contribute.rs | 17 +++++---- zokrates_cli/src/ops/setup.rs | 18 ++++++++- zokrates_cli/src/ops/universal_setup.rs | 18 ++++++++- zokrates_js/Cargo.toml | 1 + zokrates_js/src/lib.rs | 10 +++-- zokrates_proof_systems/Cargo.toml | 2 +- zokrates_proof_systems/src/lib.rs | 13 ++++--- 21 files changed, 159 insertions(+), 81 deletions(-) rename zokrates_cli/examples/book/mpc_tutorial/{circuit.zok => program.zok} (100%) create mode 100644 zokrates_cli/src/common.rs diff --git a/Cargo.lock b/Cargo.lock index f250f1fbb..4d1c40b30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3041,11 +3041,11 @@ name = "zokrates_bellman" version = "0.1.0" dependencies = [ "bellman_ce", - "getrandom", "hex 0.4.3", "pairing_ce", "phase2", "rand 0.4.6", + "rand 0.8.5", "zokrates_ast", "zokrates_field", "zokrates_interpreter", @@ -3216,6 +3216,7 @@ dependencies = [ "js-sys", "json", "lazy_static", + "rand 0.8.5", "serde", "serde_json", "toml", @@ -3264,7 +3265,7 @@ dependencies = [ "getrandom", "hex 0.4.3", "primitive-types", - "rand 0.4.6", + "rand 0.8.5", "regex 0.2.11", "serde", "zokrates_ast", diff --git a/zokrates_ark/src/gm17.rs b/zokrates_ark/src/gm17.rs index 209a1abdd..6983d1c63 100644 --- a/zokrates_ark/src/gm17.rs +++ b/zokrates_ark/src/gm17.rs @@ -9,19 +9,18 @@ use zokrates_field::{ArkFieldExtensions, Field}; use crate::Computation; use crate::{parse_fr, parse_g1, parse_g2}; use crate::{serialization, Ark}; -use rand_0_8::{rngs::StdRng, SeedableRng}; +use rand_0_8::{CryptoRng, RngCore}; use zokrates_ast::ir::{ProgIterator, Statement, Witness}; use zokrates_proof_systems::gm17::{ProofPoints, VerificationKey, GM17}; use zokrates_proof_systems::Scheme; use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair}; impl NonUniversalBackend for Ark { - fn setup>>( + fn setup>, R: RngCore + CryptoRng>( program: ProgIterator, + rng: &mut R, ) -> SetupKeypair { let computation = Computation::without_witness(program); - - let rng = &mut StdRng::from_entropy(); let (pk, vk) = ArkGM17::::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); @@ -41,10 +40,11 @@ impl NonUniversalBackend for Ark { } impl Backend for Ark { - fn generate_proof>>( + fn generate_proof>, R: RngCore + CryptoRng>( program: ProgIterator, witness: Witness, proving_key: Vec, + rng: &mut R, ) -> Proof { let computation = Computation::with_witness(program, witness); @@ -59,9 +59,7 @@ impl Backend for Ark { ) .unwrap(); - let rng = &mut StdRng::from_entropy(); let proof = ArkGM17::::prove(&pk, computation, rng).unwrap(); - let proof_points = ProofPoints { a: parse_g1::(&proof.a), b: parse_g2::(&proof.b), diff --git a/zokrates_ark/src/groth16.rs b/zokrates_ark/src/groth16.rs index 617d34ede..e96f8a62e 100644 --- a/zokrates_ark/src/groth16.rs +++ b/zokrates_ark/src/groth16.rs @@ -11,7 +11,7 @@ use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair}; use crate::Computation; use crate::{parse_fr, serialization, Ark}; use crate::{parse_g1, parse_g2}; -use rand_0_8::{rngs::StdRng, SeedableRng}; +use rand_0_8::{CryptoRng, RngCore}; use zokrates_ast::ir::{ProgIterator, Statement, Witness}; use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16}; use zokrates_proof_systems::Scheme; @@ -19,10 +19,11 @@ use zokrates_proof_systems::Scheme; const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications."; impl Backend for Ark { - fn generate_proof>>( + fn generate_proof>, R: RngCore + CryptoRng>( program: ProgIterator, witness: Witness, proving_key: Vec, + rng: &mut R, ) -> Proof { println!("{}", G16_WARNING); @@ -39,9 +40,7 @@ impl Backend for Ark { ) .unwrap(); - let rng = &mut StdRng::from_entropy(); let proof = Groth16::::prove(&pk, computation, rng).unwrap(); - let proof_points = ProofPoints { a: parse_g1::(&proof.a), b: parse_g2::(&proof.b), @@ -86,14 +85,13 @@ impl Backend for Ark { } impl NonUniversalBackend for Ark { - fn setup>>( + fn setup>, R: RngCore + CryptoRng>( program: ProgIterator, + rng: &mut R, ) -> SetupKeypair { println!("{}", G16_WARNING); let computation = Computation::without_witness(program); - - let rng = &mut StdRng::from_entropy(); let (pk, vk) = Groth16::::circuit_specific_setup(computation, rng).unwrap(); let mut pk_vec: Vec = Vec::new(); diff --git a/zokrates_ark/src/marlin.rs b/zokrates_ark/src/marlin.rs index cc85f6a24..1bb21c678 100644 --- a/zokrates_ark/src/marlin.rs +++ b/zokrates_ark/src/marlin.rs @@ -17,7 +17,7 @@ use ark_poly_commit::{ }; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use digest::Digest; -use rand_0_8::{Error, RngCore, SeedableRng}; +use rand_0_8::{CryptoRng, Error, RngCore, SeedableRng}; use sha3::Keccak256; use std::marker::PhantomData; @@ -116,9 +116,7 @@ type MarlinInst = ArkMarlin< >; impl UniversalBackend for Ark { - fn universal_setup(size: u32) -> Vec { - let rng = &mut rand_0_8::rngs::StdRng::from_entropy(); - + fn universal_setup(size: u32, rng: &mut R) -> Vec { let srs = MarlinInst::::universal_setup( 2usize.pow(size), 2usize.pow(size), @@ -128,9 +126,7 @@ impl UniversalBackend for Ark .unwrap(); let mut res = vec![]; - srs.serialize(&mut res).unwrap(); - res } @@ -210,15 +206,14 @@ impl UniversalBackend for Ark } impl Backend for Ark { - fn generate_proof>>( + fn generate_proof>, R: RngCore + CryptoRng>( program: ProgIterator, witness: Witness, proving_key: Vec, + rng: &mut R, ) -> Proof { let computation = Computation::with_witness(program, witness); - let rng = &mut rand_0_8::rngs::StdRng::from_entropy(); - let pk = IndexProverKey::< <::ArkEngine as PairingEngine>::Fr, MarlinKZG10< @@ -229,7 +224,6 @@ impl Backend for Ark { .unwrap(); let public_inputs = computation.public_inputs_values(); - let inputs = public_inputs.iter().map(parse_fr::).collect::>(); let proof = MarlinInst::::prove(&pk, computation, rng).unwrap(); diff --git a/zokrates_bellman/Cargo.toml b/zokrates_bellman/Cargo.toml index 852b1fbed..526078b7f 100644 --- a/zokrates_bellman/Cargo.toml +++ b/zokrates_bellman/Cargo.toml @@ -15,8 +15,8 @@ zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", bellman = { package = "bellman_ce", version = "^0.3", default-features = false } pairing = { package = "pairing_ce", version = "^0.21" } phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false } -rand_0_4 = { version = "0.4", package = "rand" }# -getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] } +rand_0_4 = { version = "0.4", package = "rand" } +rand_0_8 = { version = "0.8", package = "rand" } hex = "0.4.2" [dev-dependencies] diff --git a/zokrates_bellman/src/groth16.rs b/zokrates_bellman/src/groth16.rs index c918ccf5d..66df17891 100644 --- a/zokrates_bellman/src/groth16.rs +++ b/zokrates_bellman/src/groth16.rs @@ -8,11 +8,12 @@ use zokrates_field::BellmanFieldExtensions; use zokrates_field::Field; use zokrates_proof_systems::{Backend, MpcBackend, NonUniversalBackend, Proof, SetupKeypair}; -use crate::Bellman; use crate::Computation; +use crate::{get_random_seed, Bellman}; use crate::{parse_g1, parse_g2}; use phase2::MPCParameters; -use rand_0_4::Rng; +use rand_0_4::{ChaChaRng, SeedableRng}; +use rand_0_8::{CryptoRng, RngCore}; use std::io::{Read, Write}; use zokrates_ast::ir::{ProgIterator, Statement, Witness}; use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16}; @@ -21,10 +22,11 @@ use zokrates_proof_systems::Scheme; const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications."; impl Backend for Bellman { - fn generate_proof>>( + fn generate_proof>, R: RngCore + CryptoRng>( program: ProgIterator, witness: Witness, proving_key: Vec, + rng: &mut R, ) -> Proof { println!("{}", G16_WARNING); @@ -37,7 +39,7 @@ impl Backend for Bellman { .map(|e| format!("0x{}", to_hex(e))) .collect(); - let proof = computation.prove(¶ms); + let proof = computation.prove(¶ms, rng); let proof_points = ProofPoints { a: parse_g1::(&proof.a), b: parse_g2::(&proof.b), @@ -84,12 +86,13 @@ impl Backend for Bellman { } impl NonUniversalBackend for Bellman { - fn setup>>( + fn setup>, R: RngCore + CryptoRng>( program: ProgIterator, + rng: &mut R, ) -> SetupKeypair { println!("{}", G16_WARNING); - let parameters = Computation::without_witness(program).setup(); + let parameters = Computation::without_witness(program).setup(rng); let mut pk: Vec = Vec::new(); parameters.write(&mut pk).unwrap(); @@ -110,7 +113,7 @@ impl MpcBackend for Bellman { Ok(()) } - fn contribute( + fn contribute( params: &mut R, rng: &mut G, output: &mut W, @@ -118,6 +121,9 @@ impl MpcBackend for Bellman { let mut params = MPCParameters::::read(params, true).map_err(|e| e.to_string())?; + let seed = get_random_seed(rng); + let rng = &mut ChaChaRng::from_seed(seed.as_ref()); + let hash = params.contribute(rng); params.write(output).map_err(|e| e.to_string())?; diff --git a/zokrates_bellman/src/lib.rs b/zokrates_bellman/src/lib.rs index 4bf396245..3882adc21 100644 --- a/zokrates_bellman/src/lib.rs +++ b/zokrates_bellman/src/lib.rs @@ -16,6 +16,7 @@ use zokrates_field::BellmanFieldExtensions; use zokrates_field::Field; use rand_0_4::ChaChaRng; +use rand_0_8::{CryptoRng, RngCore}; pub use self::parse::*; @@ -148,22 +149,26 @@ impl>> } } -impl>> Computation { - fn get_random_seed(&self) -> Result<[u32; 8], getrandom::Error> { - let mut seed = [0u8; 32]; - getrandom::getrandom(&mut seed)?; - - use std::mem::transmute; - // This is safe because we are just reinterpreting the bytes (u8[32] -> u32[8]), - // byte order or the actual content does not matter here as this is used - // as a random seed for the rng. - let seed: [u32; 8] = unsafe { transmute(seed) }; - Ok(seed) - } +pub fn get_random_seed(rng: &mut R) -> [u32; 8] { + let mut seed = [0u8; 32]; + rng.fill_bytes(&mut seed); + + use std::mem::transmute; + // This is safe because we are just reinterpreting the bytes (u8[32] -> u32[8]), + // byte order or the actual content does not matter here as this is used + // as a random seed for the rng (rand 0.4) + let seed: [u32; 8] = unsafe { transmute(seed) }; + seed +} - pub fn prove(self, params: &Parameters) -> Proof { +impl>> Computation { + pub fn prove( + self, + params: &Parameters, + rng: &mut R, + ) -> Proof { use rand_0_4::SeedableRng; - let seed = self.get_random_seed().unwrap(); + let seed = get_random_seed(rng); let rng = &mut ChaChaRng::from_seed(seed.as_ref()); // extract public inputs @@ -186,9 +191,9 @@ impl>> Co .collect() } - pub fn setup(self) -> Parameters { + pub fn setup(self, rng: &mut R) -> Parameters { use rand_0_4::SeedableRng; - let seed = self.get_random_seed().unwrap(); + let seed = get_random_seed(rng); let rng = &mut ChaChaRng::from_seed(seed.as_ref()); // run setup phase generate_random_parameters(self, rng).unwrap() diff --git a/zokrates_book/src/toolbox/trusted_setup.md b/zokrates_book/src/toolbox/trusted_setup.md index aa05b4f03..84bdef4a2 100644 --- a/zokrates_book/src/toolbox/trusted_setup.md +++ b/zokrates_book/src/toolbox/trusted_setup.md @@ -14,7 +14,7 @@ We will start this tutorial by using ZoKrates to compile a basic program. First, we create a new file named `program.zok` with the following content: ```zokrates -{{#include ../../../zokrates_cli/examples/book/mpc_tutorial/circuit.zok}} +{{#include ../../../zokrates_cli/examples/book/mpc_tutorial/program.zok}} ``` We compile the program using the `compile` command. diff --git a/zokrates_cli/examples/book/mpc_tutorial/circuit.zok b/zokrates_cli/examples/book/mpc_tutorial/program.zok similarity index 100% rename from zokrates_cli/examples/book/mpc_tutorial/circuit.zok rename to zokrates_cli/examples/book/mpc_tutorial/program.zok diff --git a/zokrates_cli/examples/book/mpc_tutorial/test.sh b/zokrates_cli/examples/book/mpc_tutorial/test.sh index 743b881b3..979f1e08b 100755 --- a/zokrates_cli/examples/book/mpc_tutorial/test.sh +++ b/zokrates_cli/examples/book/mpc_tutorial/test.sh @@ -7,8 +7,8 @@ function zokrates() { ZOKRATES_STDLIB=$stdlib $bin "$@" } -# compile the circuit -zokrates compile -i circuit.zok -o circuit +# compile the program +zokrates compile -i program.zok -o circuit # initialize the ceremony # this step requires phase1 files eg. phase1radix2m2 for circuits of 2^2 constraints diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 99a1b0838..62b0c1db4 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -10,6 +10,7 @@ extern crate lazy_static; mod cli_constants; +mod common; mod ops; use clap::{App, AppSettings, Arg}; diff --git a/zokrates_cli/src/common.rs b/zokrates_cli/src/common.rs new file mode 100644 index 000000000..f5f1e3cc0 --- /dev/null +++ b/zokrates_cli/src/common.rs @@ -0,0 +1,21 @@ +use blake2::{Blake2b, Digest}; +use byteorder::ReadBytesExt; +use rand_0_8::rngs::StdRng; +use rand_0_8::SeedableRng; + +pub fn get_seeded_rng(entropy: &str) -> StdRng { + let h = { + let mut h = Blake2b::default(); + h.input(&entropy.as_bytes()); + h.result() + }; + + let mut digest = &h[..]; + let mut seed = [0u8; 32]; + + for e in &mut seed { + *e = digest.read_u8().unwrap(); + } + + StdRng::from_seed(seed) +} diff --git a/zokrates_cli/src/ops/generate_proof.rs b/zokrates_cli/src/ops/generate_proof.rs index 2a62042a4..eff1715f4 100644 --- a/zokrates_cli/src/ops/generate_proof.rs +++ b/zokrates_cli/src/ops/generate_proof.rs @@ -1,5 +1,8 @@ use crate::cli_constants; +use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; +use rand_0_8::rngs::StdRng; +use rand_0_8::SeedableRng; use std::convert::TryFrom; use std::fs::File; use std::io::{BufReader, Read, Write}; @@ -79,6 +82,14 @@ pub fn subcommand() -> App<'static, 'static> { .possible_values(cli_constants::SCHEMES) .default_value(constants::G16), ) + .arg( + Arg::with_name("entropy") + .short("e") + .long("entropy") + .help("User provided randomness") + .takes_value(true) + .required(false), + ) } pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { @@ -166,7 +177,12 @@ fn cli_generate_proof< .read_to_end(&mut pk) .map_err(|why| format!("Could not read {}: {}", pk_path.display(), why))?; - let proof = B::generate_proof(program, witness, pk); + let mut rng = sub_matches + .value_of("entropy") + .map(|entropy| get_seeded_rng(entropy)) + .unwrap_or_else(|| StdRng::from_entropy()); + + let proof = B::generate_proof(program, witness, pk, &mut rng); let mut proof_file = File::create(proof_path).unwrap(); let proof = diff --git a/zokrates_cli/src/ops/mpc/beacon.rs b/zokrates_cli/src/ops/mpc/beacon.rs index b5af669e7..619a95ed9 100644 --- a/zokrates_cli/src/ops/mpc/beacon.rs +++ b/zokrates_cli/src/ops/mpc/beacon.rs @@ -1,5 +1,6 @@ use crate::cli_constants::MPC_DEFAULT_PATH; use clap::{App, Arg, ArgMatches, SubCommand}; +use rand_0_8::{rngs::StdRng, SeedableRng}; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::path::Path; @@ -87,9 +88,7 @@ fn cli_mpc_beacon, B: MpcBack // Create an RNG based on the outcome of the random beacon let mut rng = { - use byteorder::{BigEndian, ReadBytesExt}; - use rand_0_4::chacha::ChaChaRng; - use rand_0_4::SeedableRng; + use byteorder::ReadBytesExt; use sha2::{Digest, Sha256}; // The hash used for the beacon @@ -126,12 +125,12 @@ fn cli_mpc_beacon, B: MpcBack let mut digest = &cur_hash[..]; - let mut seed = [0u32; 8]; + let mut seed = [0u8; 32]; for e in &mut seed { - *e = digest.read_u32::().unwrap(); + *e = digest.read_u8().unwrap(); } - ChaChaRng::from_seed(&seed) + StdRng::from_seed(seed) }; let output_path = Path::new(sub_matches.value_of("output").unwrap()); diff --git a/zokrates_cli/src/ops/mpc/contribute.rs b/zokrates_cli/src/ops/mpc/contribute.rs index 3490f381b..2936e3c28 100644 --- a/zokrates_cli/src/ops/mpc/contribute.rs +++ b/zokrates_cli/src/ops/mpc/contribute.rs @@ -1,5 +1,9 @@ use crate::cli_constants::MPC_DEFAULT_PATH; use clap::{App, Arg, ArgMatches, SubCommand}; +use rand_0_8::{ + rngs::{OsRng, StdRng}, + Rng, SeedableRng, +}; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::path::Path; @@ -76,12 +80,10 @@ pub fn cli_mpc_contribute< // Create an RNG based on a mixture of system randomness and user provided randomness let mut rng = { use blake2::{Blake2b, Digest}; - use byteorder::{BigEndian, ReadBytesExt}; - use rand_0_4::chacha::ChaChaRng; - use rand_0_4::{OsRng, Rng, SeedableRng}; + use byteorder::ReadBytesExt; let h = { - let mut system_rng = OsRng::new().unwrap(); + let mut system_rng = OsRng::default(); let mut h = Blake2b::default(); // Gather 1024 bytes of entropy from the system @@ -97,13 +99,12 @@ pub fn cli_mpc_contribute< let mut digest = &h[..]; - // Interpret the first 32 bytes of the digest as 8 32-bit words - let mut seed = [0u32; 8]; + let mut seed = [0u8; 32]; for e in &mut seed { - *e = digest.read_u32::().unwrap(); + *e = digest.read_u8().unwrap(); } - ChaChaRng::from_seed(&seed) + StdRng::from_seed(seed) }; let output_path = Path::new(sub_matches.value_of("output").unwrap()); diff --git a/zokrates_cli/src/ops/setup.rs b/zokrates_cli/src/ops/setup.rs index e9e8a2166..d368463c0 100644 --- a/zokrates_cli/src/ops/setup.rs +++ b/zokrates_cli/src/ops/setup.rs @@ -1,5 +1,8 @@ use crate::cli_constants; +use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; +use rand_0_8::rngs::StdRng; +use rand_0_8::SeedableRng; use std::convert::TryFrom; use std::fs::File; use std::io::{BufReader, Write}; @@ -78,6 +81,14 @@ pub fn subcommand() -> App<'static, 'static> { .required(false) .default_value(cli_constants::UNIVERSAL_SETUP_DEFAULT_PATH), ) + .arg( + Arg::with_name("entropy") + .short("e") + .long("entropy") + .help("User provided randomness") + .takes_value(true) + .required(false), + ) } pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { @@ -181,8 +192,13 @@ fn cli_setup_non_universal< let pk_path = Path::new(sub_matches.value_of("proving-key-path").unwrap()); let vk_path = Path::new(sub_matches.value_of("verification-key-path").unwrap()); + let mut rng = sub_matches + .value_of("entropy") + .map(|entropy| get_seeded_rng(entropy)) + .unwrap_or_else(|| StdRng::from_entropy()); + // run setup phase - let keypair = B::setup(program); + let keypair = B::setup(program, &mut rng); // write verification key let mut vk_file = File::create(vk_path) diff --git a/zokrates_cli/src/ops/universal_setup.rs b/zokrates_cli/src/ops/universal_setup.rs index 98bc88924..44761e5ec 100644 --- a/zokrates_cli/src/ops/universal_setup.rs +++ b/zokrates_cli/src/ops/universal_setup.rs @@ -1,5 +1,8 @@ use crate::cli_constants; +use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; +use rand_0_8::rngs::StdRng; +use rand_0_8::SeedableRng; use std::convert::TryFrom; use std::fs::File; use std::io::Write; @@ -54,6 +57,14 @@ pub fn subcommand() -> App<'static, 'static> { .required(false) .default_value(cli_constants::UNIVERSAL_SETUP_DEFAULT_SIZE), ) + .arg( + Arg::with_name("entropy") + .short("e") + .long("entropy") + .help("User provided randomness") + .takes_value(true) + .required(false), + ) } pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> { @@ -98,8 +109,13 @@ fn cli_universal_setup, B: UniversalBackend() .map_err(|_| format!("Universal setup size {} is invalid", size))?; + let mut rng = sub_matches + .value_of("entropy") + .map(|entropy| get_seeded_rng(entropy)) + .unwrap_or_else(|| StdRng::from_entropy()); + // run universal setup phase - let setup = B::universal_setup(size); + let setup = B::universal_setup(size, &mut rng); // write proving key let mut u_file = File::create(u_path) diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index feb949d17..297883841 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -14,6 +14,7 @@ serde_json = { version = "1.0", features = ["preserve_order"] } wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } typed-arena = "1.4.1" lazy_static = "1.4.0" +rand_0_8 = { version = "0.8", package = "rand" } zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } zokrates_ark = { path = "../zokrates_ark", default-features = false} zokrates_bellman = { path = "../zokrates_bellman", default-features = false} diff --git a/zokrates_js/src/lib.rs b/zokrates_js/src/lib.rs index cf24252e0..d349fbfb5 100644 --- a/zokrates_js/src/lib.rs +++ b/zokrates_js/src/lib.rs @@ -4,6 +4,7 @@ mod util; extern crate lazy_static; use crate::util::normalize_path; +use rand_0_8::{rngs::StdRng, SeedableRng}; use serde::{Deserialize, Serialize}; use serde_json::to_string_pretty; use std::convert::TryFrom; @@ -343,7 +344,8 @@ mod internal { >( program: ir::Prog, ) -> JsValue { - let keypair = B::setup(program); + let rng = &mut StdRng::from_entropy(); + let keypair = B::setup(program, rng); let tagged_keypair = TaggedKeypair::::new(keypair); JsValue::from_serde(&tagged_keypair).unwrap() } @@ -364,7 +366,8 @@ mod internal { pub fn universal_setup_of_size, B: UniversalBackend>( size: u32, ) -> Vec { - B::universal_setup(size) + let rng = &mut StdRng::from_entropy(); + B::universal_setup(size, rng) } pub fn generate_proof, B: Backend>( @@ -376,7 +379,8 @@ mod internal { let ir_witness: ir::Witness = ir::Witness::read(str_witness.as_bytes()) .map_err(|err| JsValue::from_str(&format!("Could not read witness: {}", err)))?; - let proof = B::generate_proof(prog, ir_witness, pk.to_vec()); + let rng = &mut StdRng::from_entropy(); + let proof = B::generate_proof(prog, ir_witness, pk.to_vec(), rng); Ok(JsValue::from_serde(&TaggedProof::::new(proof.proof, proof.inputs)).unwrap()) } diff --git a/zokrates_proof_systems/Cargo.toml b/zokrates_proof_systems/Cargo.toml index 5fc9ee2c3..bbc76f8ee 100644 --- a/zokrates_proof_systems/Cargo.toml +++ b/zokrates_proof_systems/Cargo.toml @@ -12,5 +12,5 @@ regex = "0.2" cfg-if = "0.1" ethabi = "17.0.0" primitive-types = { version = "0.11", features = ["rlp"] } -rand_0_4 = { version = "0.4", package = "rand" } +rand_0_8 = { version = "0.8", package = "rand" } getrandom = { version = "0.2", features = ["js"] } \ No newline at end of file diff --git a/zokrates_proof_systems/src/lib.rs b/zokrates_proof_systems/src/lib.rs index 231fbeee7..da705bce8 100644 --- a/zokrates_proof_systems/src/lib.rs +++ b/zokrates_proof_systems/src/lib.rs @@ -10,9 +10,8 @@ pub use tagged::{TaggedKeypair, TaggedProof, TaggedVerificationKey}; use zokrates_ast::ir; +use rand_0_8::{CryptoRng, RngCore}; use serde::{Deserialize, Serialize}; - -use rand_0_4::Rng; use std::io::{Read, Write}; use zokrates_field::Field; @@ -96,22 +95,24 @@ impl ToString for G2AffineFq2 { } pub trait Backend> { - fn generate_proof>>( + fn generate_proof>, R: RngCore + CryptoRng>( program: ir::ProgIterator, witness: ir::Witness, proving_key: Vec, + rng: &mut R, ) -> Proof; fn verify(vk: S::VerificationKey, proof: Proof) -> bool; } pub trait NonUniversalBackend>: Backend { - fn setup>>( + fn setup>, R: RngCore + CryptoRng>( program: ir::ProgIterator, + rng: &mut R, ) -> SetupKeypair; } pub trait UniversalBackend>: Backend { - fn universal_setup(size: u32) -> Vec; + fn universal_setup(size: u32, rng: &mut R) -> Vec; fn setup>>( srs: Vec, @@ -126,7 +127,7 @@ pub trait MpcBackend> { output: &mut W, ) -> Result<(), String>; - fn contribute( + fn contribute( params: &mut R, rng: &mut G, output: &mut W, From 655a54cf3761dbf25b0b214676e0a5f50f493e6c Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 12 Dec 2022 18:28:46 +0100 Subject: [PATCH 50/94] fix tests --- Cargo.lock | 1 + zokrates_ark/src/gm17.rs | 16 +++++++---- zokrates_ark/src/groth16.rs | 16 +++++++---- zokrates_ark/src/marlin.rs | 17 ++++++++---- zokrates_bellman/src/groth16.rs | 11 ++++++-- zokrates_bellman/src/lib.rs | 37 +++++++++++++++---------- zokrates_cli/src/ops/generate_proof.rs | 4 +-- zokrates_cli/src/ops/setup.rs | 4 +-- zokrates_cli/src/ops/universal_setup.rs | 4 +-- zokrates_test/Cargo.toml | 2 +- zokrates_test/tests/wasm.rs | 7 +++-- 11 files changed, 77 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d1c40b30..721b2a0b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3299,6 +3299,7 @@ dependencies = [ name = "zokrates_test" version = "0.2.0" dependencies = [ + "rand 0.8.5", "serde", "serde_derive", "serde_json", diff --git a/zokrates_ark/src/gm17.rs b/zokrates_ark/src/gm17.rs index 6983d1c63..62a0367aa 100644 --- a/zokrates_ark/src/gm17.rs +++ b/zokrates_ark/src/gm17.rs @@ -108,6 +108,8 @@ impl Backend for Ark { #[cfg(test)] mod tests { + use rand_0_8::rngs::StdRng; + use rand_0_8::SeedableRng; use zokrates_ast::flat::{Parameter, Variable}; use zokrates_ast::ir::{Prog, Statement}; use zokrates_interpreter::Interpreter; @@ -123,15 +125,18 @@ mod tests { statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))], }; - let keypair = >::setup(program.clone()); + let rng = &mut StdRng::from_entropy(); + let keypair = + >::setup(program.clone(), rng); let interpreter = Interpreter::default(); let witness = interpreter .execute(program.clone(), &[Bls12_377Field::from(42)]) .unwrap(); - let proof = - >::generate_proof(program, witness, keypair.pk); + let proof = >::generate_proof( + program, witness, keypair.pk, rng, + ); let ans = >::verify(keypair.vk, proof); assert!(ans); @@ -145,7 +150,8 @@ mod tests { statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))], }; - let keypair = >::setup(program.clone()); + let rng = &mut StdRng::from_entropy(); + let keypair = >::setup(program.clone(), rng); let interpreter = Interpreter::default(); let witness = interpreter @@ -153,7 +159,7 @@ mod tests { .unwrap(); let proof = - >::generate_proof(program, witness, keypair.pk); + >::generate_proof(program, witness, keypair.pk, rng); let ans = >::verify(keypair.vk, proof); assert!(ans); diff --git a/zokrates_ark/src/groth16.rs b/zokrates_ark/src/groth16.rs index e96f8a62e..56a25d3bf 100644 --- a/zokrates_ark/src/groth16.rs +++ b/zokrates_ark/src/groth16.rs @@ -111,6 +111,8 @@ impl NonUniversalBackend for Ark { #[cfg(test)] mod tests { + use rand_0_8::rngs::StdRng; + use rand_0_8::SeedableRng; use zokrates_ast::flat::{Parameter, Variable}; use zokrates_ast::ir::{Prog, Statement}; use zokrates_interpreter::Interpreter; @@ -126,15 +128,18 @@ mod tests { statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))], }; - let keypair = >::setup(program.clone()); + let rng = &mut StdRng::from_entropy(); + let keypair = + >::setup(program.clone(), rng); let interpreter = Interpreter::default(); let witness = interpreter .execute(program.clone(), &[Bls12_377Field::from(42)]) .unwrap(); - let proof = - >::generate_proof(program, witness, keypair.pk); + let proof = >::generate_proof( + program, witness, keypair.pk, rng, + ); let ans = >::verify(keypair.vk, proof); assert!(ans); @@ -148,7 +153,8 @@ mod tests { statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))], }; - let keypair = >::setup(program.clone()); + let rng = &mut StdRng::from_entropy(); + let keypair = >::setup(program.clone(), rng); let interpreter = Interpreter::default(); let witness = interpreter @@ -156,7 +162,7 @@ mod tests { .unwrap(); let proof = - >::generate_proof(program, witness, keypair.pk); + >::generate_proof(program, witness, keypair.pk, rng); let ans = >::verify(keypair.vk, proof); assert!(ans); diff --git a/zokrates_ark/src/marlin.rs b/zokrates_ark/src/marlin.rs index 1bb21c678..054b62349 100644 --- a/zokrates_ark/src/marlin.rs +++ b/zokrates_ark/src/marlin.rs @@ -380,6 +380,7 @@ impl Backend for Ark { #[cfg(test)] mod tests { + use rand_0_8::rngs::StdRng; use zokrates_ast::flat::{Parameter, Variable}; use zokrates_ast::ir::{Prog, QuadComb, Statement}; use zokrates_interpreter::Interpreter; @@ -405,7 +406,8 @@ mod tests { ], }; - let srs = >::universal_setup(5); + let rng = &mut StdRng::from_entropy(); + let srs = >::universal_setup(5, rng); let keypair = >::setup(srs, program.clone()).unwrap(); let interpreter = Interpreter::default(); @@ -414,8 +416,9 @@ mod tests { .execute(program.clone(), &[Bls12_377Field::from(42)]) .unwrap(); - let proof = - >::generate_proof(program, witness, keypair.pk); + let proof = >::generate_proof( + program, witness, keypair.pk, rng, + ); let ans = >::verify(keypair.vk, proof); assert!(ans); @@ -438,7 +441,8 @@ mod tests { ], }; - let srs = >::universal_setup(5); + let rng = &mut StdRng::from_entropy(); + let srs = >::universal_setup(5, rng); let keypair = >::setup(srs, program.clone()).unwrap(); let interpreter = Interpreter::default(); @@ -447,8 +451,9 @@ mod tests { .execute(program.clone(), &[Bw6_761Field::from(42)]) .unwrap(); - let proof = - >::generate_proof(program, witness, keypair.pk); + let proof = >::generate_proof( + program, witness, keypair.pk, rng, + ); let ans = >::verify(keypair.vk, proof); assert!(ans); diff --git a/zokrates_bellman/src/groth16.rs b/zokrates_bellman/src/groth16.rs index 66df17891..aa2820496 100644 --- a/zokrates_bellman/src/groth16.rs +++ b/zokrates_bellman/src/groth16.rs @@ -205,6 +205,8 @@ pub mod serialization { #[cfg(test)] mod tests { + use rand_0_8::rngs::StdRng; + use rand_0_8::SeedableRng; use zokrates_field::Bn128Field; use zokrates_interpreter::Interpreter; @@ -220,15 +222,18 @@ mod tests { statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))], }; - let keypair = >::setup(program.clone()); + let rng = &mut StdRng::from_entropy(); + let keypair = + >::setup(program.clone(), rng); let interpreter = Interpreter::default(); let witness = interpreter .execute(program.clone(), &[Bn128Field::from(42)]) .unwrap(); - let proof = - >::generate_proof(program, witness, keypair.pk); + let proof = >::generate_proof( + program, witness, keypair.pk, rng, + ); let ans = >::verify(keypair.vk, proof); assert!(ans); diff --git a/zokrates_bellman/src/lib.rs b/zokrates_bellman/src/lib.rs index 3882adc21..264accfeb 100644 --- a/zokrates_bellman/src/lib.rs +++ b/zokrates_bellman/src/lib.rs @@ -249,6 +249,8 @@ mod tests { mod prove { use super::*; + use rand_0_8::rngs::StdRng; + use rand_0_8::SeedableRng; use zokrates_ast::flat::Parameter; use zokrates_ast::ir::Prog; @@ -261,8 +263,9 @@ mod tests { let witness = interpreter.execute(program.clone(), &[]).unwrap(); let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -281,8 +284,9 @@ mod tests { let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -301,8 +305,9 @@ mod tests { let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -318,8 +323,9 @@ mod tests { let witness = interpreter.execute(program.clone(), &[]).unwrap(); let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -351,8 +357,9 @@ mod tests { .unwrap(); let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -374,8 +381,9 @@ mod tests { let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } #[test] @@ -399,8 +407,9 @@ mod tests { .unwrap(); let computation = Computation::with_witness(program, witness); - let params = computation.clone().setup(); - let _proof = computation.prove(¶ms); + let rng = &mut StdRng::from_entropy(); + let params = computation.clone().setup(rng); + let _proof = computation.prove(¶ms, rng); } } } diff --git a/zokrates_cli/src/ops/generate_proof.rs b/zokrates_cli/src/ops/generate_proof.rs index eff1715f4..65204a6e1 100644 --- a/zokrates_cli/src/ops/generate_proof.rs +++ b/zokrates_cli/src/ops/generate_proof.rs @@ -179,8 +179,8 @@ fn cli_generate_proof< let mut rng = sub_matches .value_of("entropy") - .map(|entropy| get_seeded_rng(entropy)) - .unwrap_or_else(|| StdRng::from_entropy()); + .map(get_seeded_rng) + .unwrap_or_else(StdRng::from_entropy); let proof = B::generate_proof(program, witness, pk, &mut rng); let mut proof_file = File::create(proof_path).unwrap(); diff --git a/zokrates_cli/src/ops/setup.rs b/zokrates_cli/src/ops/setup.rs index d368463c0..de7639fbc 100644 --- a/zokrates_cli/src/ops/setup.rs +++ b/zokrates_cli/src/ops/setup.rs @@ -194,8 +194,8 @@ fn cli_setup_non_universal< let mut rng = sub_matches .value_of("entropy") - .map(|entropy| get_seeded_rng(entropy)) - .unwrap_or_else(|| StdRng::from_entropy()); + .map(get_seeded_rng) + .unwrap_or_else(StdRng::from_entropy); // run setup phase let keypair = B::setup(program, &mut rng); diff --git a/zokrates_cli/src/ops/universal_setup.rs b/zokrates_cli/src/ops/universal_setup.rs index 44761e5ec..d2cf031f6 100644 --- a/zokrates_cli/src/ops/universal_setup.rs +++ b/zokrates_cli/src/ops/universal_setup.rs @@ -111,8 +111,8 @@ fn cli_universal_setup, B: UniversalBackend>::setup(program.clone()); - let _proof = >::generate_proof(program, witness, keypair.pk); + let rng = &mut StdRng::from_entropy(); + let keypair = >::setup(program.clone(), rng); + let _proof = + >::generate_proof(program, witness, keypair.pk, rng); } From 4ac95c7559f1dcf02a6f170eec2b1c68d355a237 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 13 Dec 2022 14:41:56 +0100 Subject: [PATCH 51/94] add changelog, update zokrates-js --- Cargo.lock | 2 + changelogs/unreleased/1254-dark64 | 1 + zokrates_cli/src/ops/mpc/contribute.rs | 37 ++----- zokrates_js/Cargo.toml | 2 + zokrates_js/index.d.ts | 7 +- zokrates_js/lib.js | 29 ++++-- zokrates_js/src/lib.rs | 135 ++++++++++++++++++------- zokrates_js/src/util.rs | 22 ++++ zokrates_js/tests/tests.js | 28 ++++- 9 files changed, 179 insertions(+), 84 deletions(-) create mode 100644 changelogs/unreleased/1254-dark64 diff --git a/Cargo.lock b/Cargo.lock index 721b2a0b6..25c59edb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3211,6 +3211,8 @@ dependencies = [ name = "zokrates_js" version = "1.1.4" dependencies = [ + "blake2 0.8.1", + "byteorder", "console_error_panic_hook", "indexmap", "js-sys", diff --git a/changelogs/unreleased/1254-dark64 b/changelogs/unreleased/1254-dark64 new file mode 100644 index 000000000..f31f1cd54 --- /dev/null +++ b/changelogs/unreleased/1254-dark64 @@ -0,0 +1 @@ +Allow user-provided randomness in setup and proof generation \ No newline at end of file diff --git a/zokrates_cli/src/ops/mpc/contribute.rs b/zokrates_cli/src/ops/mpc/contribute.rs index 2936e3c28..aceda7b42 100644 --- a/zokrates_cli/src/ops/mpc/contribute.rs +++ b/zokrates_cli/src/ops/mpc/contribute.rs @@ -1,4 +1,5 @@ use crate::cli_constants::MPC_DEFAULT_PATH; +use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; use rand_0_8::{ rngs::{OsRng, StdRng}, @@ -75,37 +76,6 @@ pub fn cli_mpc_contribute< File::open(&path).map_err(|why| format!("Could not open `{}`: {}", path.display(), why))?; let mut reader = BufReader::new(file); - let entropy = sub_matches.value_of("entropy").unwrap(); - - // Create an RNG based on a mixture of system randomness and user provided randomness - let mut rng = { - use blake2::{Blake2b, Digest}; - use byteorder::ReadBytesExt; - - let h = { - let mut system_rng = OsRng::default(); - let mut h = Blake2b::default(); - - // Gather 1024 bytes of entropy from the system - for _ in 0..1024 { - let r: u8 = system_rng.gen(); - h.input(&[r]); - } - - // Hash it all up to make a seed - h.input(&entropy.as_bytes()); - h.result() - }; - - let mut digest = &h[..]; - - let mut seed = [0u8; 32]; - for e in &mut seed { - *e = digest.read_u8().unwrap(); - } - - StdRng::from_seed(seed) - }; let output_path = Path::new(sub_matches.value_of("output").unwrap()); let output_file = File::create(&output_path) @@ -115,6 +85,11 @@ pub fn cli_mpc_contribute< println!("Contributing to `{}`...", path.display()); + let mut rng = sub_matches + .value_of("entropy") + .map(get_seeded_rng) + .unwrap_or_else(StdRng::from_entropy); + let hash = B::contribute(&mut reader, &mut rng, &mut writer) .map_err(|e| format!("Failed to contribute: {}", e))?; println!("The BLAKE2b hash of your contribution is:\n"); diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 297883841..7b088d33b 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -15,6 +15,8 @@ wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } typed-arena = "1.4.1" lazy_static = "1.4.0" rand_0_8 = { version = "0.8", package = "rand" } +blake2 = "0.8.1" +byteorder = "1" zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } zokrates_ark = { path = "../zokrates_ark", default-features = false} zokrates_bellman = { path = "../zokrates_bellman", default-features = false} diff --git a/zokrates_js/index.d.ts b/zokrates_js/index.d.ts index 979603e86..9a59b538f 100644 --- a/zokrates_js/index.d.ts +++ b/zokrates_js/index.d.ts @@ -84,13 +84,14 @@ declare module "zokrates-js" { args: any[], options?: ComputeOptions ): ComputationResult; - setup(program: Uint8Array): SetupKeypair; - universalSetup(size: number): Uint8Array; + setup(program: Uint8Array, entropy?: string): SetupKeypair; + universalSetup(size: number, entropy?: string): Uint8Array; setupWithSrs(srs: Uint8Array, program: Uint8Array): SetupKeypair; generateProof( program: Uint8Array, witness: string, - provingKey: Uint8Array + provingKey: Uint8Array, + entropy?: string ): Proof; verify(verificationKey: VerificationKey, proof: Proof): boolean; exportSolidityVerifier(verificationKey: VerificationKey): string; diff --git a/zokrates_js/lib.js b/zokrates_js/lib.js index 717541231..2fa5eaf57 100644 --- a/zokrates_js/lib.js +++ b/zokrates_js/lib.js @@ -54,17 +54,17 @@ module.exports = (pkg) => { ptr.free(); return result; }, - setup: (program, options) => { - return pkg.setup(program, options); + setup: (program, entropy, options) => { + return pkg.setup(program, entropy, options); }, - universalSetup: (curve, size) => { - return pkg.universal_setup(curve, size); + universalSetup: (curve, size, entropy) => { + return pkg.universal_setup(curve, size, entropy); }, setupWithSrs: (srs, program, options) => { return pkg.setup_with_srs(srs, program, options); }, - generateProof: (program, witness, provingKey, options) => { - return pkg.generate_proof(program, witness, provingKey, options); + generateProof: (program, witness, provingKey, entropy, options) => { + return pkg.generate_proof(program, witness, provingKey, entropy, options); }, verify: (vk, proof, options) => { return pkg.verify(vk, proof, options); @@ -89,13 +89,20 @@ module.exports = (pkg) => { }), computeWitness: (artifacts, args, computeOptions = {}) => defaultProvider.computeWitness(artifacts, args, computeOptions), - setup: (program) => defaultProvider.setup(program, options), - universalSetup: (size) => - defaultProvider.universalSetup(options.curve, size), + setup: (program, entropy) => + defaultProvider.setup(program, entropy, options), + universalSetup: (size, entropy) => + defaultProvider.universalSetup(options.curve, size, entropy), setupWithSrs: (srs, program) => defaultProvider.setupWithSrs(srs, program, options), - generateProof: (program, witness, provingKey) => - defaultProvider.generateProof(program, witness, provingKey, options), + generateProof: (program, witness, provingKey, entropy) => + defaultProvider.generateProof( + program, + witness, + provingKey, + entropy, + options + ), verify: (vk, proof) => defaultProvider.verify(vk, proof, options), exportSolidityVerifier: (vk) => defaultProvider.exportSolidityVerifier(vk), diff --git a/zokrates_js/src/lib.rs b/zokrates_js/src/lib.rs index d349fbfb5..3949f8584 100644 --- a/zokrates_js/src/lib.rs +++ b/zokrates_js/src/lib.rs @@ -3,7 +3,7 @@ mod util; #[macro_use] extern crate lazy_static; -use crate::util::normalize_path; +use crate::util::{get_seeded_rng, normalize_path}; use rand_0_8::{rngs::StdRng, SeedableRng}; use serde::{Deserialize, Serialize}; use serde_json::to_string_pretty; @@ -218,6 +218,7 @@ impl<'a> Write for LogWriter<'a> { mod internal { use super::*; + use rand_0_8::{CryptoRng, RngCore}; pub fn compile( source: JsValue, @@ -341,10 +342,11 @@ mod internal { T: Field, S: NonUniversalScheme + Serialize, B: NonUniversalBackend, + R: RngCore + CryptoRng, >( program: ir::Prog, + rng: &mut R, ) -> JsValue { - let rng = &mut StdRng::from_entropy(); let keypair = B::setup(program, rng); let tagged_keypair = TaggedKeypair::::new(keypair); JsValue::from_serde(&tagged_keypair).unwrap() @@ -363,23 +365,28 @@ mod internal { Ok(JsValue::from_serde(&TaggedKeypair::::new(keypair)).unwrap()) } - pub fn universal_setup_of_size, B: UniversalBackend>( + pub fn universal_setup_of_size< + T: Field, + S: UniversalScheme, + B: UniversalBackend, + R: RngCore + CryptoRng, + >( size: u32, + rng: &mut R, ) -> Vec { - let rng = &mut StdRng::from_entropy(); B::universal_setup(size, rng) } - pub fn generate_proof, B: Backend>( + pub fn generate_proof, B: Backend, R: RngCore + CryptoRng>( prog: ir::Prog, witness: JsValue, pk: &[u8], + rng: &mut R, ) -> Result { let str_witness = witness.as_string().unwrap(); let ir_witness: ir::Witness = ir::Witness::read(str_witness.as_bytes()) .map_err(|err| JsValue::from_str(&format!("Could not read witness: {}", err)))?; - let rng = &mut StdRng::from_entropy(); let proof = B::generate_proof(prog, ir_witness, pk.to_vec(), rng); Ok(JsValue::from_serde(&TaggedProof::::new(proof.proof, proof.inputs)).unwrap()) } @@ -514,7 +521,7 @@ pub fn export_solidity_verifier(vk: JsValue) -> Result { } #[wasm_bindgen] -pub fn setup(program: &[u8], options: JsValue) -> Result { +pub fn setup(program: &[u8], entropy: JsValue, options: JsValue) -> Result { let options: serde_json::Value = options.into_serde().unwrap(); let backend = BackendParameter::try_from( @@ -535,25 +542,48 @@ pub fn setup(program: &[u8], options: JsValue) -> Result { .map_err(|err| JsValue::from_str(&err))? .collect(); + let mut rng = entropy + .as_string() + .map(|s| get_seeded_rng(&s)) + .unwrap_or_else(StdRng::from_entropy); + match (backend, scheme) { (BackendParameter::Bellman, SchemeParameter::G16) => match prog { - ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Bellman>(p)), + ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Bellman, _>( + p, &mut rng, + )), ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str( "Not supported: https://github.com/Zokrates/ZoKrates/issues/1200", )), _ => Err(JsValue::from_str("Not supported")), }, (BackendParameter::Ark, SchemeParameter::G16) => match prog { - ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)), - ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)), - ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)), - ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)), + ProgEnum::Bn128Program(p) => { + Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng)) + } + ProgEnum::Bls12_381Program(p) => { + Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng)) + } + ProgEnum::Bls12_377Program(p) => { + Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng)) + } + ProgEnum::Bw6_761Program(p) => { + Ok(internal::setup_non_universal::<_, G16, Ark, _>(p, &mut rng)) + } }, (BackendParameter::Ark, SchemeParameter::GM17) => match prog { - ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)), - ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)), - ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)), - ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)), + ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>( + p, &mut rng, + )), + ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>( + p, &mut rng, + )), + ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>( + p, &mut rng, + )), + ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark, _>( + p, &mut rng, + )), }, _ => Err(JsValue::from_str("Unsupported options")), } @@ -586,27 +616,40 @@ pub fn setup_with_srs(srs: &[u8], program: &[u8], options: JsValue) -> Result Result, JsValue> { +pub fn universal_setup(curve: JsValue, size: u32, entropy: JsValue) -> Result, JsValue> { let curve = CurveParameter::try_from(curve.as_string().unwrap().as_str()) .map_err(|e| JsValue::from_str(&e))?; + let mut rng = entropy + .as_string() + .map(|s| get_seeded_rng(&s)) + .unwrap_or_else(StdRng::from_entropy); + match curve { - CurveParameter::Bn128 => { - Ok(internal::universal_setup_of_size::(size)) - } + CurveParameter::Bn128 => Ok(internal::universal_setup_of_size::< + Bn128Field, + Marlin, + Ark, + _, + >(size, &mut rng)), CurveParameter::Bls12_381 => Ok(internal::universal_setup_of_size::< Bls12_381Field, Marlin, Ark, - >(size)), + _, + >(size, &mut rng)), CurveParameter::Bls12_377 => Ok(internal::universal_setup_of_size::< Bls12_377Field, Marlin, Ark, - >(size)), - CurveParameter::Bw6_761 => { - Ok(internal::universal_setup_of_size::(size)) - } + _, + >(size, &mut rng)), + CurveParameter::Bw6_761 => Ok(internal::universal_setup_of_size::< + Bw6_761Field, + Marlin, + Ark, + _, + >(size, &mut rng)), } } @@ -615,6 +658,7 @@ pub fn generate_proof( program: &[u8], witness: JsValue, pk: &[u8], + entropy: JsValue, options: JsValue, ) -> Result { let options: serde_json::Value = options.into_serde().unwrap(); @@ -637,10 +681,15 @@ pub fn generate_proof( .map_err(|err| JsValue::from_str(&err))? .collect(); + let mut rng = entropy + .as_string() + .map(|s| get_seeded_rng(&s)) + .unwrap_or_else(StdRng::from_entropy); + match (backend, scheme) { (BackendParameter::Bellman, SchemeParameter::G16) => match prog { ProgEnum::Bn128Program(p) => { - internal::generate_proof::<_, G16, Bellman>(p, witness, pk) + internal::generate_proof::<_, G16, Bellman, _>(p, witness, pk, &mut rng) } ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str( "Not supported: https://github.com/Zokrates/ZoKrates/issues/1200", @@ -648,35 +697,45 @@ pub fn generate_proof( _ => Err(JsValue::from_str("Not supported")), }, (BackendParameter::Ark, SchemeParameter::G16) => match prog { - ProgEnum::Bn128Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk), + ProgEnum::Bn128Program(p) => { + internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng) + } ProgEnum::Bls12_381Program(p) => { - internal::generate_proof::<_, G16, Ark>(p, witness, pk) + internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng) } ProgEnum::Bls12_377Program(p) => { - internal::generate_proof::<_, G16, Ark>(p, witness, pk) + internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng) + } + ProgEnum::Bw6_761Program(p) => { + internal::generate_proof::<_, G16, Ark, _>(p, witness, pk, &mut rng) } - ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk), }, (BackendParameter::Ark, SchemeParameter::GM17) => match prog { - ProgEnum::Bn128Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk), + ProgEnum::Bn128Program(p) => { + internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng) + } ProgEnum::Bls12_381Program(p) => { - internal::generate_proof::<_, GM17, Ark>(p, witness, pk) + internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng) } ProgEnum::Bls12_377Program(p) => { - internal::generate_proof::<_, GM17, Ark>(p, witness, pk) + internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng) + } + ProgEnum::Bw6_761Program(p) => { + internal::generate_proof::<_, GM17, Ark, _>(p, witness, pk, &mut rng) } - ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk), }, (BackendParameter::Ark, SchemeParameter::MARLIN) => match prog { - ProgEnum::Bn128Program(p) => internal::generate_proof::<_, Marlin, Ark>(p, witness, pk), + ProgEnum::Bn128Program(p) => { + internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng) + } ProgEnum::Bls12_381Program(p) => { - internal::generate_proof::<_, Marlin, Ark>(p, witness, pk) + internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng) } ProgEnum::Bls12_377Program(p) => { - internal::generate_proof::<_, Marlin, Ark>(p, witness, pk) + internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng) } ProgEnum::Bw6_761Program(p) => { - internal::generate_proof::<_, Marlin, Ark>(p, witness, pk) + internal::generate_proof::<_, Marlin, Ark, _>(p, witness, pk, &mut rng) } }, _ => Err(JsValue::from_str("Unsupported options")), diff --git a/zokrates_js/src/util.rs b/zokrates_js/src/util.rs index 65b1ffbc6..b037730ca 100644 --- a/zokrates_js/src/util.rs +++ b/zokrates_js/src/util.rs @@ -1,3 +1,5 @@ +use rand_0_8::rngs::StdRng; +use rand_0_8::SeedableRng; use std::path::{Component, PathBuf}; pub fn normalize_path(path: PathBuf) -> PathBuf { @@ -26,3 +28,23 @@ pub fn normalize_path(path: PathBuf) -> PathBuf { } ret } + +pub fn get_seeded_rng(entropy: &str) -> StdRng { + use blake2::{Blake2b, Digest}; + use byteorder::ReadBytesExt; + + let h = { + let mut h = Blake2b::default(); + h.input(&entropy.as_bytes()); + h.result() + }; + + let mut digest = &h[..]; + let mut seed = [0u8; 32]; + + for e in &mut seed { + *e = digest.read_u8().unwrap(); + } + + StdRng::from_seed(seed) +} diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index 86ed3bcd0..031474241 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -168,7 +168,7 @@ describe("tests", () => { it("compile", () => { assert.doesNotThrow(() => { const code = `def main(private field a, field b) -> bool { - bool check = if (a == 0){ true} else {a * a == b}; + bool check = if (a == 0) { true } else { a * a == b }; assert(check); return true; }`; @@ -199,6 +199,18 @@ describe("tests", () => { }); }); + it("setup (with user-provided entropy)", () => { + assert.doesNotThrow(() => { + let entropy = "f5c51ca46c331965"; + if (options.scheme === "marlin") { + const srs = provider.universalSetup(4, entropy); + keypair = provider.setupWithSrs(srs, artifacts.program); + } else { + keypair = provider.setup(artifacts.program, entropy); + } + }); + }); + if (options.scheme === "g16" && options.curve == "bn128") { it("snarkjs setup", () => { // write program to fs @@ -238,6 +250,20 @@ describe("tests", () => { }); }); + it("generate proof (with user-provided entropy)", () => { + assert.doesNotThrow(() => { + let entropy = "326e2c864f414ffb"; + proof = provider.generateProof( + artifacts.program, + computationResult.witness, + keypair.pk, + entropy + ); + assert.ok(proof !== undefined); + assert.equal(proof.inputs.length, 2); + }); + }); + if (options.scheme === "g16" && options.curve == "bn128") { it("generate snarkjs proof", () => { // write witness to fs From ed9a0b54402379f3f2231f8ce7ee504235a88f81 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 13 Dec 2022 14:42:55 +0100 Subject: [PATCH 52/94] clippy --- zokrates_cli/src/ops/mpc/contribute.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/zokrates_cli/src/ops/mpc/contribute.rs b/zokrates_cli/src/ops/mpc/contribute.rs index aceda7b42..ff21acd1c 100644 --- a/zokrates_cli/src/ops/mpc/contribute.rs +++ b/zokrates_cli/src/ops/mpc/contribute.rs @@ -1,10 +1,7 @@ use crate::cli_constants::MPC_DEFAULT_PATH; use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; -use rand_0_8::{ - rngs::{OsRng, StdRng}, - Rng, SeedableRng, -}; +use rand_0_8::{rngs::StdRng, SeedableRng}; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::path::Path; From 097e707de45b983ce4dddffed50313f0ae23939d Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 13 Dec 2022 14:59:07 +0100 Subject: [PATCH 53/94] improve js tests --- zokrates_js/tests/tests.js | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index 031474241..a87f5bbe9 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -192,21 +192,33 @@ describe("tests", () => { assert.doesNotThrow(() => { if (options.scheme === "marlin") { const srs = provider.universalSetup(4); + const srs2 = provider.universalSetup(4); + // second call should return a new srs + assert.notDeepEqual(srs, srs2); keypair = provider.setupWithSrs(srs, artifacts.program); } else { keypair = provider.setup(artifacts.program); + const keypair2 = provider.setup(artifacts.program); + // second call should return a new keypair + assert.notDeepEqual(keypair, keypair2); } }); }); - it("setup (with user-provided entropy)", () => { + it("setup with user-provided entropy", () => { assert.doesNotThrow(() => { let entropy = "f5c51ca46c331965"; if (options.scheme === "marlin") { const srs = provider.universalSetup(4, entropy); + const srs2 = provider.universalSetup(4, entropy); + // second call with the same entropy should return the same srs + assert.deepEqual(srs, srs2); keypair = provider.setupWithSrs(srs, artifacts.program); } else { keypair = provider.setup(artifacts.program, entropy); + const keypair2 = provider.setup(artifacts.program, entropy); + // second call with the same entropy should return the same keypair + assert.deepEqual(keypair, keypair2); } }); }); @@ -247,10 +259,18 @@ describe("tests", () => { ); assert.ok(proof !== undefined); assert.equal(proof.inputs.length, 2); + + // second call should return a new proof + let proof2 = provider.generateProof( + artifacts.program, + computationResult.witness, + keypair.pk + ); + assert.notDeepEqual(proof, proof2); }); }); - it("generate proof (with user-provided entropy)", () => { + it("generate proof with user-provided entropy", () => { assert.doesNotThrow(() => { let entropy = "326e2c864f414ffb"; proof = provider.generateProof( @@ -261,6 +281,15 @@ describe("tests", () => { ); assert.ok(proof !== undefined); assert.equal(proof.inputs.length, 2); + + // second call with the same entropy should return the same proof + let proof2 = provider.generateProof( + artifacts.program, + computationResult.witness, + keypair.pk, + entropy + ); + assert.deepEqual(proof, proof2); }); }); From 632a3d49c9d3c0147a90169c1d5f17cc069cbbce Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 11:52:10 +0100 Subject: [PATCH 54/94] change endianness in bitify --- .../tests/tests/assembly/binary_sub.json | 13 +++++++++++++ zokrates_core_test/tests/tests/assembly/bitify.json | 8 ++++---- zokrates_core_test/tests/tests/assembly/bitify.zok | 11 +++++------ .../tests/tests/assembly/less_than.zok | 2 +- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/zokrates_core_test/tests/tests/assembly/binary_sub.json b/zokrates_core_test/tests/tests/assembly/binary_sub.json index f4e06cc8c..f74256be0 100644 --- a/zokrates_core_test/tests/tests/assembly/binary_sub.json +++ b/zokrates_core_test/tests/tests/assembly/binary_sub.json @@ -2,6 +2,19 @@ "curves": ["Bn128"], "max_constraint_count": 10, "tests": [ + { + "input": { + "values": [ + ["0", "0", "1", "1"], + ["0", "0", "0", "1"] + ] + }, + "output": { + "Ok": { + "value": ["0", "0", "1", "0"] + } + } + }, { "input": { "values": [ diff --git a/zokrates_core_test/tests/tests/assembly/bitify.json b/zokrates_core_test/tests/tests/assembly/bitify.json index 392b9cce6..516aed2d9 100644 --- a/zokrates_core_test/tests/tests/assembly/bitify.json +++ b/zokrates_core_test/tests/tests/assembly/bitify.json @@ -7,7 +7,7 @@ }, "output": { "Ok": { - "value": ["1", "0", "0", "0"] + "value": ["0", "0", "0", "1"] } } }, @@ -17,7 +17,7 @@ }, "output": { "Ok": { - "value": ["0", "1", "0", "0"] + "value": ["0", "0", "1", "0"] } } }, @@ -27,7 +27,7 @@ }, "output": { "Ok": { - "value": ["1", "1", "0", "0"] + "value": ["0", "0", "1", "1"] } } }, @@ -52,7 +52,7 @@ "SourceAssemblyConstraint": { "file": "tests/tests/assembly/bitify.zok", "position": { - "line": 14, + "line": 13, "col": 9 } } diff --git a/zokrates_core_test/tests/tests/assembly/bitify.zok b/zokrates_core_test/tests/tests/assembly/bitify.zok index 9867f5f6b..ae1f01a5e 100644 --- a/zokrates_core_test/tests/tests/assembly/bitify.zok +++ b/zokrates_core_test/tests/tests/assembly/bitify.zok @@ -1,17 +1,16 @@ def bitify(field num) -> field[N] { field[N] mut out = [0; N]; - field mut lc1 = 0; - field mut e2 = 1; + field mut aux = 0; for u32 i in 0..N { + u32 j = N - i - 1; asm { - out[i] <-- (num >> i) & 1; + out[i] <-- (num >> j) & 1; out[i] * (out[i] - 1) === 0; } - lc1 = lc1 + out[i] * e2; - e2 = e2 + e2; + aux = aux + out[i] * (2**j); } asm { - lc1 === num; + aux === num; } return out; } diff --git a/zokrates_core_test/tests/tests/assembly/less_than.zok b/zokrates_core_test/tests/tests/assembly/less_than.zok index 1810f6a1d..6d307aeed 100644 --- a/zokrates_core_test/tests/tests/assembly/less_than.zok +++ b/zokrates_core_test/tests/tests/assembly/less_than.zok @@ -5,7 +5,7 @@ from "./bitify" import bitify; def less_than(field a, field b) -> bool { assert(N < FIELD_SIZE_IN_BITS - 1); field[N + 1] bits = bitify(a + 2**N - b); - bool out = field_to_bool_unsafe(1 - bits[N]); + bool out = field_to_bool_unsafe(1 - bits[0]); return out; } From 2afdbcb47bb2f49ccf35720df09720abb08c9e14 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 12:42:24 +0100 Subject: [PATCH 55/94] fix array rewrite issue --- zokrates_codegen/src/lib.rs | 13 ++++--------- .../assembly/propagation/array_rewrite.json | 16 ++++++++++++++++ .../tests/assembly/propagation/array_rewrite.zok | 8 ++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.zok diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index 543bfcfca..cf4e8cbb0 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -2231,21 +2231,16 @@ impl<'ast, T: Field> Flattener<'ast, T> { ) { match stat { ZirAssemblyStatement::Assignment(assignees, function) => { - let outputs: Vec = assignees - .into_iter() - .map(|assignee| { - self.layout - .get(&assignee.id) - .cloned() - .unwrap_or_else(|| self.use_variable(&assignee)) - }) - .collect(); let inputs: Vec> = function .arguments .iter() .cloned() .map(|p| self.layout.get(&p.id.id).cloned().unwrap().into()) .collect(); + let outputs: Vec = assignees + .into_iter() + .map(|assignee| self.use_variable(&assignee)) + .collect(); let directive = FlatDirective::new(outputs, Solver::Zir(function), inputs); statements_flattened.push_back(FlatStatement::Directive(directive)); } diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.json b/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.json new file mode 100644 index 000000000..307badbc6 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.json @@ -0,0 +1,16 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 2, + "tests": [ + { + "input": { + "values": ["2"] + }, + "output": { + "Ok": { + "value": ["4"] + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.zok b/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.zok new file mode 100644 index 000000000..d6b9fec58 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_rewrite.zok @@ -0,0 +1,8 @@ +def main(field x) -> field[1] { + field[1] mut a = [x]; + asm { + a[0] <-- a[0] + a[0]; + a[0] === x + x; + } + return a; +} \ No newline at end of file From f72c210a4ffaa5424153af8f5a9067666ac93437 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 16:10:20 +0100 Subject: [PATCH 56/94] fold assignee in shallow ssa --- zokrates_analysis/src/reducer/shallow_ssa.rs | 36 +++++++------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/zokrates_analysis/src/reducer/shallow_ssa.rs b/zokrates_analysis/src/reducer/shallow_ssa.rs index e479b3778..a071a0446 100644 --- a/zokrates_analysis/src/reducer/shallow_ssa.rs +++ b/zokrates_analysis/src/reducer/shallow_ssa.rs @@ -121,6 +121,16 @@ impl<'ast, 'a> ShallowTransformer<'ast, 'a> { fold_function(self, f) } + + fn fold_assignee(&mut self, a: TypedAssignee<'ast, T>) -> TypedAssignee<'ast, T> { + match a { + TypedAssignee::Identifier(v) => { + let v = self.issue_next_ssa_variable(v); + TypedAssignee::Identifier(self.fold_variable(v)) + } + a => fold_assignee(self, a), + } + } } impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { @@ -131,13 +141,7 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { match s { TypedAssemblyStatement::Assignment(a, e) => { let e = self.fold_expression(e); - let a = match a { - TypedAssignee::Identifier(v) => { - let v = self.issue_next_ssa_variable(v); - TypedAssignee::Identifier(self.fold_variable(v)) - } - a => fold_assignee(self, a), - }; + let a = self.fold_assignee(a); vec![TypedAssemblyStatement::Assignment(a, e)] } s => fold_assembly_statement(self, s), @@ -147,26 +151,12 @@ impl<'ast, 'a, T: Field> Folder<'ast, T> for ShallowTransformer<'ast, 'a> { match s { TypedStatement::Definition(a, DefinitionRhs::Expression(e)) => { let e = self.fold_expression(e); - - let a = match a { - TypedAssignee::Identifier(v) => { - let v = self.issue_next_ssa_variable(v); - TypedAssignee::Identifier(self.fold_variable(v)) - } - a => fold_assignee(self, a), - }; - + let a = self.fold_assignee(a); vec![TypedStatement::definition(a, e)] } TypedStatement::Definition(assignee, DefinitionRhs::EmbedCall(embed_call)) => { - let assignee = match assignee { - TypedAssignee::Identifier(v) => { - let v = self.issue_next_ssa_variable(v); - TypedAssignee::Identifier(self.fold_variable(v)) - } - a => fold_assignee(self, a), - }; let embed_call = self.fold_embed_call(embed_call); + let assignee = self.fold_assignee(assignee); vec![TypedStatement::embed_call_definition(assignee, embed_call)] } TypedStatement::For(v, from, to, stats) => { From 43cb632c4a4b08c4480c9a0e8dc7d8360cffe0c7 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 19:11:44 +0100 Subject: [PATCH 57/94] move rng function to proof systems crate --- Cargo.lock | 5 ++--- zokrates_cli/src/bin.rs | 1 - zokrates_cli/src/ops/generate_proof.rs | 4 ++-- zokrates_cli/src/ops/mpc/contribute.rs | 4 ++-- zokrates_cli/src/ops/setup.rs | 4 ++-- zokrates_cli/src/ops/universal_setup.rs | 4 ++-- zokrates_js/Cargo.toml | 2 -- zokrates_js/src/lib.rs | 9 ++++---- zokrates_js/src/util.rs | 22 ------------------- zokrates_proof_systems/Cargo.toml | 3 ++- zokrates_proof_systems/src/lib.rs | 1 + .../src/rng.rs | 5 ++--- 12 files changed, 20 insertions(+), 44 deletions(-) rename zokrates_cli/src/common.rs => zokrates_proof_systems/src/rng.rs (76%) diff --git a/Cargo.lock b/Cargo.lock index 25c59edb5..dcb6f2df6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3211,8 +3211,6 @@ dependencies = [ name = "zokrates_js" version = "1.1.4" dependencies = [ - "blake2 0.8.1", - "byteorder", "console_error_panic_hook", "indexmap", "js-sys", @@ -3262,9 +3260,10 @@ dependencies = [ name = "zokrates_proof_systems" version = "0.1.0" dependencies = [ + "blake2 0.8.1", + "byteorder", "cfg-if 0.1.10", "ethabi", - "getrandom", "hex 0.4.3", "primitive-types", "rand 0.8.5", diff --git a/zokrates_cli/src/bin.rs b/zokrates_cli/src/bin.rs index 62b0c1db4..99a1b0838 100644 --- a/zokrates_cli/src/bin.rs +++ b/zokrates_cli/src/bin.rs @@ -10,7 +10,6 @@ extern crate lazy_static; mod cli_constants; -mod common; mod ops; use clap::{App, AppSettings, Arg}; diff --git a/zokrates_cli/src/ops/generate_proof.rs b/zokrates_cli/src/ops/generate_proof.rs index 65204a6e1..82624ffe4 100644 --- a/zokrates_cli/src/ops/generate_proof.rs +++ b/zokrates_cli/src/ops/generate_proof.rs @@ -1,5 +1,4 @@ use crate::cli_constants; -use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; use rand_0_8::rngs::StdRng; use rand_0_8::SeedableRng; @@ -15,6 +14,7 @@ use zokrates_bellman::Bellman; use zokrates_common::constants; use zokrates_common::helpers::*; use zokrates_field::Field; +use zokrates_proof_systems::rng::get_rng_from_entropy; #[cfg(any(feature = "bellman", feature = "ark"))] use zokrates_proof_systems::*; @@ -179,7 +179,7 @@ fn cli_generate_proof< let mut rng = sub_matches .value_of("entropy") - .map(get_seeded_rng) + .map(get_rng_from_entropy) .unwrap_or_else(StdRng::from_entropy); let proof = B::generate_proof(program, witness, pk, &mut rng); diff --git a/zokrates_cli/src/ops/mpc/contribute.rs b/zokrates_cli/src/ops/mpc/contribute.rs index ff21acd1c..fcb7e5461 100644 --- a/zokrates_cli/src/ops/mpc/contribute.rs +++ b/zokrates_cli/src/ops/mpc/contribute.rs @@ -1,5 +1,4 @@ use crate::cli_constants::MPC_DEFAULT_PATH; -use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; use rand_0_8::{rngs::StdRng, SeedableRng}; use std::fs::File; @@ -8,6 +7,7 @@ use std::path::Path; use zokrates_bellman::Bellman; use zokrates_common::constants::{BLS12_381, BN128}; use zokrates_field::{BellmanFieldExtensions, Bls12_381Field, Bn128Field, Field}; +use zokrates_proof_systems::rng::get_rng_from_entropy; use zokrates_proof_systems::{MpcBackend, MpcScheme, G16}; pub fn subcommand() -> App<'static, 'static> { @@ -84,7 +84,7 @@ pub fn cli_mpc_contribute< let mut rng = sub_matches .value_of("entropy") - .map(get_seeded_rng) + .map(get_rng_from_entropy) .unwrap_or_else(StdRng::from_entropy); let hash = B::contribute(&mut reader, &mut rng, &mut writer) diff --git a/zokrates_cli/src/ops/setup.rs b/zokrates_cli/src/ops/setup.rs index de7639fbc..49f291811 100644 --- a/zokrates_cli/src/ops/setup.rs +++ b/zokrates_cli/src/ops/setup.rs @@ -1,5 +1,4 @@ use crate::cli_constants; -use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; use rand_0_8::rngs::StdRng; use rand_0_8::SeedableRng; @@ -15,6 +14,7 @@ use zokrates_bellman::Bellman; use zokrates_common::constants; use zokrates_common::helpers::*; use zokrates_field::Field; +use zokrates_proof_systems::rng::get_rng_from_entropy; #[cfg(any(feature = "bellman", feature = "ark"))] use zokrates_proof_systems::*; @@ -194,7 +194,7 @@ fn cli_setup_non_universal< let mut rng = sub_matches .value_of("entropy") - .map(get_seeded_rng) + .map(get_rng_from_entropy) .unwrap_or_else(StdRng::from_entropy); // run setup phase diff --git a/zokrates_cli/src/ops/universal_setup.rs b/zokrates_cli/src/ops/universal_setup.rs index d2cf031f6..b3831b65e 100644 --- a/zokrates_cli/src/ops/universal_setup.rs +++ b/zokrates_cli/src/ops/universal_setup.rs @@ -1,5 +1,4 @@ use crate::cli_constants; -use crate::common::get_seeded_rng; use clap::{App, Arg, ArgMatches, SubCommand}; use rand_0_8::rngs::StdRng; use rand_0_8::SeedableRng; @@ -12,6 +11,7 @@ use zokrates_ark::Ark; use zokrates_common::constants; use zokrates_common::helpers::*; use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field}; +use zokrates_proof_systems::rng::get_rng_from_entropy; #[cfg(any(feature = "bellman", feature = "ark"))] use zokrates_proof_systems::*; @@ -111,7 +111,7 @@ fn cli_universal_setup, B: UniversalBackend Result Result PathBuf { @@ -28,23 +26,3 @@ pub fn normalize_path(path: PathBuf) -> PathBuf { } ret } - -pub fn get_seeded_rng(entropy: &str) -> StdRng { - use blake2::{Blake2b, Digest}; - use byteorder::ReadBytesExt; - - let h = { - let mut h = Blake2b::default(); - h.input(&entropy.as_bytes()); - h.result() - }; - - let mut digest = &h[..]; - let mut seed = [0u8; 32]; - - for e in &mut seed { - *e = digest.read_u8().unwrap(); - } - - StdRng::from_seed(seed) -} diff --git a/zokrates_proof_systems/Cargo.toml b/zokrates_proof_systems/Cargo.toml index bbc76f8ee..a1c0deb5b 100644 --- a/zokrates_proof_systems/Cargo.toml +++ b/zokrates_proof_systems/Cargo.toml @@ -13,4 +13,5 @@ cfg-if = "0.1" ethabi = "17.0.0" primitive-types = { version = "0.11", features = ["rlp"] } rand_0_8 = { version = "0.8", package = "rand" } -getrandom = { version = "0.2", features = ["js"] } \ No newline at end of file +blake2 = "0.8.1" +byteorder = "1" \ No newline at end of file diff --git a/zokrates_proof_systems/src/lib.rs b/zokrates_proof_systems/src/lib.rs index da705bce8..18b28c2b2 100644 --- a/zokrates_proof_systems/src/lib.rs +++ b/zokrates_proof_systems/src/lib.rs @@ -1,3 +1,4 @@ +pub mod rng; pub mod to_token; mod scheme; diff --git a/zokrates_cli/src/common.rs b/zokrates_proof_systems/src/rng.rs similarity index 76% rename from zokrates_cli/src/common.rs rename to zokrates_proof_systems/src/rng.rs index f5f1e3cc0..9e2d51df5 100644 --- a/zokrates_cli/src/common.rs +++ b/zokrates_proof_systems/src/rng.rs @@ -1,9 +1,8 @@ use blake2::{Blake2b, Digest}; use byteorder::ReadBytesExt; -use rand_0_8::rngs::StdRng; -use rand_0_8::SeedableRng; +use rand_0_8::{rngs::StdRng, SeedableRng}; -pub fn get_seeded_rng(entropy: &str) -> StdRng { +pub fn get_rng_from_entropy(entropy: &str) -> StdRng { let h = { let mut h = Blake2b::default(); h.input(&entropy.as_bytes()); From 6de2fe9accdbd75e46739760febb669ce5777be3 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 19:39:18 +0100 Subject: [PATCH 58/94] remove cash restore --- .circleci/config.yml | 2 +- zokrates_js/package-lock.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0bfef41ee..39d89a9f0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,7 +57,7 @@ jobs: name: Version information command: rustc --version; cargo --version; rustup --version - setup-sccache - - restore-sccache-cache + # - restore-sccache-cache - run: name: Test on firefox command: | diff --git a/zokrates_js/package-lock.json b/zokrates_js/package-lock.json index 1e3c42f27..5c012bde1 100644 --- a/zokrates_js/package-lock.json +++ b/zokrates_js/package-lock.json @@ -6,13 +6,13 @@ "packages": { "": { "name": "zokrates-js", - "version": "1.1.1", + "version": "1.1.4", "license": "GPLv3", "devDependencies": { "dree": "^2.6.1", "mocha": "^9.2.0", "rimraf": "^3.0.2", - "snarkjs": "^0.4.24", + "snarkjs": "^0.4.25", "wasm-pack": "^0.10.2" } }, From ce04905e8f418ed1ee2859ed64e0645c4ed6a11d Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 19:44:11 +0100 Subject: [PATCH 59/94] revert --- .circleci/config.yml | 2 +- zokrates_js/Cargo.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 39d89a9f0..0bfef41ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,7 +57,7 @@ jobs: name: Version information command: rustc --version; cargo --version; rustup --version - setup-sccache - # - restore-sccache-cache + - restore-sccache-cache - run: name: Test on firefox command: | diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 297883841..2989f0bd2 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -15,6 +15,7 @@ wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } typed-arena = "1.4.1" lazy_static = "1.4.0" rand_0_8 = { version = "0.8", package = "rand" } +getrandom = { version = "0.2", features = ["js"] } zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } zokrates_ark = { path = "../zokrates_ark", default-features = false} zokrates_bellman = { path = "../zokrates_bellman", default-features = false} From 3e8ada46085588a1ded7959513e787a1935fe28c Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 27 Dec 2022 19:51:47 +0100 Subject: [PATCH 60/94] enable js feature in test --- zokrates_test/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/zokrates_test/Cargo.toml b/zokrates_test/Cargo.toml index 29fb9cd65..5eaba81c9 100644 --- a/zokrates_test/Cargo.toml +++ b/zokrates_test/Cargo.toml @@ -22,5 +22,6 @@ wasm-bindgen-test = "^0.3.0" zokrates_ark = { version = "0.1", path = "../zokrates_ark" } zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems" } rand_0_8 = { version = "0.8", package = "rand" } +getrandom = { version = "0.2", features = ["js"] } [lib] From 3a546615f35f5d1f2d32c467a54a16c775be6e81 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 3 Jan 2023 12:36:17 +0100 Subject: [PATCH 61/94] fix zir assembly propagation --- zokrates_analysis/src/zir_propagation.rs | 24 ++++++++++++++++++- .../propagation/array_propagation.json | 16 +++++++++++++ .../propagation/array_propagation.zok | 12 ++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_propagation.json create mode 100644 zokrates_core_test/tests/tests/assembly/propagation/array_propagation.zok diff --git a/zokrates_analysis/src/zir_propagation.rs b/zokrates_analysis/src/zir_propagation.rs index 4a08a7144..8fdaaf73c 100644 --- a/zokrates_analysis/src/zir_propagation.rs +++ b/zokrates_analysis/src/zir_propagation.rs @@ -7,7 +7,7 @@ use zokrates_ast::zir::types::UBitwidth; use zokrates_ast::zir::{ result_folder::*, Conditional, ConditionalExpression, ConditionalOrExpression, Constant, Expr, Id, IdentifierExpression, IdentifierOrExpression, SelectExpression, SelectOrExpression, - ZirAssemblyStatement, + ZirAssemblyStatement, ZirFunction, }; use zokrates_ast::zir::{ BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression, @@ -57,6 +57,28 @@ impl<'ast, T: Field> ZirPropagator<'ast, T> { impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { type Error = Error; + fn fold_function( + &mut self, + f: ZirFunction<'ast, T>, + ) -> Result, Self::Error> { + Ok(ZirFunction { + arguments: f + .arguments + .into_iter() + .filter(|p| !self.constants.contains_key(&p.id.id)) + .collect(), + statements: f + .statements + .into_iter() + .map(|s| self.fold_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(), + ..f + }) + } + fn fold_assembly_statement( &mut self, s: ZirAssemblyStatement<'ast, T>, diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.json b/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.json new file mode 100644 index 000000000..02caa4e5b --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.json @@ -0,0 +1,16 @@ +{ + "curves": ["Bn128"], + "max_constraint_count": 1, + "tests": [ + { + "input": { + "values": ["2"] + }, + "output": { + "Ok": { + "value": "4" + } + } + } + ] +} diff --git a/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.zok b/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.zok new file mode 100644 index 000000000..12fa26c73 --- /dev/null +++ b/zokrates_core_test/tests/tests/assembly/propagation/array_propagation.zok @@ -0,0 +1,12 @@ +def mul(field a, field b) -> field { + field mut res = 0; + asm { + res <== a * b; + } + return res; +} + +def main(field a) -> field { + field[2] b = [2, a]; // this will get propagated in zir + return mul(b[0], b[1]); +} \ No newline at end of file From 28ac40923cc21c96be6ff555c24fc2a942e7acd7 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Wed, 11 Jan 2023 03:07:03 +0200 Subject: [PATCH 62/94] Fix typos --- changelogs/unreleased/1260-rex4539 | 1 + zokrates_analysis/src/struct_concretizer.rs | 2 +- zokrates_book/src/toolbox/abi.md | 2 +- zokrates_book/src/toolbox/trusted_setup.md | 10 +++++----- zokrates_cli/examples/book/numeric_inference.zok | 4 ++-- zokrates_codegen/src/lib.rs | 2 +- zokrates_core/src/semantics.rs | 4 ++-- zokrates_core_test/tests/tests/native_le.zok | 2 +- zokrates_interpreter/src/lib.rs | 2 +- zokrates_js/README.md | 2 +- 10 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 changelogs/unreleased/1260-rex4539 diff --git a/changelogs/unreleased/1260-rex4539 b/changelogs/unreleased/1260-rex4539 new file mode 100644 index 000000000..d0c02778b --- /dev/null +++ b/changelogs/unreleased/1260-rex4539 @@ -0,0 +1 @@ +Fix typos \ No newline at end of file diff --git a/zokrates_analysis/src/struct_concretizer.rs b/zokrates_analysis/src/struct_concretizer.rs index 102cb4d8f..932a92670 100644 --- a/zokrates_analysis/src/struct_concretizer.rs +++ b/zokrates_analysis/src/struct_concretizer.rs @@ -1,5 +1,5 @@ // After all generics are inlined, a program should be completely "concrete", which means that all types must only contain -// litterals for array sizes. This is especially important to generate the ABI of the program. +// literals for array sizes. This is especially important to generate the ABI of the program. // It is direct to ensure that with most types, however the way structs are implemented requires a slightly different process: // Where for an array, `field[N]` ends up being propagated to `field[42]` which is direct to turn into a concrete type, // for structs, `Foo { field[N] a }` is propagated to `Foo<42> { field[N] a }`. The missing step is replacing `N` by `42` diff --git a/zokrates_book/src/toolbox/abi.md b/zokrates_book/src/toolbox/abi.md index caaa0c3be..15fd55030 100644 --- a/zokrates_book/src/toolbox/abi.md +++ b/zokrates_book/src/toolbox/abi.md @@ -1,6 +1,6 @@ # ZoKrates ABI -In order to interact programatically with compiled ZoKrates programs, ZoKrates supports passing arguments using an ABI. +In order to interact programmatically with compiled ZoKrates programs, ZoKrates supports passing arguments using an ABI. To illustrate this, we'll use the following example program: diff --git a/zokrates_book/src/toolbox/trusted_setup.md b/zokrates_book/src/toolbox/trusted_setup.md index aa05b4f03..bb643e0e3 100644 --- a/zokrates_book/src/toolbox/trusted_setup.md +++ b/zokrates_book/src/toolbox/trusted_setup.md @@ -1,6 +1,6 @@ # Performing a trusted setup using a multi-party computation protocol (MPC) -The zk-SNARK schemes supported by ZoKrates require a trusted setup. This procedure must be run to generate the proving and verification keys. This procedure generates some data often refered to as "toxic waste" which can be used to create fake proofs which will be accepted by the verifier. The entity running the trusted setup is trusted to delete this toxic waste. +The zk-SNARK schemes supported by ZoKrates require a trusted setup. This procedure must be run to generate the proving and verification keys. This procedure generates some data often referred to as "toxic waste" which can be used to create fake proofs which will be accepted by the verifier. The entity running the trusted setup is trusted to delete this toxic waste. Using an MPC protocol, we can run the trusted setup in a decentralized way, so that this responsibility is shared among all participants of the setup. If at least one participant is honest and deletes their part of the toxic waste, then no fake proofs can be created by anyone. This section of the book describes the steps to perform a trusted setup for the Groth16 scheme. @@ -35,7 +35,7 @@ Parameters written to `mpc.params` ``` Using the `-r` flag, we pass a path to the file which contains the parameters for our circuit with depth `2^n` (`phase1radix2m{n}`). -The parameters for various circuit depths can be computed using the [phase2-bn254](https://github.com/kobigurk/phase2-bn254) utility +The parameters for various circuit depths can be computed using the [phase2-bn254](https://github.com/kobigurk/phase2-bn254) utility by picking the latest response from the [Perpetual Powers of Tau](https://github.com/weijiekoh/perpetualpowersoftau) and following the instructions in the mentioned repositories. ## Making a contribution @@ -126,9 +126,9 @@ Your contribution has been written to `final.params` ``` The random beacon is the `2^n` iteration of `SHA256` over the hash evaluated on -some high entropy and publicly available data. Possible sources of data could be: +some high entropy and publicly available data. Possible sources of data could be: * The closing value of the stock market on a certain date -* The output of a selected set of national lotteries +* The output of a selected set of national lotteries * The value of a block at a particular height in one or more blockchains * [League of Entropy](https://www.cloudflare.com/leagueofentropy/) (drand) @@ -163,5 +163,5 @@ Once the ceremony is finalized, we can export the keys and use them to generate The secure generation of parameters for zk-SNARKs is a crucial step in the trustworthiness of the resulting proof system. The security of the ceremony relies entirely on the fact that at least one participant needs to securely delete their "toxic waste" for the resulting parameters to be generated honestly. Opening the ceremony to a large number of participants reduces the probability that the resulting parameters are dishonest. -Once the ceremony is finalized, we can generate a verifier smart contract by using the keys we obtained through the trusted setup ceremony. +Once the ceremony is finalized, we can generate a verifier smart contract by using the keys we obtained through the trusted setup ceremony. At this point, we can safely deploy the contract and verify proofs on-chain. diff --git a/zokrates_cli/examples/book/numeric_inference.zok b/zokrates_cli/examples/book/numeric_inference.zok index f81064319..b3446b51e 100644 --- a/zokrates_cli/examples/book/numeric_inference.zok +++ b/zokrates_cli/examples/book/numeric_inference.zok @@ -1,8 +1,8 @@ def main() { - // `255` is infered to `255f`, and the addition happens between field elements + // `255` is inferred to `255f`, and the addition happens between field elements assert(255 + 1f == 256); - // `255` is infered to `255u8`, and the addition happens between u8 + // `255` is inferred to `255u8`, and the addition happens between u8 // This causes an overflow assert(255 + 1u8 == 0); diff --git a/zokrates_codegen/src/lib.rs b/zokrates_codegen/src/lib.rs index cf4e8cbb0..e149a9688 100644 --- a/zokrates_codegen/src/lib.rs +++ b/zokrates_codegen/src/lib.rs @@ -259,7 +259,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { /// As long as `sizeUnknown` is `true` we don't yet know if a is <= than b. /// 2. Loop over `b`: /// * b[0] = 1 - /// when `b` is 1 we check wether `a` is 0 in that particular run and update + /// when `b` is 1 we check whether `a` is 0 in that particular run and update /// `sizeUnknown` accordingly: /// `sizeUnknown = sizeUnknown && a[0]` /// * b[1] = 1 diff --git a/zokrates_core/src/semantics.rs b/zokrates_core/src/semantics.rs index ad584e717..a4f7bb0c3 100644 --- a/zokrates_core/src/semantics.rs +++ b/zokrates_core/src/semantics.rs @@ -988,7 +988,7 @@ impl<'ast, T: Field> Checker<'ast, T> { _ => unreachable!(), }; - // return if any errors occured + // return if any errors occurred if !errors.is_empty() { return Err(errors); } @@ -1035,7 +1035,7 @@ impl<'ast, T: Field> Checker<'ast, T> { // insert into typed_modules if we checked anything if let Some(typed_module) = to_insert { - // there should be no checked module at that key just yet, if there is we have a colision or we checked something twice + // there should be no checked module at that key just yet, if there is we have a collision or we checked something twice assert!(state .typed_modules .insert(module_id.to_path_buf(), typed_module) diff --git a/zokrates_core_test/tests/tests/native_le.zok b/zokrates_core_test/tests/tests/native_le.zok index 74d51a19c..1a70dbe00 100644 --- a/zokrates_core_test/tests/tests/native_le.zok +++ b/zokrates_core_test/tests/tests/native_le.zok @@ -27,7 +27,7 @@ def le(field a, field c) -> bool { return le(a_bits, c_bits); } -// this instanciates comparison starting from u32 +// this instantiates comparison starting from u32 def le(u32 a, u32 c) -> bool { bool[32] a_bits = u32_to_bits(a); bool[32] c_bits = u32_to_bits(c); diff --git a/zokrates_interpreter/src/lib.rs b/zokrates_interpreter/src/lib.rs index f33ab3de4..9f90e00ca 100644 --- a/zokrates_interpreter/src/lib.rs +++ b/zokrates_interpreter/src/lib.rs @@ -13,7 +13,7 @@ pub type ExecutionResult = Result, Error>; #[derive(Default)] pub struct Interpreter { /// Whether we should try to give out-of-range bit decompositions when the input is not a single summand. - /// Used to do targetted testing of `<` flattening, making sure the bit decomposition we base the result on is unique. + /// Used to do targeted testing of `<` flattening, making sure the bit decomposition we base the result on is unique. should_try_out_of_range: bool, } diff --git a/zokrates_js/README.md b/zokrates_js/README.md index 8fbbd0007..21911e6cf 100644 --- a/zokrates_js/README.md +++ b/zokrates_js/README.md @@ -6,4 +6,4 @@ JavaScript bindings for [ZoKrates](https://github.com/Zokrates/ZoKrates) project npm install zokrates-js ``` -Check the offical [ZoKrates documentation](https://zokrates.github.io/toolbox/zokrates_js.html) for more details. +Check the official [ZoKrates documentation](https://zokrates.github.io/toolbox/zokrates_js.html) for more details. From 2fa711e0ca39353c90fbe975df891349e53fd57e Mon Sep 17 00:00:00 2001 From: dark64 Date: Thu, 19 Jan 2023 13:00:37 +0100 Subject: [PATCH 63/94] use ark parallel feature --- Cargo.lock | 125 +++++++++++++++++++++++++++++++++--- zokrates_ark/Cargo.toml | 4 +- zokrates_bellman/Cargo.toml | 1 + zokrates_embed/Cargo.toml | 2 +- zokrates_js/Cargo.toml | 4 +- 5 files changed, 122 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33389a5d4..4bffcb3ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,7 @@ dependencies = [ "blake2 0.9.2", "derivative", "digest 0.9.0", + "rayon", "tracing", ] @@ -141,6 +142,7 @@ dependencies = [ "ark-std", "derivative", "num-traits 0.2.15", + "rayon", "zeroize", ] @@ -158,6 +160,7 @@ dependencies = [ "num-bigint 0.4.3", "num-traits 0.2.15", "paste", + "rayon", "rustc_version", "zeroize", ] @@ -199,6 +202,7 @@ dependencies = [ "ark-serialize", "ark-std", "derivative", + "rayon", "tracing", ] @@ -215,6 +219,7 @@ dependencies = [ "ark-relations", "ark-serialize", "ark-std", + "rayon", ] [[package]] @@ -230,6 +235,7 @@ dependencies = [ "ark-std", "derivative", "digest 0.9.0", + "rayon", ] [[package]] @@ -261,6 +267,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.11.2", + "rayon", ] [[package]] @@ -271,11 +278,14 @@ checksum = "a71ddfa72bad1446cab7bbecb6018dbbdc9abcbc3a0065483ae5186ad2a64dcd" dependencies = [ "ark-ec", "ark-ff", + "ark-nonnative-field", "ark-poly", + "ark-relations", "ark-serialize", "ark-std", "derivative", "digest 0.9.0", + "rayon", "tracing", ] @@ -304,6 +314,7 @@ dependencies = [ "ark-ff", "ark-std", "tracing", + "tracing-subscriber", ] [[package]] @@ -347,6 +358,7 @@ checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" dependencies = [ "num-traits 0.2.15", "rand 0.8.5", + "rayon", ] [[package]] @@ -765,11 +777,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" dependencies = [ "cfg-if 0.1.10", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", + "crossbeam-channel 0.4.4", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", "crossbeam-queue", - "crossbeam-utils", + "crossbeam-utils 0.7.2", ] [[package]] @@ -778,21 +790,42 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.7.2", "maybe-uninit", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils 0.8.14", +] + [[package]] name = "crossbeam-deque" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", "maybe-uninit", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch 0.9.13", + "crossbeam-utils 0.8.14", +] + [[package]] name = "crossbeam-epoch" version = "0.8.2" @@ -801,10 +834,23 @@ checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ "autocfg", "cfg-if 0.1.10", - "crossbeam-utils", + "crossbeam-utils 0.7.2", "lazy_static", "maybe-uninit", - "memoffset", + "memoffset 0.5.6", + "scopeguard", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils 0.8.14", + "memoffset 0.7.1", "scopeguard", ] @@ -815,7 +861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" dependencies = [ "cfg-if 0.1.10", - "crossbeam-utils", + "crossbeam-utils 0.7.2", "maybe-uninit", ] @@ -830,6 +876,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1543,6 +1598,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "miniz_oxide" version = "0.5.3" @@ -2080,6 +2144,28 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel 0.5.6", + "crossbeam-deque 0.8.2", + "crossbeam-utils 0.8.14", + "num_cpus", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -2686,6 +2772,19 @@ name = "tracing-core" version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b7358be39f2f274f322d2aaed611acc57f382e8eb1e5b48cb9ae30933495ce7" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" +dependencies = [ + "tracing-core", +] [[package]] name = "typed-arena" @@ -2768,6 +2867,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vec_map" version = "0.8.2" diff --git a/zokrates_ark/Cargo.toml b/zokrates_ark/Cargo.toml index 86508b552..bc162969e 100644 --- a/zokrates_ark/Cargo.toml +++ b/zokrates_ark/Cargo.toml @@ -3,7 +3,9 @@ name = "zokrates_ark" version = "0.1.1" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["multicore"] +multicore = ["ark-groth16/parallel", "ark-gm17/parallel", "ark-marlin/parallel"] [dependencies] zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false } diff --git a/zokrates_bellman/Cargo.toml b/zokrates_bellman/Cargo.toml index 852b1fbed..86af751f0 100644 --- a/zokrates_bellman/Cargo.toml +++ b/zokrates_bellman/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [features] +default = ["multicore"] wasm = ["bellman/nolog", "bellman/wasm"] multicore = ["bellman/multicore", "phase2/multicore"] diff --git a/zokrates_embed/Cargo.toml b/zokrates_embed/Cargo.toml index 9249b9073..0a97a2de5 100644 --- a/zokrates_embed/Cargo.toml +++ b/zokrates_embed/Cargo.toml @@ -9,7 +9,7 @@ default = ["ark", "bellman"] ark = ["ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-relations", "ark-crypto-primitives", "ark-r1cs-std", "ark-std", "ark-ec", "ark-ff", "sapling-crypto_ce"] bellman = ["bellman_ce"] wasm = ["bellman_ce/wasm", "sapling-crypto_ce/wasm"] -multicore = ["bellman_ce/multicore", "sapling-crypto_ce/multicore"] +multicore = ["bellman_ce/multicore", "sapling-crypto_ce/multicore", "ark-gm17/parallel", "ark-r1cs-std/parallel"] [dependencies] zokrates_field = { version = "0.5.0", path = "../zokrates_field", default-features = false } diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index feb949d17..778e7b000 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -15,8 +15,8 @@ wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } typed-arena = "1.4.1" lazy_static = "1.4.0" zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } -zokrates_ark = { path = "../zokrates_ark", default-features = false} -zokrates_bellman = { path = "../zokrates_bellman", default-features = false} +zokrates_ark = { path = "../zokrates_ark", default-features = false } +zokrates_bellman = { path = "../zokrates_bellman", default-features = false, features = ["wasm"] } zokrates_common = { path = "../zokrates_common", default-features = false, features = ["ark", "bellman"] } zokrates_proof_systems = { path = "../zokrates_proof_systems", default-features = false } zokrates_ast = { path = "../zokrates_ast", default-features = false, features = ["ark", "bellman"] } From 6ee546d497d2fbcae7030db3363fe3c727ad41c1 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 03:28:06 +0100 Subject: [PATCH 64/94] optimize js lib size, inline wasm --- Cargo.lock | 5 +- zokrates_bellman/Cargo.toml | 4 +- zokrates_js/.gitignore | 5 +- zokrates_js/Cargo.toml | 1 + zokrates_js/build.rs | 2 +- zokrates_js/index-node.js | 5 + zokrates_js/index.js | 119 +++++- zokrates_js/lib.js | 112 ------ zokrates_js/node/index.js | 8 - zokrates_js/package-lock.json | 708 ++++++++++++++++++++++++++-------- zokrates_js/package.json | 31 +- zokrates_js/patch.js | 75 ++++ zokrates_js/publish.sh | 6 - zokrates_js/tests/tests.js | 18 +- 14 files changed, 781 insertions(+), 318 deletions(-) create mode 100644 zokrates_js/index-node.js delete mode 100644 zokrates_js/lib.js delete mode 100644 zokrates_js/node/index.js create mode 100644 zokrates_js/patch.js diff --git a/Cargo.lock b/Cargo.lock index 33389a5d4..5f9137d7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1270,9 +1270,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3258,6 +3258,7 @@ name = "zokrates_js" version = "1.1.4" dependencies = [ "console_error_panic_hook", + "getrandom", "indexmap", "js-sys", "json", diff --git a/zokrates_bellman/Cargo.toml b/zokrates_bellman/Cargo.toml index 852b1fbed..124efb23f 100644 --- a/zokrates_bellman/Cargo.toml +++ b/zokrates_bellman/Cargo.toml @@ -15,8 +15,8 @@ zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", bellman = { package = "bellman_ce", version = "^0.3", default-features = false } pairing = { package = "pairing_ce", version = "^0.21" } phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false } -rand_0_4 = { version = "0.4", package = "rand" }# -getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] } +rand_0_4 = { version = "0.4", package = "rand" } +getrandom = { version = "0.2.8" } hex = "0.4.2" [dev-dependencies] diff --git a/zokrates_js/.gitignore b/zokrates_js/.gitignore index cd9aa5f80..3817319e6 100644 --- a/zokrates_js/.gitignore +++ b/zokrates_js/.gitignore @@ -3,6 +3,5 @@ dist target pkg wasm-pack.log -stdlib -stdlib.js -metadata.js \ No newline at end of file +metadata.js +wasm.js \ No newline at end of file diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index feb949d17..9aabea505 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -26,6 +26,7 @@ zokrates_abi = { path = "../zokrates_abi", default-features = false, features = zokrates_circom = { path = "../zokrates_circom" } console_error_panic_hook = "0.1.6" indexmap = "~1.6.2" # see https://github.com/rustwasm/wasm-bindgen/issues/2770#issuecomment-1041102532 +getrandom = { version = "0.2.8", features = ["js"] } [build-dependencies] json = "0.12.4" diff --git a/zokrates_js/build.rs b/zokrates_js/build.rs index 5eea2bc9d..ea3b67847 100644 --- a/zokrates_js/build.rs +++ b/zokrates_js/build.rs @@ -42,7 +42,7 @@ fn export_metadata() { fs::write( "metadata.js", - format!("module.exports = {}", metadata.dump()), + format!("export default {}", metadata.dump()), ) .unwrap(); } diff --git a/zokrates_js/index-node.js b/zokrates_js/index-node.js new file mode 100644 index 000000000..9eebb16d3 --- /dev/null +++ b/zokrates_js/index-node.js @@ -0,0 +1,5 @@ +// https://docs.rs/getrandom/0.2.8/getrandom/index.html#nodejs-es-module-support +import { webcrypto } from 'node:crypto'; +globalThis.crypto = webcrypto; + +export * from "./index.js"; \ No newline at end of file diff --git a/zokrates_js/index.js b/zokrates_js/index.js index 2d7b9514c..559421a88 100644 --- a/zokrates_js/index.js +++ b/zokrates_js/index.js @@ -1,9 +1,120 @@ -import lib from "./lib.js"; +import { inflate } from "pako"; import metadata from "./metadata.js"; +import * as wasmExports from "./wasm.js"; const initialize = async () => { - const pkg = await import("./pkg/index.js"); - return lib(pkg); + await wasmExports.init(inflate); + + const defaultProvider = { + compile: (source, compileOptions = {}) => { + var { + curve = "bn128", + location = "main.zok", + resolveCallback = () => null, + config = {}, + snarkjs = false, + } = compileOptions; + + config = { snarkjs, ...config }; + + const ptr = wasmExports.compile(source, location, resolveCallback, config, curve); + const result = Object.assign( + { + program: ptr.program(), + abi: ptr.abi(), + constraintCount: ptr.constraint_count(), + }, + snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} + ); + ptr.free(); + return result; + }, + computeWitness: (input, args, computeOptions = {}) => { + const { program, abi } = + input instanceof Uint8Array ? { program: input, abi: null } : input; + + const { snarkjs = false, logCallback = console.log } = computeOptions; + const ptr = wasmExports.compute_witness( + program, + abi, + JSON.stringify(args), + { + snarkjs: snarkjs, + }, + logCallback + ); + + const result = Object.assign( + { + witness: ptr.witness(), + output: ptr.output(), + }, + snarkjs + ? { + snarkjs: { + witness: ptr.snarkjs_witness(), + }, + } + : {} + ); + + ptr.free(); + return result; + }, + setup: (program, options) => { + return wasmExports.setup(program, options); + }, + universalSetup: (curve, size) => { + return wasmExports.universal_setup(curve, size); + }, + setupWithSrs: (srs, program, options) => { + return wasmExports.setup_with_srs(srs, program, options); + }, + generateProof: (program, witness, provingKey, options) => { + return wasmExports.generate_proof(program, witness, provingKey, options); + }, + verify: (vk, proof, options) => { + return wasmExports.verify(vk, proof, options); + }, + exportSolidityVerifier: (vk) => { + return wasmExports.export_solidity_verifier(vk); + }, + utils: { + formatProof: (proof) => { + return wasmExports.format_proof(proof); + }, + }, + }; + + const withOptions = (options) => { + return { + withOptions, + compile: (source, compileOptions = {}) => + defaultProvider.compile(source, { + ...compileOptions, + curve: options.curve, + }), + computeWitness: (artifacts, args, computeOptions = {}) => + defaultProvider.computeWitness(artifacts, args, computeOptions), + setup: (program) => defaultProvider.setup(program, options), + universalSetup: (size) => + defaultProvider.universalSetup(options.curve, size), + setupWithSrs: (srs, program) => + defaultProvider.setupWithSrs(srs, program, options), + generateProof: (program, witness, provingKey) => + defaultProvider.generateProof(program, witness, provingKey, options), + verify: (vk, proof) => defaultProvider.verify(vk, proof, options), + exportSolidityVerifier: (vk) => + defaultProvider.exportSolidityVerifier(vk), + utils: { + formatProof: (proof) => defaultProvider.utils.formatProof(proof), + }, + }; + }; + + return { + ...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }), + }; }; -export { initialize, metadata }; +export { initialize, metadata }; \ No newline at end of file diff --git a/zokrates_js/lib.js b/zokrates_js/lib.js deleted file mode 100644 index b3e1ff4ef..000000000 --- a/zokrates_js/lib.js +++ /dev/null @@ -1,112 +0,0 @@ -module.exports = (pkg) => { - const defaultProvider = { - compile: (source, compileOptions = {}) => { - var { - curve = "bn128", - location = "main.zok", - resolveCallback = () => null, - config = {}, - snarkjs = false, - } = compileOptions; - - config = { snarkjs, ...config }; - - const ptr = pkg.compile(source, location, resolveCallback, config, curve); - const result = Object.assign( - { - program: ptr.program(), - abi: ptr.abi(), - constraintCount: ptr.constraint_count(), - }, - snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} - ); - ptr.free(); - return result; - }, - computeWitness: (input, args, computeOptions = {}) => { - const { program, abi } = - input instanceof Uint8Array ? { program: input, abi: null } : input; - - const { snarkjs = false, logCallback = console.log } = computeOptions; - const ptr = pkg.compute_witness( - program, - abi, - JSON.stringify(args), - { - snarkjs: snarkjs, - }, - logCallback - ); - - const result = Object.assign( - { - witness: ptr.witness(), - output: ptr.output(), - }, - snarkjs - ? { - snarkjs: { - witness: ptr.snarkjs_witness(), - }, - } - : {} - ); - - ptr.free(); - return result; - }, - setup: (program, options) => { - return pkg.setup(program, options); - }, - universalSetup: (curve, size) => { - return pkg.universal_setup(curve, size); - }, - setupWithSrs: (srs, program, options) => { - return pkg.setup_with_srs(srs, program, options); - }, - generateProof: (program, witness, provingKey, options) => { - return pkg.generate_proof(program, witness, provingKey, options); - }, - verify: (vk, proof, options) => { - return pkg.verify(vk, proof, options); - }, - exportSolidityVerifier: (vk) => { - return pkg.export_solidity_verifier(vk); - }, - utils: { - formatProof: (proof) => { - return pkg.format_proof(proof); - }, - }, - }; - - const withOptions = (options) => { - return { - withOptions, - compile: (source, compileOptions = {}) => - defaultProvider.compile(source, { - ...compileOptions, - curve: options.curve, - }), - computeWitness: (artifacts, args, computeOptions = {}) => - defaultProvider.computeWitness(artifacts, args, computeOptions), - setup: (program) => defaultProvider.setup(program, options), - universalSetup: (size) => - defaultProvider.universalSetup(options.curve, size), - setupWithSrs: (srs, program) => - defaultProvider.setupWithSrs(srs, program, options), - generateProof: (program, witness, provingKey) => - defaultProvider.generateProof(program, witness, provingKey, options), - verify: (vk, proof) => defaultProvider.verify(vk, proof, options), - exportSolidityVerifier: (vk) => - defaultProvider.exportSolidityVerifier(vk), - utils: { - formatProof: (proof) => defaultProvider.utils.formatProof(proof), - }, - }; - }; - - return { - ...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }), - }; -}; diff --git a/zokrates_js/node/index.js b/zokrates_js/node/index.js deleted file mode 100644 index d6d50f3ba..000000000 --- a/zokrates_js/node/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const lib = require("../lib.js"); -const metadata = require("../metadata.js"); - -const initialize = async () => { - return lib(require("./pkg/index.js")); -}; - -module.exports = { initialize, metadata }; diff --git a/zokrates_js/package-lock.json b/zokrates_js/package-lock.json index b15cb706f..8cb663f83 100644 --- a/zokrates_js/package-lock.json +++ b/zokrates_js/package-lock.json @@ -6,10 +6,15 @@ "packages": { "": { "name": "zokrates-js", - "version": "1.1.2", + "version": "1.1.4", "license": "GPLv3", + "dependencies": { + "pako": "^2.1.0" + }, "devDependencies": { - "dree": "^2.6.1", + "acorn": "^8.8.1", + "astring": "^1.8.4", + "dree": "^3.4.3", "mocha": "^9.2.0", "rimraf": "^3.0.2", "snarkjs": "^0.4.25", @@ -34,8 +39,21 @@ }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, - "license": "ISC" + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, "node_modules/ansi-regex": { "version": "5.0.1", @@ -48,8 +66,9 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -62,31 +81,45 @@ }, "node_modules/argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/astring": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.4.tgz", + "integrity": "sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==", "dev": true, - "license": "Python-2.0" + "bin": { + "astring": "bin/astring" + } }, "node_modules/async": { "version": "3.2.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true }, "node_modules/axios": { "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, - "license": "MIT", "dependencies": { "follow-redirects": "^1.14.0" } }, "node_modules/b4a": { "version": "1.5.3", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", + "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", + "dev": true }, "node_modules/balanced-match": { "version": "1.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "node_modules/bfj": { "version": "7.0.2", @@ -114,8 +147,9 @@ }, "node_modules/binary-install": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", + "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", "dev": true, - "license": "MIT", "dependencies": { "axios": "^0.21.1", "rimraf": "^3.0.2", @@ -127,8 +161,9 @@ }, "node_modules/blake2b-wasm": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", "dev": true, - "license": "MIT", "dependencies": { "b4a": "^1.0.1", "nanoassert": "^2.0.0" @@ -148,8 +183,9 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -157,8 +193,9 @@ }, "node_modules/browser-stdout": { "version": "1.3.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "node_modules/check-types": { "version": "11.1.2", @@ -168,8 +205,9 @@ }, "node_modules/chownr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } @@ -188,8 +226,9 @@ }, "node_modules/cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -198,8 +237,9 @@ }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -209,56 +249,73 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/concat-map": { "version": "0.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dree": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/dree/-/dree-2.8.4.tgz", - "integrity": "sha512-2mrDEAfvLcSelHhZEiJSI4ESFnih5th6cZoqbCwOw8siJy88uCaQMi6wJy4t0IUKHSRDGPpNas+IT8M2EeEFBg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/dree/-/dree-3.4.3.tgz", + "integrity": "sha512-InS4gt3Mqw1/VH9zxKHb9kE4K20H58h91ByR2+6XM3oxalpEUqDhfusK13W1++lePcE+0W1S0A4d3syr405Siw==", "dev": true, "dependencies": { - "yargs": "^17.3.1" + "yargs": "^17.6.2" }, "bin": { "dree": "bundled/bin/index.js" } }, + "node_modules/dree/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dree/node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" } }, "node_modules/dree/node_modules/yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { "node": ">=12" @@ -266,8 +323,9 @@ }, "node_modules/ejs": { "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -280,13 +338,15 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "node_modules/escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -311,24 +371,27 @@ }, "node_modules/filelist": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, - "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, "node_modules/filelist/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/filelist/node_modules/minimatch": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -338,14 +401,17 @@ }, "node_modules/flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true, - "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/follow-redirects": { "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true, "funding": [ { @@ -353,7 +419,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -365,8 +430,9 @@ }, "node_modules/fs-minipass": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -376,21 +442,24 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "node_modules/get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/glob": { "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -408,16 +477,18 @@ }, "node_modules/growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true, - "license": "MIT", "engines": { "node": ">=4.x" } }, "node_modules/he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, - "license": "MIT", "bin": { "he": "bin/he" } @@ -433,8 +504,9 @@ }, "node_modules/inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, - "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -442,29 +514,33 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, - "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -474,16 +550,18 @@ }, "node_modules/is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -493,13 +571,15 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "node_modules/jake": { "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", @@ -515,8 +595,9 @@ }, "node_modules/jake/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -530,16 +611,18 @@ }, "node_modules/jake/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/jake/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -549,13 +632,15 @@ }, "node_modules/js-sha3": { "version": "0.8.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -565,8 +650,9 @@ }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, - "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -579,8 +665,9 @@ }, "node_modules/log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, - "license": "MIT", "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -594,8 +681,9 @@ }, "node_modules/log-symbols/node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -609,16 +697,18 @@ }, "node_modules/log-symbols/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/log-symbols/node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -628,13 +718,15 @@ }, "node_modules/logplease": { "version": "1.2.15", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", + "dev": true }, "node_modules/minimatch": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -644,8 +736,9 @@ }, "node_modules/minipass": { "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, - "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -655,13 +748,15 @@ }, "node_modules/minipass/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/minizlib": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -672,13 +767,15 @@ }, "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/mocha": { "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", "dev": true, - "license": "MIT", "dependencies": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -719,16 +816,18 @@ }, "node_modules/mocha/node_modules/ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mocha/node_modules/anymatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, - "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -739,16 +838,18 @@ }, "node_modules/mocha/node_modules/binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/mocha/node_modules/braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -758,6 +859,8 @@ }, "node_modules/mocha/node_modules/chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "funding": [ { @@ -765,7 +868,6 @@ "url": "https://paulmillr.com/funding/" } ], - "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -784,8 +886,9 @@ }, "node_modules/mocha/node_modules/debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, - "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -800,13 +903,15 @@ }, "node_modules/mocha/node_modules/debug/node_modules/ms": { "version": "2.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/mocha/node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -816,8 +921,9 @@ }, "node_modules/mocha/node_modules/fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -827,8 +933,9 @@ }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, - "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -842,8 +949,10 @@ }, "node_modules/mocha/node_modules/fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "license": "MIT", + "hasInstallScript": true, "optional": true, "os": [ "darwin" @@ -854,8 +963,9 @@ }, "node_modules/mocha/node_modules/glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, - "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -873,8 +983,9 @@ }, "node_modules/mocha/node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -884,8 +995,9 @@ }, "node_modules/mocha/node_modules/is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, - "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -895,37 +1007,42 @@ }, "node_modules/mocha/node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/mocha/node_modules/ms": { "version": "2.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/mocha/node_modules/normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/mocha/node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/mocha/node_modules/readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, - "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -935,8 +1052,9 @@ }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" }, @@ -946,8 +1064,9 @@ }, "node_modules/mocha/node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -957,8 +1076,9 @@ }, "node_modules/mocha/node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -971,21 +1091,24 @@ }, "node_modules/mocha/node_modules/yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/nanoassert": { "version": "2.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", + "dev": true }, "node_modules/nanoid": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true, - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -995,16 +1118,18 @@ }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, - "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -1017,8 +1142,9 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, - "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -1029,18 +1155,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, "node_modules/path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1062,24 +1195,27 @@ }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, - "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, - "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -1092,13 +1228,15 @@ }, "node_modules/safe-buffer": { "version": "5.1.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -1152,8 +1290,9 @@ }, "node_modules/supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -1166,16 +1305,18 @@ }, "node_modules/supports-color/node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/tar": { "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, - "license": "ISC", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -1190,8 +1331,9 @@ }, "node_modules/tar/node_modules/mkdirp": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "license": "MIT", "bin": { "mkdirp": "bin/cmd.js" }, @@ -1201,8 +1343,9 @@ }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/tryer": { "version": "1.0.1", @@ -1212,9 +1355,10 @@ }, "node_modules/wasm-pack": { "version": "0.10.2", + "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.10.2.tgz", + "integrity": "sha512-Kuh8XAArQNVoikMUenjDs4+g6LpktgfXgqlp03G2dJKDBokA7Y8Cx6MDCnvREzNnmprk9IohHytwycVSemwe/w==", "dev": true, "hasInstallScript": true, - "license": "MIT OR Apache-2.0", "dependencies": { "binary-install": "^0.1.0" }, @@ -1249,13 +1393,15 @@ }, "node_modules/workerpool": { "version": "6.2.0", - "dev": true, - "license": "Apache-2.0" + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true }, "node_modules/wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1270,21 +1416,24 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "node_modules/y18n": { "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, - "license": "MIT", "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -1300,16 +1449,18 @@ }, "node_modules/yargs-parser": { "version": "20.2.6", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", + "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", "dev": true, - "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, - "license": "MIT", "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -1322,8 +1473,9 @@ }, "node_modules/yargs-unparser/node_modules/camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -1333,8 +1485,9 @@ }, "node_modules/yargs-unparser/node_modules/decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -1344,8 +1497,9 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, @@ -1373,6 +1527,14 @@ }, "@ungap/promise-all-settled": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true }, "ansi-regex": { @@ -1383,6 +1545,8 @@ }, "ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" @@ -1390,14 +1554,26 @@ }, "argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "astring": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.4.tgz", + "integrity": "sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==", "dev": true }, "async": { "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, "axios": { "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, "requires": { "follow-redirects": "^1.14.0" @@ -1405,10 +1581,14 @@ }, "b4a": { "version": "1.5.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", + "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", "dev": true }, "balanced-match": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "bfj": { @@ -1431,6 +1611,8 @@ }, "binary-install": { "version": "0.1.1", + "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", + "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", "dev": true, "requires": { "axios": "^0.21.1", @@ -1440,6 +1622,8 @@ }, "blake2b-wasm": { "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", "dev": true, "requires": { "b4a": "^1.0.1", @@ -1460,6 +1644,8 @@ }, "brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -1468,6 +1654,8 @@ }, "browser-stdout": { "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "check-types": { @@ -1478,6 +1666,8 @@ }, "chownr": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, "circom_runtime": { @@ -1491,6 +1681,8 @@ }, "cliui": { "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", @@ -1500,6 +1692,8 @@ }, "color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" @@ -1507,50 +1701,69 @@ }, "color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "diff": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "dree": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/dree/-/dree-2.8.4.tgz", - "integrity": "sha512-2mrDEAfvLcSelHhZEiJSI4ESFnih5th6cZoqbCwOw8siJy88uCaQMi6wJy4t0IUKHSRDGPpNas+IT8M2EeEFBg==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/dree/-/dree-3.4.3.tgz", + "integrity": "sha512-InS4gt3Mqw1/VH9zxKHb9kE4K20H58h91ByR2+6XM3oxalpEUqDhfusK13W1++lePcE+0W1S0A4d3syr405Siw==", "dev": true, "requires": { - "yargs": "^17.3.1" + "yargs": "^17.6.2" }, "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } }, "ejs": { "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", "dev": true, "requires": { "jake": "^10.8.5" @@ -1558,10 +1771,14 @@ }, "emoji-regex": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "escalade": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "fastfile": { @@ -1584,6 +1801,8 @@ }, "filelist": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", "dev": true, "requires": { "minimatch": "^5.0.1" @@ -1591,6 +1810,8 @@ "dependencies": { "brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -1598,6 +1819,8 @@ }, "minimatch": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -1607,14 +1830,20 @@ }, "flat": { "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, "follow-redirects": { "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true }, "fs-minipass": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { "minipass": "^3.0.0" @@ -1622,14 +1851,20 @@ }, "fs.realpath": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "get-caller-file": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "glob": { "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1642,10 +1877,14 @@ }, "growl": { "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "he": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "hoopy": { @@ -1656,6 +1895,8 @@ }, "inflight": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", @@ -1664,18 +1905,26 @@ }, "inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -1683,18 +1932,26 @@ }, "is-plain-obj": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-unicode-supported": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "jake": { "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", "dev": true, "requires": { "async": "^3.2.3", @@ -1705,6 +1962,8 @@ "dependencies": { "chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -1713,10 +1972,14 @@ }, "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -1726,10 +1989,14 @@ }, "js-sha3": { "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "dev": true }, "js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -1737,6 +2004,8 @@ }, "locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" @@ -1744,6 +2013,8 @@ }, "log-symbols": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -1752,6 +2023,8 @@ "dependencies": { "chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -1760,10 +2033,14 @@ }, "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -1773,10 +2050,14 @@ }, "logplease": { "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", "dev": true }, "minimatch": { "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -1784,6 +2065,8 @@ }, "minipass": { "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -1791,12 +2074,16 @@ "dependencies": { "yallist": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "minizlib": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "requires": { "minipass": "^3.0.0", @@ -1805,12 +2092,16 @@ "dependencies": { "yallist": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "mocha": { "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -1841,10 +2132,14 @@ "dependencies": { "ansi-colors": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, "anymatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -1853,10 +2148,14 @@ }, "binary-extensions": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "braces": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.0.1" @@ -1864,6 +2163,8 @@ }, "chokidar": { "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dev": true, "requires": { "anymatch": "~3.1.2", @@ -1878,6 +2179,8 @@ }, "debug": { "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" @@ -1885,16 +2188,22 @@ "dependencies": { "ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "fill-range": { "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -1902,6 +2211,8 @@ }, "find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", @@ -1910,11 +2221,15 @@ }, "fsevents": { "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, "glob": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1927,6 +2242,8 @@ }, "glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -1934,6 +2251,8 @@ }, "is-binary-path": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" @@ -1941,22 +2260,32 @@ }, "is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "ms": { "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "normalize-path": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "readdirp": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "requires": { "picomatch": "^2.2.1" @@ -1964,10 +2293,14 @@ }, "strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" @@ -1975,6 +2308,8 @@ }, "which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -1982,20 +2317,28 @@ }, "yargs-parser": { "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true } } }, "nanoassert": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", "dev": true }, "nanoid": { "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true }, "once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" @@ -2003,6 +2346,8 @@ }, "p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" @@ -2010,17 +2355,28 @@ }, "p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" } }, + "pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, "path-is-absolute": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "r1csfile": { @@ -2037,6 +2393,8 @@ }, "randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -2044,10 +2402,14 @@ }, "require-directory": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "rimraf": { "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -2055,10 +2417,14 @@ }, "safe-buffer": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "serialize-javascript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -2104,6 +2470,8 @@ }, "supports-color": { "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -2111,12 +2479,16 @@ "dependencies": { "has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true } } }, "tar": { "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -2129,10 +2501,14 @@ "dependencies": { "mkdirp": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, "yallist": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } @@ -2145,6 +2521,8 @@ }, "wasm-pack": { "version": "0.10.2", + "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.10.2.tgz", + "integrity": "sha512-Kuh8XAArQNVoikMUenjDs4+g6LpktgfXgqlp03G2dJKDBokA7Y8Cx6MDCnvREzNnmprk9IohHytwycVSemwe/w==", "dev": true, "requires": { "binary-install": "^0.1.0" @@ -2177,10 +2555,14 @@ }, "workerpool": { "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", "dev": true }, "wrap-ansi": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -2190,14 +2572,20 @@ }, "wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "y18n": { "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true }, "yargs": { "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", @@ -2211,10 +2599,14 @@ }, "yargs-parser": { "version": "20.2.6", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", + "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", "dev": true }, "yargs-unparser": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { "camelcase": "^6.0.0", @@ -2225,16 +2617,22 @@ "dependencies": { "camelcase": { "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "decamelize": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true } } }, "yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } diff --git a/zokrates_js/package.json b/zokrates_js/package.json index ce404bacd..934268a41 100644 --- a/zokrates_js/package.json +++ b/zokrates_js/package.json @@ -2,7 +2,7 @@ "name": "zokrates-js", "version": "1.1.4", "module": "index.js", - "main": "node/index.js", + "main": "index-node.js", "description": "JavaScript bindings for ZoKrates", "contributors": [ "Darko Macesic ", @@ -15,38 +15,37 @@ ], "license": "GPLv3", "files": [ - "node", - "pkg", "index.js", + "index-node.js", "index.d.ts", - "lib.js", + "wasm.js", "metadata.js" ], "types": "index.d.ts", + "type": "module", "exports": { - "node": "./node/index.js", + "node": "./index-node.js", "default": "./index.js" }, "scripts": { - "wasm-pack": "wasm-pack build --out-name index", + "wasm-pack": "wasm-pack build --out-name index --target web", "prebuild": "npm install", - "build": "npm run build:bundler && npm run build:node", - "build:dev": "npm run build:bundler:dev && npm run build:node:dev", - "build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg", - "build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg", - "build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg", - "build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg", - "clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts", - "clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts", - "pretest": "npm run build:node:dev", + "build": "npm run wasm-pack -- --release && node patch.js", + "build:dev": "npm run wasm-pack -- --dev && node patch.js", + "pretest": "npm run build:dev", "test": "npm run run-tests", "run-tests": "mocha --timeout 100000 --recursive tests" }, "devDependencies": { - "dree": "^2.6.1", + "acorn": "^8.8.1", + "astring": "^1.8.4", + "dree": "^3.4.3", "mocha": "^9.2.0", "rimraf": "^3.0.2", "snarkjs": "^0.4.25", "wasm-pack": "^0.10.2" + }, + "dependencies": { + "pako": "^2.1.0" } } diff --git a/zokrates_js/patch.js b/zokrates_js/patch.js new file mode 100644 index 000000000..b20652d0b --- /dev/null +++ b/zokrates_js/patch.js @@ -0,0 +1,75 @@ +import { parse } from "acorn"; +import { generate } from "astring"; +import fs from "fs/promises"; +import pako from "pako"; + +(async function () { + const packageObject = JSON.parse( + await fs.readFile("pkg/package.json", { encoding: "utf-8" }) + ); + const wasmPath = packageObject.files.find((file) => file.endsWith(".wasm")); + const wasm = await fs.readFile(`pkg/${wasmPath}`); + + const deflated = Buffer.from(pako.deflate(wasm)); + const wasmBase64 = deflated.toString("base64"); + + const init = `export async function init(inflate) { + const encoded = '${wasmBase64}'; + + let bytes; + + if (typeof atob === 'function') { + const binary = atob(encoded); + bytes = new Uint8Array(binary.length); + + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + } else if (typeof Buffer === 'function') { + bytes = Buffer.from(encoded, 'base64'); + } else { + throw new Error('Unsupported platform'); + } + + const imports = getImports(); + initMemory(imports); + + bytes = inflate(bytes); + + const { instance, module } = await WebAssembly.instantiate(bytes, imports); + return finalizeInit(instance, module); +} + +export default init;`; + + const generatedSource = await fs.readFile(`pkg/${packageObject.module}`, { + encoding: "utf-8", + }); + + const ast = parse(generatedSource, { + ecmaVersion: "latest", + sourceType: "module", + }); + + let body = ast.body.filter((v) => { + switch (v.type) { + case "FunctionDeclaration": + // we don't use these functions so we strip them out + return !["load", "init", "initSync"].includes(v.id.name); + case "ExportDefaultDeclaration": + // we will provide our own default export + return false; + default: + return true; + } + }); + + body.pop(); // removes `export { initSync }` + + const source = generate({ + ...ast, + body, + }); + + await fs.writeFile("wasm.js", source + init); +})(); diff --git a/zokrates_js/publish.sh b/zokrates_js/publish.sh index f625a0c0f..681dcd1a8 100755 --- a/zokrates_js/publish.sh +++ b/zokrates_js/publish.sh @@ -24,12 +24,6 @@ if [ $NPM_VERSION = $PACKAGE_VERSION ]; then exit 0 fi -# make sure the pkg folder is present -if [ ! -d "pkg" ]; then - echo "pkg folder is missing" - exit 1 -fi - # publish npm set //registry.npmjs.org/:_authToken=${NPM_TOKEN} npm publish \ No newline at end of file diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index 8202baa12..efb4cbd70 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -1,10 +1,10 @@ -const assert = require("assert"); -const path = require("path"); -const fs = require("fs"); -const os = require("os"); -const dree = require("dree"); -const snarkjs = require("snarkjs"); -const { initialize, metadata } = require("../node/index.js"); +import assert from "assert"; +import path from "path"; +import fs from "fs"; +import os from "os"; +import * as snarkjs from "snarkjs"; +import dree from "dree"; +import { initialize, metadata } from "../index.js"; let zokratesProvider; let tmpFolder; @@ -364,8 +364,8 @@ describe("tests", () => { extensions: ["json"], }; - dree.scan(testsPath, options, function (file) { - const test = require(file.path); + dree.scan(testsPath, options, async function (file) { + const test = JSON.parse(await fs.promises.readFile(file.path)); const testName = file.path.substring(testsPath.length + 1); if (!ignoreList.some((v) => testName.startsWith(v))) From 8d8972af9e671910985a6663062c93519e63b7c1 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 03:29:49 +0100 Subject: [PATCH 65/94] add getrandom dependency --- Cargo.lock | 1 + zokrates_test/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5f9137d7c..2e653ca11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3345,6 +3345,7 @@ dependencies = [ name = "zokrates_test" version = "0.2.0" dependencies = [ + "getrandom", "serde", "serde_derive", "serde_json", diff --git a/zokrates_test/Cargo.toml b/zokrates_test/Cargo.toml index d1fef01bf..2ec6a80ea 100644 --- a/zokrates_test/Cargo.toml +++ b/zokrates_test/Cargo.toml @@ -21,6 +21,6 @@ typed-arena = "1.4.1" wasm-bindgen-test = "^0.3.0" zokrates_ark = { version = "0.1", path = "../zokrates_ark" } zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems" } - +getrandom = { version = "0.2.8", features = ["js"] } [lib] From b090888b810946cb00447d5875b17d380ff92e87 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 03:34:03 +0100 Subject: [PATCH 66/94] fmt --- zokrates_js/build.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/zokrates_js/build.rs b/zokrates_js/build.rs index ea3b67847..45d38a383 100644 --- a/zokrates_js/build.rs +++ b/zokrates_js/build.rs @@ -40,9 +40,5 @@ fn export_metadata() { .insert("version", config["package"]["version"].as_str().unwrap()) .unwrap(); - fs::write( - "metadata.js", - format!("export default {}", metadata.dump()), - ) - .unwrap(); + fs::write("metadata.js", format!("export default {}", metadata.dump())).unwrap(); } From b9d8965392cbea4c157c6ffe933dfd7c08b192d0 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 13:08:42 +0100 Subject: [PATCH 67/94] fix tests --- zokrates_js/index-node.js | 4 +- zokrates_js/index.js | 206 +++++++++++++++++++------------------ zokrates_js/patch.js | 2 +- zokrates_js/tests/tests.js | 2 +- 4 files changed, 110 insertions(+), 104 deletions(-) diff --git a/zokrates_js/index-node.js b/zokrates_js/index-node.js index 9eebb16d3..566a24632 100644 --- a/zokrates_js/index-node.js +++ b/zokrates_js/index-node.js @@ -1,5 +1,5 @@ // https://docs.rs/getrandom/0.2.8/getrandom/index.html#nodejs-es-module-support -import { webcrypto } from 'node:crypto'; +import { webcrypto } from "node:crypto"; globalThis.crypto = webcrypto; -export * from "./index.js"; \ No newline at end of file +export * from "./index.js"; diff --git a/zokrates_js/index.js b/zokrates_js/index.js index 559421a88..143326b43 100644 --- a/zokrates_js/index.js +++ b/zokrates_js/index.js @@ -6,115 +6,121 @@ const initialize = async () => { await wasmExports.init(inflate); const defaultProvider = { - compile: (source, compileOptions = {}) => { - var { - curve = "bn128", - location = "main.zok", - resolveCallback = () => null, - config = {}, - snarkjs = false, - } = compileOptions; + compile: (source, compileOptions = {}) => { + var { + curve = "bn128", + location = "main.zok", + resolveCallback = () => null, + config = {}, + snarkjs = false, + } = compileOptions; - config = { snarkjs, ...config }; + config = { snarkjs, ...config }; - const ptr = wasmExports.compile(source, location, resolveCallback, config, curve); - const result = Object.assign( - { - program: ptr.program(), - abi: ptr.abi(), - constraintCount: ptr.constraint_count(), - }, - snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} - ); - ptr.free(); - return result; - }, - computeWitness: (input, args, computeOptions = {}) => { - const { program, abi } = - input instanceof Uint8Array ? { program: input, abi: null } : input; + const ptr = wasmExports.compile( + source, + location, + resolveCallback, + config, + curve + ); + const result = Object.assign( + { + program: ptr.program(), + abi: ptr.abi(), + constraintCount: ptr.constraint_count(), + }, + snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {} + ); + ptr.free(); + return result; + }, + computeWitness: (input, args, computeOptions = {}) => { + const { program, abi } = + input instanceof Uint8Array ? { program: input, abi: null } : input; - const { snarkjs = false, logCallback = console.log } = computeOptions; - const ptr = wasmExports.compute_witness( - program, - abi, - JSON.stringify(args), - { - snarkjs: snarkjs, - }, - logCallback - ); + const { snarkjs = false, logCallback = console.log } = computeOptions; + const ptr = wasmExports.compute_witness( + program, + abi, + JSON.stringify(args), + { + snarkjs: snarkjs, + }, + logCallback + ); - const result = Object.assign( - { - witness: ptr.witness(), - output: ptr.output(), - }, - snarkjs - ? { - snarkjs: { - witness: ptr.snarkjs_witness(), - }, - } - : {} - ); + const result = Object.assign( + { + witness: ptr.witness(), + output: ptr.output(), + }, + snarkjs + ? { + snarkjs: { + witness: ptr.snarkjs_witness(), + }, + } + : {} + ); - ptr.free(); - return result; - }, - setup: (program, options) => { - return wasmExports.setup(program, options); - }, - universalSetup: (curve, size) => { - return wasmExports.universal_setup(curve, size); - }, - setupWithSrs: (srs, program, options) => { - return wasmExports.setup_with_srs(srs, program, options); - }, - generateProof: (program, witness, provingKey, options) => { - return wasmExports.generate_proof(program, witness, provingKey, options); - }, - verify: (vk, proof, options) => { - return wasmExports.verify(vk, proof, options); - }, - exportSolidityVerifier: (vk) => { - return wasmExports.export_solidity_verifier(vk); + ptr.free(); + return result; + }, + setup: (program, options) => { + return wasmExports.setup(program, options); + }, + universalSetup: (curve, size) => { + return wasmExports.universal_setup(curve, size); + }, + setupWithSrs: (srs, program, options) => { + return wasmExports.setup_with_srs(srs, program, options); + }, + generateProof: (program, witness, provingKey, options) => { + return wasmExports.generate_proof(program, witness, provingKey, options); + }, + verify: (vk, proof, options) => { + return wasmExports.verify(vk, proof, options); + }, + exportSolidityVerifier: (vk) => { + return wasmExports.export_solidity_verifier(vk); + }, + utils: { + formatProof: (proof) => { + return wasmExports.format_proof(proof); }, + }, + }; + + const withOptions = (options) => { + return { + withOptions, + compile: (source, compileOptions = {}) => + defaultProvider.compile(source, { + ...compileOptions, + curve: options.curve, + }), + computeWitness: (artifacts, args, computeOptions = {}) => + defaultProvider.computeWitness(artifacts, args, computeOptions), + setup: (program) => defaultProvider.setup(program, options), + universalSetup: (size) => + defaultProvider.universalSetup(options.curve, size), + setupWithSrs: (srs, program) => + defaultProvider.setupWithSrs(srs, program, options), + generateProof: (program, witness, provingKey) => + defaultProvider.generateProof(program, witness, provingKey, options), + verify: (vk, proof) => defaultProvider.verify(vk, proof, options), + exportSolidityVerifier: (vk) => + defaultProvider.exportSolidityVerifier(vk), utils: { - formatProof: (proof) => { - return wasmExports.format_proof(proof); - }, + formatProof: (proof) => defaultProvider.utils.formatProof(proof), }, }; + }; - const withOptions = (options) => { - return { - withOptions, - compile: (source, compileOptions = {}) => - defaultProvider.compile(source, { - ...compileOptions, - curve: options.curve, - }), - computeWitness: (artifacts, args, computeOptions = {}) => - defaultProvider.computeWitness(artifacts, args, computeOptions), - setup: (program) => defaultProvider.setup(program, options), - universalSetup: (size) => - defaultProvider.universalSetup(options.curve, size), - setupWithSrs: (srs, program) => - defaultProvider.setupWithSrs(srs, program, options), - generateProof: (program, witness, provingKey) => - defaultProvider.generateProof(program, witness, provingKey, options), - verify: (vk, proof) => defaultProvider.verify(vk, proof, options), - exportSolidityVerifier: (vk) => - defaultProvider.exportSolidityVerifier(vk), - utils: { - formatProof: (proof) => defaultProvider.utils.formatProof(proof), - }, - }; - }; - - return { - ...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }), - }; + return { + ...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }), + }; }; -export { initialize, metadata }; \ No newline at end of file +export { initialize, metadata }; diff --git a/zokrates_js/patch.js b/zokrates_js/patch.js index b20652d0b..4e33e752c 100644 --- a/zokrates_js/patch.js +++ b/zokrates_js/patch.js @@ -71,5 +71,5 @@ export default init;`; body, }); - await fs.writeFile("wasm.js", source + init); + await fs.writeFile("wasm.js", source + init); })(); diff --git a/zokrates_js/tests/tests.js b/zokrates_js/tests/tests.js index efb4cbd70..2870cb80c 100644 --- a/zokrates_js/tests/tests.js +++ b/zokrates_js/tests/tests.js @@ -4,7 +4,7 @@ import fs from "fs"; import os from "os"; import * as snarkjs from "snarkjs"; import dree from "dree"; -import { initialize, metadata } from "../index.js"; +import { initialize, metadata } from "../index-node.js"; let zokratesProvider; let tmpFolder; From e66b3c8c5c715c0766ad37187fdc1ed090054cea Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 13:21:39 +0100 Subject: [PATCH 68/94] update book --- zokrates_book/src/toolbox/zokrates_js.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/zokrates_book/src/toolbox/zokrates_js.md b/zokrates_book/src/toolbox/zokrates_js.md index 953e662e9..6296db619 100644 --- a/zokrates_book/src/toolbox/zokrates_js.md +++ b/zokrates_book/src/toolbox/zokrates_js.md @@ -8,17 +8,14 @@ npm install zokrates-js ## Importing -##### Bundlers -**Note:** As this library uses a model where the wasm module itself is natively an ES module, you will need a bundler of some form. -Currently the only known bundler known to be fully compatible with `zokrates-js` is [Webpack](https://webpack.js.org/) (`experiments.syncWebAssembly` must be enabled). -The choice of this default was done to reflect the trends of the JS ecosystem. +##### ES modules ```js import { initialize } from 'zokrates-js'; ``` -##### Node +##### CommonJS ```js -const { initialize } = require('zokrates-js') +let { initialize } = await import('zokrates-js'); ``` ## Example @@ -201,3 +198,11 @@ Parameters: * `verificationKey` - Verification key from the setup keypair Returns: `string` + +##### utils.formatProof(proof) +Formats the proof into an array of field elements that are compatible as input to the generated solidity contract + +Parameters: +* `proof` - Generated proof + +Returns: `array` \ No newline at end of file From ca664cb1a0324798585aaf2c2daaf0b959c648cb Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 13:52:42 +0100 Subject: [PATCH 69/94] use buffer first, add changelog --- changelogs/unreleased/1264-dark64 | 1 + zokrates_js/patch.js | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 changelogs/unreleased/1264-dark64 diff --git a/changelogs/unreleased/1264-dark64 b/changelogs/unreleased/1264-dark64 new file mode 100644 index 000000000..c9d64e903 --- /dev/null +++ b/changelogs/unreleased/1264-dark64 @@ -0,0 +1 @@ +Optimize `zokrates-js` library size \ No newline at end of file diff --git a/zokrates_js/patch.js b/zokrates_js/patch.js index 4e33e752c..4f4c19aa7 100644 --- a/zokrates_js/patch.js +++ b/zokrates_js/patch.js @@ -18,17 +18,17 @@ import pako from "pako"; let bytes; - if (typeof atob === 'function') { + if (typeof Buffer === "function") { + bytes = Buffer.from(encoded, "base64"); + } else if (typeof atob === "function") { const binary = atob(encoded); bytes = new Uint8Array(binary.length); - + for (let i = 0; i < binary.length; i++) { bytes[i] = binary.charCodeAt(i); - } - } else if (typeof Buffer === 'function') { - bytes = Buffer.from(encoded, 'base64'); + } } else { - throw new Error('Unsupported platform'); + throw new Error("Unsupported platform"); } const imports = getImports(); From 86164bd1904f46cf67fab8b1f9c022daffc8a817 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 23 Jan 2023 19:53:18 +0100 Subject: [PATCH 70/94] update features on dependencies --- Cargo.lock | 2 ++ zokrates_ark/Cargo.toml | 13 +++++++++++-- zokrates_bellman/Cargo.toml | 2 +- zokrates_cli/Cargo.toml | 7 ++++--- zokrates_embed/Cargo.toml | 13 +++++++++++-- zokrates_field/Cargo.toml | 1 + zokrates_js/Cargo.toml | 3 ++- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bffcb3ac..bac9691db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3234,6 +3234,7 @@ dependencies = [ "zokrates_circom", "zokrates_common", "zokrates_core", + "zokrates_embed", "zokrates_field", "zokrates_fs_resolver", "zokrates_interpreter", @@ -3380,6 +3381,7 @@ dependencies = [ "zokrates_circom", "zokrates_common", "zokrates_core", + "zokrates_embed", "zokrates_field", "zokrates_interpreter", "zokrates_proof_systems", diff --git a/zokrates_ark/Cargo.toml b/zokrates_ark/Cargo.toml index bc162969e..6069009a0 100644 --- a/zokrates_ark/Cargo.toml +++ b/zokrates_ark/Cargo.toml @@ -4,8 +4,17 @@ version = "0.1.1" edition = "2021" [features] -default = ["multicore"] -multicore = ["ark-groth16/parallel", "ark-gm17/parallel", "ark-marlin/parallel"] +default = [] +multicore = [ + "ark-ff/parallel", + "ark-ec/parallel", + "ark-groth16/parallel", + "ark-gm17/parallel", + "ark-marlin/parallel", + "ark-poly/parallel", + "ark-poly-commit/parallel", + "ark-crypto-primitives/parallel", +] [dependencies] zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false } diff --git a/zokrates_bellman/Cargo.toml b/zokrates_bellman/Cargo.toml index 86af751f0..ca3dd8cea 100644 --- a/zokrates_bellman/Cargo.toml +++ b/zokrates_bellman/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [features] -default = ["multicore"] +default = [] wasm = ["bellman/nolog", "bellman/wasm"] multicore = ["bellman/multicore", "phase2/multicore"] diff --git a/zokrates_cli/Cargo.toml b/zokrates_cli/Cargo.toml index 0aa946334..c0073bdd3 100644 --- a/zokrates_cli/Cargo.toml +++ b/zokrates_cli/Cargo.toml @@ -17,12 +17,13 @@ cfg-if = "0.1" clap = "2.26.2" serde_cbor = "0.11.2" regex = "0.2" -zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false } +zokrates_field = { version = "0.5", path = "../zokrates_field", features = ["multicore"] } zokrates_abi = { version = "0.1", path = "../zokrates_abi" } zokrates_core = { version = "0.7", path = "../zokrates_core", default-features = false } zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false } zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter", default-features = false } zokrates_circom = { version = "0.1", path = "../zokrates_circom", default-features = false } +zokrates_embed = { version = "0.1", path = "../zokrates_embed", features = ["multicore"] } typed-arena = "1.4.1" zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"} zokrates_common = { version = "0.1", path = "../zokrates_common", default-features = false } @@ -39,8 +40,8 @@ sha2 = "0.10.0" # Backends zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", default-features = false } -zokrates_ark = { version = "0.1", path = "../zokrates_ark", default-features = false, optional = true } -zokrates_bellman = { version = "0.1", path = "../zokrates_bellman", default-features = false, optional = true } +zokrates_ark = { version = "0.1", path = "../zokrates_ark", features = ["multicore"], optional = true } +zokrates_bellman = { version = "0.1", path = "../zokrates_bellman", features = ["multicore"], optional = true } [dev-dependencies] glob = "0.2.11" diff --git a/zokrates_embed/Cargo.toml b/zokrates_embed/Cargo.toml index 0a97a2de5..9b1da6a79 100644 --- a/zokrates_embed/Cargo.toml +++ b/zokrates_embed/Cargo.toml @@ -8,8 +8,17 @@ edition = "2018" default = ["ark", "bellman"] ark = ["ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-relations", "ark-crypto-primitives", "ark-r1cs-std", "ark-std", "ark-ec", "ark-ff", "sapling-crypto_ce"] bellman = ["bellman_ce"] -wasm = ["bellman_ce/wasm", "sapling-crypto_ce/wasm"] -multicore = ["bellman_ce/multicore", "sapling-crypto_ce/multicore", "ark-gm17/parallel", "ark-r1cs-std/parallel"] +wasm = ["bellman_ce/nolog", "bellman_ce/wasm", "sapling-crypto_ce/wasm"] +multicore = [ + "bellman_ce/multicore", + "sapling-crypto_ce/multicore", + "ark-gm17/parallel", + "ark-crypto-primitives/parallel", + "ark-r1cs-std/parallel", + "ark-std/parallel", + "ark-ec/parallel", + "ark-ff/parallel" +] [dependencies] zokrates_field = { version = "0.5.0", path = "../zokrates_field", default-features = false } diff --git a/zokrates_field/Cargo.toml b/zokrates_field/Cargo.toml index 87c98f369..65825f003 100644 --- a/zokrates_field/Cargo.toml +++ b/zokrates_field/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [features] default = ["bellman"] bellman = ["bellman_ce"] +multicore = ["ark-ff/parallel", "ark-ec/parallel"] [dependencies] serde = "1.0" diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 778e7b000..345539118 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -14,14 +14,15 @@ serde_json = { version = "1.0", features = ["preserve_order"] } wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } typed-arena = "1.4.1" lazy_static = "1.4.0" +zokrates_field = { path = "../zokrates_field" } zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } zokrates_ark = { path = "../zokrates_ark", default-features = false } +zokrates_embed = { path = "../zokrates_embed", default-features = false, features = ["wasm"] } zokrates_bellman = { path = "../zokrates_bellman", default-features = false, features = ["wasm"] } zokrates_common = { path = "../zokrates_common", default-features = false, features = ["ark", "bellman"] } zokrates_proof_systems = { path = "../zokrates_proof_systems", default-features = false } zokrates_ast = { path = "../zokrates_ast", default-features = false, features = ["ark", "bellman"] } zokrates_interpreter = { path = "../zokrates_interpreter", default-features = false, features = ["ark", "bellman"] } -zokrates_field = { path = "../zokrates_field", default-features = false } zokrates_abi = { path = "../zokrates_abi", default-features = false, features = ["ark", "bellman"] } zokrates_circom = { path = "../zokrates_circom" } console_error_panic_hook = "0.1.6" From e70611628e7be1677d69459005673edd6f9210a3 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 24 Jan 2023 13:32:08 +0100 Subject: [PATCH 71/94] test --- zokrates_circom/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_circom/Cargo.toml b/zokrates_circom/Cargo.toml index d4ce79429..a2b8ca645 100644 --- a/zokrates_circom/Cargo.toml +++ b/zokrates_circom/Cargo.toml @@ -14,4 +14,4 @@ byteorder = "1.4.3" [dev-dependencies] pretty_assertions = "1.2.1" zkutil = "0.5.0" -bellman_ce = { version = "^0.3" } \ No newline at end of file +bellman_ce = { version = "^0.3", default-features = false } \ No newline at end of file From cfb30c4b14bb0bbe41579c303d59109bde4448b9 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 24 Jan 2023 14:34:44 +0100 Subject: [PATCH 72/94] use resolver in js crate --- zokrates_circom/Cargo.toml | 2 +- zokrates_js/Cargo.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/zokrates_circom/Cargo.toml b/zokrates_circom/Cargo.toml index a2b8ca645..d4ce79429 100644 --- a/zokrates_circom/Cargo.toml +++ b/zokrates_circom/Cargo.toml @@ -14,4 +14,4 @@ byteorder = "1.4.3" [dev-dependencies] pretty_assertions = "1.2.1" zkutil = "0.5.0" -bellman_ce = { version = "^0.3", default-features = false } \ No newline at end of file +bellman_ce = { version = "^0.3" } \ No newline at end of file diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 345539118..8f9f3b2c6 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -3,6 +3,7 @@ name = "zokrates_js" version = "1.1.4" authors = ["Darko Macesic"] edition = "2018" +resolver = "2" [lib] crate-type = ["cdylib"] From 01bf1235aa402fee142bcecb94e983ead7930997 Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 24 Jan 2023 14:58:59 +0100 Subject: [PATCH 73/94] enable wasm feature only on wasm32 target --- Cargo.toml | 2 +- zokrates_js/Cargo.toml | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c5b23352..585b7e715 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] - +resolver = "2" members = [ "zokrates_common", "zokrates_core", diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 8f9f3b2c6..e0a32bcfb 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -3,7 +3,6 @@ name = "zokrates_js" version = "1.1.4" authors = ["Darko Macesic"] edition = "2018" -resolver = "2" [lib] crate-type = ["cdylib"] @@ -18,8 +17,8 @@ lazy_static = "1.4.0" zokrates_field = { path = "../zokrates_field" } zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] } zokrates_ark = { path = "../zokrates_ark", default-features = false } -zokrates_embed = { path = "../zokrates_embed", default-features = false, features = ["wasm"] } -zokrates_bellman = { path = "../zokrates_bellman", default-features = false, features = ["wasm"] } +zokrates_embed = { path = "../zokrates_embed", default-features = false } +zokrates_bellman = { path = "../zokrates_bellman", default-features = false } zokrates_common = { path = "../zokrates_common", default-features = false, features = ["ark", "bellman"] } zokrates_proof_systems = { path = "../zokrates_proof_systems", default-features = false } zokrates_ast = { path = "../zokrates_ast", default-features = false, features = ["ark", "bellman"] } @@ -29,6 +28,10 @@ zokrates_circom = { path = "../zokrates_circom" } console_error_panic_hook = "0.1.6" indexmap = "~1.6.2" # see https://github.com/rustwasm/wasm-bindgen/issues/2770#issuecomment-1041102532 +[target.'cfg(target_arch = "wasm32")'.dependencies] +zokrates_embed = { path = "../zokrates_embed", features = ["wasm"] } +zokrates_bellman = { path = "../zokrates_bellman", features = ["wasm"] } + [build-dependencies] json = "0.12.4" walkdir = "2.3.2" From 19f54c8f1be47dd70e0312691a2c15451f7bee3d Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 24 Jan 2023 18:21:33 +0100 Subject: [PATCH 74/94] add umd version for web usage --- zokrates_book/src/toolbox/zokrates_js.md | 155 +- zokrates_js/.gitignore | 3 +- zokrates_js/package-lock.json | 9575 +++++++++++++++++++--- zokrates_js/package.json | 16 +- zokrates_js/tests/umd/index.html | 38 + zokrates_js/tests/umd/tests.js | 24 + 6 files changed, 8684 insertions(+), 1127 deletions(-) create mode 100644 zokrates_js/tests/umd/index.html create mode 100644 zokrates_js/tests/umd/tests.js diff --git a/zokrates_book/src/toolbox/zokrates_js.md b/zokrates_book/src/toolbox/zokrates_js.md index 6296db619..67ac6898f 100644 --- a/zokrates_book/src/toolbox/zokrates_js.md +++ b/zokrates_book/src/toolbox/zokrates_js.md @@ -9,109 +9,134 @@ npm install zokrates-js ## Importing ##### ES modules + ```js -import { initialize } from 'zokrates-js'; +import { initialize } from "zokrates-js"; ``` ##### CommonJS + ```js -let { initialize } = await import('zokrates-js'); +let { initialize } = await import("zokrates-js"); +``` + +##### CDN + +```html + + ``` ## Example + ```js initialize().then((zokratesProvider) => { - const source = "def main(private field a) -> field { return a * a; }"; + const source = "def main(private field a) -> field { return a * a; }"; - // compilation - const artifacts = zokratesProvider.compile(source); + // compilation + const artifacts = zokratesProvider.compile(source); - // computation - const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]); + // computation + const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]); - // run setup - const keypair = zokratesProvider.setup(artifacts.program); + // run setup + const keypair = zokratesProvider.setup(artifacts.program); - // generate proof - const proof = zokratesProvider.generateProof(artifacts.program, witness, keypair.pk); + // generate proof + const proof = zokratesProvider.generateProof( + artifacts.program, + witness, + keypair.pk + ); - // export solidity verifier - const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk); - - // or verify off-chain - const isVerified = zokratesProvider.verify(keypair.vk, proof); + // export solidity verifier + const verifier = zokratesProvider.exportSolidityVerifier(keypair.vk); + + // or verify off-chain + const isVerified = zokratesProvider.verify(keypair.vk, proof); }); ``` ## API ##### initialize() + Returns an initialized `ZoKratesProvider` as a promise. ```js -initialize().then((zokratesProvider) => { - // call api functions here +initialize().then((zokratesProvider) => { + // call api functions here }); ``` Returns: `Promise` ##### withOptions(options) + Returns a `ZoKratesProvider` configured with given options. ```js -initialize().then((defaultProvider) => { - let zokratesProvider = defaultProvider.withOptions({ - backend: "ark", - curve: "bls12_381", - scheme: "g16" - }); - // ... +initialize().then((defaultProvider) => { + let zokratesProvider = defaultProvider.withOptions({ + backend: "ark", + curve: "bls12_381", + scheme: "g16", + }); + // ... }); ``` Options: -* `backend` - Backend (options: `ark` | `bellman`, default: `ark`) -* `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`) -* `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`) + +- `backend` - Backend (options: `ark` | `bellman`, default: `ark`) +- `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`) +- `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`) Returns: `ZoKratesProvider` ##### compile(source[, options]) + Compiles source code into ZoKrates internal representation of arithmetic circuits. Parameters: -* `source` - Source code to compile -* `options` - Compilation options + +- `source` - Source code to compile +- `options` - Compilation options Returns: `CompilationArtifacts` **Examples:** Compilation: + ```js const artifacts = zokratesProvider.compile("def main() { return; }"); ``` Compilation with custom options: + ```js const source = "..."; const options = { - location: "main.zok", // location of the root module - resolveCallback: (currentLocation, importLocation) => { - console.log(currentLocation + ' is importing ' + importLocation); - return { - source: "def main() { return; }", - location: importLocation - }; - } + location: "main.zok", // location of the root module + resolveCallback: (currentLocation, importLocation) => { + console.log(currentLocation + " is importing " + importLocation); + return { + source: "def main() { return; }", + location: importLocation, + }; + }, }; const artifacts = zokratesProvider.compile(source, options); ``` -**Note:** The `resolveCallback` function is used to resolve dependencies. -This callback receives the current module location and the import location of the module which is being imported. -The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above. +**Note:** The `resolveCallback` function is used to resolve dependencies. +This callback receives the current module location and the import location of the module which is being imported. +The callback must synchronously return either an error, `null` or a valid `ResolverResult` object like shown in the example above. A simple file system resolver for a node environment can be implemented as follows: ```js @@ -126,19 +151,21 @@ const fileSystemResolver = (from, to) => { ``` ##### computeWitness(artifacts, args[, options]) + Computes a valid assignment of the variables, which include the results of the computation. Parameters: -* `artifacts` - Compilation artifacts -* `args` - Array of arguments (eg. `["1", "2", true]`) -* `options` - Computation options + +- `artifacts` - Compilation artifacts +- `args` - Array of arguments (eg. `["1", "2", true]`) +- `options` - Computation options Returns: `ComputationResult` **Example:** ```js -const code = 'def main(private field a) -> field { return a * a; }'; +const code = "def main(private field a) -> field { return a * a; }"; const artifacts = zokratesProvider.compile(code); const { witness, output } = zokratesProvider.computeWitness(artifacts, ["2"]); @@ -148,61 +175,75 @@ console.log(output); // Computation output: "4" ``` ##### setup(program) + Generates a trusted setup for the compiled program. Parameters: -* `program` - Compiled program + +- `program` - Compiled program Returns: `SetupKeypair` ##### universalSetup(size) + Performs the universal phase of a trusted setup. Only available for the `marlin` scheme. Parameters: -* `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`. + +- `size` - Size of the trusted setup passed as an exponent. For example, `8` for `2**8`. Returns: `Uint8Array` ##### setupWithSrs(srs, program) + Generates a trusted setup with universal public parameters for the compiled program. Only available for `marlin` scheme. Parameters: -* `srs` - Universal public parameters from the universal setup phase -* `program` - Compiled program + +- `srs` - Universal public parameters from the universal setup phase +- `program` - Compiled program Returns: `SetupKeypair` ##### generateProof(program, witness, provingKey) + Generates a proof for a computation of the compiled program. Parameters: -* `program` - Compiled program -* `witness` - Witness (valid assignment of the variables) from the computation result -* `provingKey` - Proving key from the setup keypair + +- `program` - Compiled program +- `witness` - Witness (valid assignment of the variables) from the computation result +- `provingKey` - Proving key from the setup keypair Returns: `Proof` ##### verify(verificationKey, proof) + Verifies the generated proof. Parameters: -* `verificationKey` - Verification key from the setup keypair -* `proof` - Generated proof + +- `verificationKey` - Verification key from the setup keypair +- `proof` - Generated proof Returns: `boolean` ##### exportSolidityVerifier(verificationKey) + Generates a Solidity contract which contains the generated verification key and a public function to verify proofs of computation of the compiled program. Parameters: -* `verificationKey` - Verification key from the setup keypair + +- `verificationKey` - Verification key from the setup keypair Returns: `string` ##### utils.formatProof(proof) + Formats the proof into an array of field elements that are compatible as input to the generated solidity contract Parameters: -* `proof` - Generated proof -Returns: `array` \ No newline at end of file +- `proof` - Generated proof + +Returns: `array` diff --git a/zokrates_js/.gitignore b/zokrates_js/.gitignore index 3817319e6..07ba096de 100644 --- a/zokrates_js/.gitignore +++ b/zokrates_js/.gitignore @@ -4,4 +4,5 @@ target pkg wasm-pack.log metadata.js -wasm.js \ No newline at end of file +wasm.js +umd.min.js \ No newline at end of file diff --git a/zokrates_js/package-lock.json b/zokrates_js/package-lock.json index 8cb663f83..00ecd023a 100644 --- a/zokrates_js/package-lock.json +++ b/zokrates_js/package-lock.json @@ -12,1652 +12,7520 @@ "pako": "^2.1.0" }, "devDependencies": { + "@babel/core": "^7.20.12", + "@babel/preset-env": "^7.20.2", "acorn": "^8.8.1", "astring": "^1.8.4", + "babelify": "^10.0.0", + "browserify": "^17.0.0", "dree": "^3.4.3", "mocha": "^9.2.0", + "puppeteer": "^19.6.0", "rimraf": "^3.0.2", "snarkjs": "^0.4.25", + "uglify-js": "^3.17.4", "wasm-pack": "^0.10.2" } }, - "node_modules/@iden3/bigarray": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", - "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==", - "dev": true - }, - "node_modules/@iden3/binfileutils": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", - "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, "dependencies": { - "fastfile": "0.0.20", - "ffjavascript": "^0.2.48" + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@babel/highlight": "^7.18.6" }, "engines": { - "node": ">=0.4.0" + "node": ">=6.9.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", "dev": true, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, - "node_modules/astring": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.4.tgz", - "integrity": "sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==", + "node_modules/@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dev": true, - "bin": { - "astring": "bin/astring" + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { - "follow-redirects": "^1.14.0" + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/b4a": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", - "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, "dependencies": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" + "@babel/types": "^7.18.6" }, "engines": { - "node": ">= 8.0.0" + "node": ">=6.9.0" } }, - "node_modules/big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dev": true, + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, "engines": { - "node": ">=0.6" + "node": ">=6.9.0" } }, - "node_modules/binary-install": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", - "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "dependencies": { - "axios": "^0.21.1", - "rimraf": "^3.0.2", - "tar": "^6.1.0" + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/blake2b-wasm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", - "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", + "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", "dev": true, "dependencies": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", - "dev": true - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.2.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/check-types": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", - "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==", - "dev": true + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, - "node_modules/circom_runtime": { - "version": "0.1.18", - "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.18.tgz", - "integrity": "sha512-j6k+Jg1DXCYFVgjDRbJDmkAJ9E17js8h1iR7F1UX0IUr5v8NXeOXkfRh9+/73JqSgXb3Eo166a4JHdA/CeoEeA==", + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "dev": true, "dependencies": { - "ffjavascript": "0.2.55" + "@babel/types": "^7.18.6" }, - "bin": { - "calcwit": "calcwit.js" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@babel/types": "^7.18.6" }, "engines": { - "node": ">=7.0.0" + "node": ">=6.9.0" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", + "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + }, "engines": { - "node": ">=0.3.1" + "node": ">=6.9.0" } }, - "node_modules/dree": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/dree/-/dree-3.4.3.tgz", - "integrity": "sha512-InS4gt3Mqw1/VH9zxKHb9kE4K20H58h91ByR2+6XM3oxalpEUqDhfusK13W1++lePcE+0W1S0A4d3syr405Siw==", + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { - "yargs": "^17.6.2" + "@babel/types": "^7.18.6" }, - "bin": { - "dree": "bundled/bin/index.js" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/dree/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/dree/node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dev": true, "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "@babel/types": "^7.18.6" }, "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/dree/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=6.9.0" } }, - "node_modules/ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dev": true, "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/@babel/helper-replace-supers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + }, "engines": { - "node": ">=6" + "node": ">=6.9.0" } }, - "node_modules/fastfile": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.20.tgz", - "integrity": "sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==", - "dev": true - }, - "node_modules/ffjavascript": { - "version": "0.2.55", - "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.55.tgz", - "integrity": "sha512-8X0FCIPOWiK6DTWh3pnE3O6D6nIQsirStAXpWMzRDnoDX7SEnDX4I28aVhwjL7L35XS1vy2AU7zc0UCGYxdLjw==", + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "big-integer": "^1.6.48", - "wasmbuilder": "^0.0.12", - "wasmcurves": "0.1.0", - "web-worker": "^1.2.0" + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "dev": true, "dependencies": { - "minimatch": "^5.0.1" + "@babel/types": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, - "bin": { - "flat": "cli.js" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/follow-redirects": { - "version": "1.14.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", - "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=6.9.0" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/@babel/helper-wrap-function": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "dev": true, "dependencies": { - "minipass": "^3.0.0" + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=6.9.0" } }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=6.9.0" } }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "node_modules/@babel/parser": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, "engines": { - "node": ">=4.x" + "node": ">=6.0.0" } }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "dev": true, - "bin": { - "he": "bin/he" + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" + }, "engines": { - "node": ">= 6.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/@babel/plugin-proposal-class-static-block": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", + "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" } }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "dev": true, "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "bin": { - "jake": "bin/cli.js" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/jake/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/jake/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/@babel/plugin-proposal-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", + "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", "dev": true, "dependencies": { - "p-locate": "^5.0.0" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dev": true, "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "dev": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=8" + "node": ">=4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/logplease": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", - "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", - "dev": true + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": "*" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/minipass/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "dev": true, "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/minizlib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/mocha": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", - "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.2.0", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "@babel/helper-plugin-utils": "^7.10.4" }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">= 12.0.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@babel/helper-plugin-utils": "^7.8.0" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { - "node": ">= 8.10.0" + "node": ">=6.9.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { - "node": ">=6.0" + "node": ">=6.9.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", + "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/@babel/plugin-transform-classes": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", + "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", + "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { - "node": "*" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { - "node": ">= 6" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dev": true, + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=0.12.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, "dependencies": { - "picomatch": "^2.2.1" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { - "node": ">=8.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "dev": true, "dependencies": { - "is-number": "^7.0.0" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" }, "engines": { - "node": ">=8.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", + "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "dev": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" }, "engines": { - "node": ">= 8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/mocha/node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "dev": true, + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" + }, "engines": { - "node": ">=10" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/nanoassert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", - "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", - "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "dev": true, "dependencies": { - "wrappy": "1" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dev": true, "dependencies": { - "yocto-queue": "^0.1.0" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dev": true, "dependencies": { - "p-limit": "^3.0.2" + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=8.6" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/r1csfile": { - "version": "0.0.40", - "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.40.tgz", - "integrity": "sha512-3tKaFLncf42ZTRpPMlgyiFBdk6kir4S4O3X+u4UQjgLYoDPHfizazNbK0Jzj++PVIXVUFAqugSbIo4W3UDuHcQ==", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "dev": true, "dependencies": { - "@iden3/bigarray": "0.0.2", - "@iden3/binfileutils": "0.0.11", - "fastfile": "0.0.20", - "ffjavascript": "0.2.55" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dev": true, "dependencies": { - "safe-buffer": "^5.1.0" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/@babel/plugin-transform-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dev": true, "dependencies": { - "randombytes": "^2.1.0" + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/snarkjs": { - "version": "0.4.25", - "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.4.25.tgz", - "integrity": "sha512-20manpB7xCd5gkfkioD6GaAR7tgJmN7xQQislJcPV3Xs2Vkf+1Dz6V+LKRwlc/rU/vT/EopUBm5apqvTOKidbQ==", + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, "dependencies": { - "@iden3/binfileutils": "0.0.11", - "bfj": "^7.0.2", - "blake2b-wasm": "^2.4.0", - "circom_runtime": "0.1.18", - "ejs": "^3.1.6", - "fastfile": "0.0.20", - "ffjavascript": "0.2.55", - "js-sha3": "^0.8.0", - "logplease": "^1.2.15", - "r1csfile": "0.0.40" + "@babel/helper-plugin-utils": "^7.18.9" }, - "bin": { - "snarkjs": "build/cli.cjs" + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" + "@babel/helper-plugin-utils": "^7.18.9" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/supports-color/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@babel/preset-env": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "node_modules/@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "dev": true, + "dependencies": { + "regenerator-runtime": "^0.13.11" }, "engines": { - "node": ">= 10" + "node": ">=6.9.0" } }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { - "node": ">=10" + "node": ">=6.9.0" } }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", - "dev": true - }, - "node_modules/wasm-pack": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.10.2.tgz", - "integrity": "sha512-Kuh8XAArQNVoikMUenjDs4+g6LpktgfXgqlp03G2dJKDBokA7Y8Cx6MDCnvREzNnmprk9IohHytwycVSemwe/w==", + "node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, - "hasInstallScript": true, "dependencies": { - "binary-install": "^0.1.0" + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" }, - "bin": { - "wasm-pack": "run.js" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/wasmbuilder": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.12.tgz", - "integrity": "sha512-dTMpBgrnLOXrN58i2zakn2ScynsBhq9LfyQIsPz4CyxRF9k1GAORniuqn3xmE9NnI1l7g3iiVCkoB2Cl0/oG8w==", + "node_modules/@iden3/bigarray": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", + "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==", + "dev": true + }, + "node_modules/@iden3/binfileutils": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", + "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", "dev": true, "dependencies": { - "big-integer": "^1.6.48" + "fastfile": "0.0.20", + "ffjavascript": "^0.2.48" } }, - "node_modules/wasmcurves": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.1.0.tgz", - "integrity": "sha512-kIlcgbVUAv2uQ6lGsepGz/m5V40+Z6rvTBkqCYn3Y2+OcXst+UaP4filJYLh/xDxjJl62FFjZZeAnpeli1Y5/Q==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==", - "dev": true + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true, + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "node_modules/y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", "dev": true, "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/yargs-parser": { - "version": "20.2.6", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", - "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" + "debug": "4" }, "engines": { - "node": ">=10" + "node": ">= 6.0.0" } }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "color-convert": "^2.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } - } - }, - "dependencies": { - "@iden3/bigarray": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", - "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==", + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "@iden3/binfileutils": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", - "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", "dev": true, - "requires": { - "fastfile": "0.0.20", - "ffjavascript": "^0.2.48" + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" } }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "acorn": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", - "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", "dev": true, - "requires": { - "color-convert": "^2.0.1" + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" } }, - "argparse": { + "node_modules/assert/node_modules/inherits": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", "dev": true }, - "astring": { + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/astring": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.4.tgz", "integrity": "sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==", - "dev": true + "dev": true, + "bin": { + "astring": "bin/astring" + } }, - "async": { + "node_modules/async": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", "dev": true }, - "axios": { + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { "version": "0.21.4", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/b4a": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", + "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", + "dev": true + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dev": true, + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babelify": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", + "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/binary-install": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", + "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", + "dev": true, + "dependencies": { + "axios": "^0.21.1", + "rimraf": "^3.0.2", + "tar": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "dev": true, + "dependencies": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "dependencies": { + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "JSONStream": "^1.0.3", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + }, + "bin": { + "browser-pack": "bin/cmd.js" + } + }, + "node_modules/browser-resolve": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", + "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", + "dev": true, + "dependencies": { + "resolve": "^1.17.0" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz", + "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==", + "dev": true, + "dependencies": { + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^2.0.0", + "browserify-zlib": "~0.2.0", + "buffer": "~5.2.1", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.1", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^3.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.2.1", + "JSONStream": "^1.0.3", + "labeled-stream-splicer": "^2.0.0", + "mkdirp-classic": "^0.5.2", + "module-deps": "^6.2.3", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "^1.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum-object": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^3.0.0", + "stream-http": "^3.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.12.0", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "browserify": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserify-zlib/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/cached-path-relative": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", + "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001447", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", + "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/chalk/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-types": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", + "integrity": "sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ==", + "dev": true + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/circom_runtime": { + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.18.tgz", + "integrity": "sha512-j6k+Jg1DXCYFVgjDRbJDmkAJ9E17js8h1iR7F1UX0IUr5v8NXeOXkfRh9+/73JqSgXb3Eo166a4JHdA/CeoEeA==", + "dev": true, + "dependencies": { + "ffjavascript": "0.2.55" + }, + "bin": { + "calcwit": "calcwit.js" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "dev": true, + "dependencies": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, + "node_modules/core-js-compat": { + "version": "3.27.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", + "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", + "dev": true, + "dependencies": { + "browserslist": "^4.21.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", + "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "dev": true + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deps-sort": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", + "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", + "dev": true, + "dependencies": { + "JSONStream": "^1.0.3", + "shasum-object": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + }, + "bin": { + "deps-sort": "bin/cmd.js" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1082910", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1082910.tgz", + "integrity": "sha512-RqoZ2GmqaNxyx+99L/RemY5CkwG9D0WEfOKxekwCRXOGrDCep62ngezEJUVMq6rISYQ+085fJnWDQqGHlxVNww==", + "dev": true + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/dree": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/dree/-/dree-3.4.3.tgz", + "integrity": "sha512-InS4gt3Mqw1/VH9zxKHb9kE4K20H58h91ByR2+6XM3oxalpEUqDhfusK13W1++lePcE+0W1S0A4d3syr405Siw==", + "dev": true, + "dependencies": { + "yargs": "^17.6.2" + }, + "bin": { + "dree": "bundled/bin/index.js" + } + }, + "node_modules/dree/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dree/node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dree/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/ejs": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, + "node_modules/fastfile": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.20.tgz", + "integrity": "sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==", + "dev": true + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/ffjavascript": { + "version": "0.2.55", + "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.55.tgz", + "integrity": "sha512-8X0FCIPOWiK6DTWh3pnE3O6D6nIQsirStAXpWMzRDnoDX7SEnDX4I28aVhwjL7L35XS1vy2AU7zc0UCGYxdLjw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.48", + "wasmbuilder": "^0.0.12", + "wasmcurves": "0.1.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.7", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz", + "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", + "dev": true, + "dependencies": { + "source-map": "~0.5.3" + } + }, + "node_modules/insert-module-globals": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", + "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", + "dev": true, + "dependencies": { + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "JSONStream": "^1.0.3", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + }, + "bin": { + "insert-module-globals": "bin/cmd.js" + } + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jake/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/labeled-stream-splicer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", + "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "stream-splicer": "^2.0.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/logplease": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/logplease/-/logplease-1.2.15.tgz", + "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/mocha": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", + "integrity": "sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.3", + "debug": "4.3.3", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.2.0", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.1.0", + "log-symbols": "4.1.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.2.0", + "serialize-javascript": "6.0.0", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "workerpool": "6.2.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mocha/node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mocha/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/mocha/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mocha/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/module-deps": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", + "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", + "dev": true, + "dependencies": { + "browser-resolve": "^2.0.0", + "cached-path-relative": "^1.0.2", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.2.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "JSONStream": "^1.0.3", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + }, + "bin": { + "module-deps": "bin/cmd.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoassert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", + "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", + "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pako": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", + "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", + "dev": true, + "dependencies": { + "path-platform": "~0.11.15" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/puppeteer": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.6.0.tgz", + "integrity": "sha512-KpRjn/bosTWe8xOQ/F5J1UmQ4inR77ADddn8G6MqMPp/y9Tl+7EycXgrjO0/3i/OQfHi5bsvkTKXRkm0ieo/ew==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "cosmiconfig": "8.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "puppeteer-core": "19.6.0" + }, + "engines": { + "node": ">=14.1.0" + } + }, + "node_modules/puppeteer-core": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.6.0.tgz", + "integrity": "sha512-GvqWdHr9eY/MFR5pXf9o0apnrTmG0hhS7/TtCPfeAvCbaUS1bsLMZWxNGvI/QbviRu4xxi6HrR7VW4x/4esq1Q==", + "dev": true, + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1082910", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.11.0" + }, + "engines": { + "node": ">=14.1.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/r1csfile": { + "version": "0.0.40", + "resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.40.tgz", + "integrity": "sha512-3tKaFLncf42ZTRpPMlgyiFBdk6kir4S4O3X+u4UQjgLYoDPHfizazNbK0Jzj++PVIXVUFAqugSbIo4W3UDuHcQ==", + "dev": true, + "dependencies": { + "@iden3/bigarray": "0.0.2", + "@iden3/binfileutils": "0.0.11", + "fastfile": "0.0.20", + "ffjavascript": "0.2.55" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "node_modules/regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexpu-core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "dev": true, + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", + "dev": true + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shasum-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", + "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", + "dev": true, + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/snarkjs": { + "version": "0.4.25", + "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.4.25.tgz", + "integrity": "sha512-20manpB7xCd5gkfkioD6GaAR7tgJmN7xQQislJcPV3Xs2Vkf+1Dz6V+LKRwlc/rU/vT/EopUBm5apqvTOKidbQ==", + "dev": true, + "dependencies": { + "@iden3/binfileutils": "0.0.11", + "bfj": "^7.0.2", + "blake2b-wasm": "^2.4.0", + "circom_runtime": "0.1.18", + "ejs": "^3.1.6", + "fastfile": "0.0.20", + "ffjavascript": "0.2.55", + "js-sha3": "^0.8.0", + "logplease": "^1.2.15", + "r1csfile": "0.0.40" + }, + "bin": { + "snarkjs": "build/cli.cjs" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "dependencies": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", + "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", + "dev": true, + "dependencies": { + "minimist": "^1.1.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-color/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "dependencies": { + "acorn-node": "^1.2.0" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", + "dev": true, + "dependencies": { + "process": "~0.11.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true, + "bin": { + "umd": "bin/cli.js" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + }, + "bin": { + "undeclared-identifiers": "bin.js" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/wasm-pack": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.10.2.tgz", + "integrity": "sha512-Kuh8XAArQNVoikMUenjDs4+g6LpktgfXgqlp03G2dJKDBokA7Y8Cx6MDCnvREzNnmprk9IohHytwycVSemwe/w==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "binary-install": "^0.1.0" + }, + "bin": { + "wasm-pack": "run.js" + } + }, + "node_modules/wasmbuilder": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.12.tgz", + "integrity": "sha512-dTMpBgrnLOXrN58i2zakn2ScynsBhq9LfyQIsPz4CyxRF9k1GAORniuqn3xmE9NnI1l7g3iiVCkoB2Cl0/oG8w==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.48" + } + }, + "node_modules/wasmcurves": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.1.0.tgz", + "integrity": "sha512-kIlcgbVUAv2uQ6lGsepGz/m5V40+Z6rvTBkqCYn3Y2+OcXst+UaP4filJYLh/xDxjJl62FFjZZeAnpeli1Y5/Q==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.42", + "blakejs": "^1.1.0" + } + }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==", + "dev": true + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workerpool": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", + "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.6", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.6.tgz", + "integrity": "sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "dev": true + }, + "@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz", + "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/helper-split-export-declaration": "^7.18.6" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.2.1" + } + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz", + "integrity": "sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + } + }, + "@babel/helper-replace-supers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "dev": true, + "requires": { + "@babel/types": "^7.20.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + } + }, + "@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "dev": true + }, + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" + } + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-class-static-block": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz", + "integrity": "sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz", + "integrity": "sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-import-assertions": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz", + "integrity": "sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz", + "integrity": "sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-split-export-declaration": "^7.18.6", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", + "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dev": true, + "requires": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", + "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.9" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/preset-env": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.20.0", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", + "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@iden3/bigarray": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz", + "integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==", + "dev": true + }, + "@iden3/binfileutils": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/@iden3/binfileutils/-/binfileutils-0.0.11.tgz", + "integrity": "sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA==", + "dev": true, + "requires": { + "fastfile": "0.0.20", + "ffjavascript": "^0.2.48" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true, + "optional": true + }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "dev": true + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "astring": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.4.tgz", + "integrity": "sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==", + "dev": true + }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "requires": { + "follow-redirects": "^1.14.0" + } + }, + "b4a": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", + "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", + "dev": true + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + } + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dev": true, + "requires": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + } + }, + "babelify": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-10.0.0.tgz", + "integrity": "sha512-X40FaxyH7t3X+JFAKvb1H9wooWKLRCi8pg3m8poqtdZaIng+bjzp9RvKQCvRjF9isHiPkXspbbXT/zwXLtwgwg==", + "dev": true, + "requires": {} + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bfj": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", + "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^11.1.1", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big-integer": { + "version": "1.6.51", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", + "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", + "dev": true + }, + "binary-install": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", + "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", + "dev": true, + "requires": { + "axios": "^0.21.1", + "rimraf": "^3.0.2", + "tar": "^6.1.0" + } + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "blake2b-wasm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", + "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "dev": true, + "requires": { + "b4a": "^1.0.1", + "nanoassert": "^2.0.0" + } + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "JSONStream": "^1.0.3", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", + "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", + "dev": true, + "requires": { + "resolve": "^1.17.0" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-17.0.0.tgz", + "integrity": "sha512-SaHqzhku9v/j6XsQMRxPyBrSP3gnwmE27gLJYZgMT2GeK3J0+0toN+MnuNYDfHwVGQfLiMZ7KSNSIXHemy905w==", + "dev": true, + "requires": { + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^2.0.0", + "browserify-zlib": "~0.2.0", + "buffer": "~5.2.1", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.1", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^3.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.2.1", + "JSONStream": "^1.0.3", + "labeled-stream-splicer": "^2.0.0", + "mkdirp-classic": "^0.5.2", + "module-deps": "^6.2.3", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "^1.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum-object": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^3.0.0", + "stream-http": "^3.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.12.0", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, "requires": { - "follow-redirects": "^1.14.0" + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } } }, - "b4a": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.5.3.tgz", - "integrity": "sha512-1aCQIzQJK7G0z1Una75tWMlwVAR8o+QHoAlnWc5XAxRVBESY9WsitfBgM5nPyDBP5HrhPU1Np4Pq2Y7CJQ+tVw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" + "pako": "~1.0.5" + }, + "dependencies": { + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + } } }, - "big-integer": { - "version": "1.6.51", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", - "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", - "dev": true - }, - "binary-install": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-0.1.1.tgz", - "integrity": "sha512-DqED0D/6LrS+BHDkKn34vhRqOGjy5gTMgvYZsGK2TpNbdPuz4h+MRlNgGv5QBRd7pWq/jylM4eKNCizgAq3kNQ==", + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "requires": { - "axios": "^0.21.1", - "rimraf": "^3.0.2", - "tar": "^6.1.0" + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" } }, - "blake2b-wasm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz", - "integrity": "sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==", + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, "requires": { - "b4a": "^1.0.1", - "nanoassert": "^2.0.0" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, - "blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "cached-path-relative": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", + "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", + "dev": true + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001447", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", + "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "check-types": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.1.2.tgz", @@ -1670,6 +7538,16 @@ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "circom_runtime": { "version": "0.1.18", "resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.18.tgz", @@ -1705,18 +7583,245 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, + "core-js-compat": { + "version": "3.27.2", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.27.2.tgz", + "integrity": "sha512-welaYuF7ZtbYKGrIy7y3eb40d37rG1FvzEOfe7hSLd2iD6duMDqUhRfSvCGyC46HhR6Y8JXXdZ2lnRUMkPBpvg==", + "dev": true, + "requires": { + "browserslist": "^4.21.4" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", + "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "dev": true, + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "requires": { + "node-fetch": "2.6.7" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "dev": true + }, + "deps-sort": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", + "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum-object": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "requires": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + } + }, + "devtools-protocol": { + "version": "0.0.1082910", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1082910.tgz", + "integrity": "sha512-RqoZ2GmqaNxyx+99L/RemY5CkwG9D0WEfOKxekwCRXOGrDCep62ngezEJUVMq6rISYQ+085fJnWDQqGHlxVNww==", + "dev": true + }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, "dree": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/dree/-/dree-3.4.3.tgz", @@ -1760,6 +7865,15 @@ } } }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, "ejs": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", @@ -1769,24 +7883,126 @@ "jake": "^10.8.5" } }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "fastfile": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.20.tgz", "integrity": "sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA==", "dev": true }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "ffjavascript": { "version": "0.2.55", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.55.tgz", @@ -1840,6 +8056,21 @@ "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==", "dev": true }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", @@ -1855,12 +8086,50 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -1875,24 +8144,158 @@ "path-is-absolute": "^1.0.0" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", "dev": true }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", + "dev": true + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1909,6 +8312,70 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", + "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", + "dev": true, + "requires": { + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "JSONStream": "^1.0.3", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + } + }, + "is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1921,6 +8388,15 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", @@ -1936,12 +8412,31 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1993,6 +8488,12 @@ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", "dev": true }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2002,6 +8503,56 @@ "argparse": "^2.0.1" } }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "labeled-stream-splicer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", + "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "stream-splicer": "^2.0.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2011,6 +8562,18 @@ "p-locate": "^5.0.0" } }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "dev": true + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -2054,6 +8617,56 @@ "integrity": "sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA==", "dev": true }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2063,6 +8676,12 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, "minipass": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", @@ -2098,6 +8717,12 @@ } } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "mocha": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.0.tgz", @@ -2323,6 +8948,35 @@ } } }, + "module-deps": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", + "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", + "dev": true, + "requires": { + "browser-resolve": "^2.0.0", + "cached-path-relative": "^1.0.2", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.2.0", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "JSONStream": "^1.0.3", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "nanoassert": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", @@ -2335,6 +8989,27 @@ "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2344,6 +9019,12 @@ "wrappy": "1" } }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -2367,16 +9048,213 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "puppeteer": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.6.0.tgz", + "integrity": "sha512-KpRjn/bosTWe8xOQ/F5J1UmQ4inR77ADddn8G6MqMPp/y9Tl+7EycXgrjO0/3i/OQfHi5bsvkTKXRkm0ieo/ew==", + "dev": true, + "requires": { + "cosmiconfig": "8.0.0", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "puppeteer-core": "19.6.0" + } + }, + "puppeteer-core": { + "version": "19.6.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.6.0.tgz", + "integrity": "sha512-GvqWdHr9eY/MFR5pXf9o0apnrTmG0hhS7/TtCPfeAvCbaUS1bsLMZWxNGvI/QbviRu4xxi6HrR7VW4x/4esq1Q==", + "dev": true, + "requires": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1082910", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.11.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "dev": true }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", "dev": true }, "r1csfile": { @@ -2400,12 +9278,141 @@ "safe-buffer": "^5.1.0" } }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "read-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.2" + } + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4" + } + }, + "regexpu-core": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "dev": true, + "requires": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + } + }, + "regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", + "dev": true + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "dev": true + } + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2415,12 +9422,34 @@ "glob": "^7.1.3" } }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -2430,6 +9459,37 @@ "randombytes": "^2.1.0" } }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum-object": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.0.tgz", + "integrity": "sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==", + "dev": true, + "requires": { + "fast-safe-stringify": "^2.0.7" + } + }, + "shell-quote": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "dev": true + }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "dev": true + }, "snarkjs": { "version": "0.4.25", "resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.4.25.tgz", @@ -2448,6 +9508,97 @@ "r1csfile": "0.0.40" } }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", + "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2468,6 +9619,15 @@ "ansi-regex": "^5.0.1" } }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", + "dev": true, + "requires": { + "minimist": "^1.1.0" + } + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -2485,6 +9645,21 @@ } } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, "tar": { "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", @@ -2513,12 +9688,223 @@ } } }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + }, + "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + } + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", "dev": true }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + } + } + }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "wasm-pack": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.10.2.tgz", @@ -2553,6 +9939,36 @@ "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==", "dev": true }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", @@ -2576,12 +9992,31 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, "y18n": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", "dev": true }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -2629,6 +10064,16 @@ } } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/zokrates_js/package.json b/zokrates_js/package.json index 934268a41..0841556df 100644 --- a/zokrates_js/package.json +++ b/zokrates_js/package.json @@ -19,7 +19,8 @@ "index-node.js", "index.d.ts", "wasm.js", - "metadata.js" + "metadata.js", + "umd.min.js" ], "types": "index.d.ts", "type": "module", @@ -30,19 +31,26 @@ "scripts": { "wasm-pack": "wasm-pack build --out-name index --target web", "prebuild": "npm install", - "build": "npm run wasm-pack -- --release && node patch.js", - "build:dev": "npm run wasm-pack -- --dev && node patch.js", + "build": "npm run wasm-pack -- --release && node patch.js && npm run bundle", + "build:dev": "npm run wasm-pack -- --dev && node patch.js && npm run bundle", "pretest": "npm run build:dev", "test": "npm run run-tests", - "run-tests": "mocha --timeout 100000 --recursive tests" + "run-tests": "mocha --timeout 100000 --recursive tests", + "bundle": "browserify ./index.js --standalone zokrates -t [ babelify --presets [ @babel/preset-env ] ] | uglifyjs --compress --mangle > umd.min.js" }, "devDependencies": { + "@babel/core": "^7.20.12", + "@babel/preset-env": "^7.20.2", "acorn": "^8.8.1", "astring": "^1.8.4", + "babelify": "^10.0.0", + "browserify": "^17.0.0", "dree": "^3.4.3", "mocha": "^9.2.0", + "puppeteer": "^19.6.0", "rimraf": "^3.0.2", "snarkjs": "^0.4.25", + "uglify-js": "^3.17.4", "wasm-pack": "^0.10.2" }, "dependencies": { diff --git a/zokrates_js/tests/umd/index.html b/zokrates_js/tests/umd/index.html new file mode 100644 index 000000000..cfb8fe740 --- /dev/null +++ b/zokrates_js/tests/umd/index.html @@ -0,0 +1,38 @@ + + + + + + + Test Document + + + + + + diff --git a/zokrates_js/tests/umd/tests.js b/zokrates_js/tests/umd/tests.js new file mode 100644 index 000000000..beb5e3609 --- /dev/null +++ b/zokrates_js/tests/umd/tests.js @@ -0,0 +1,24 @@ +import puppeteer from "puppeteer"; +import assert from "assert"; +import path from "path"; + +describe("umd web tests", () => { + it("verify", async () => { + const browser = await puppeteer.launch({ headless: true }); + const page = await browser.newPage(); + + let response = await page.goto( + path.dirname(import.meta.url) + "/index.html" + ); + assert(response.ok()); + + let element = await page.waitForSelector("#result", { + timeout: 5000, + visible: true, + }); + let value = await element.evaluate((el) => el.textContent, element); + assert.equal(value, "true"); + + await browser.close(); + }); +}); From b88187606d05df3292bd34cc1f798511dcc0d29e Mon Sep 17 00:00:00 2001 From: dark64 Date: Tue, 24 Jan 2023 18:26:16 +0100 Subject: [PATCH 75/94] update book --- zokrates_book/src/toolbox/zokrates_js.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zokrates_book/src/toolbox/zokrates_js.md b/zokrates_book/src/toolbox/zokrates_js.md index 67ac6898f..235a6ed46 100644 --- a/zokrates_book/src/toolbox/zokrates_js.md +++ b/zokrates_book/src/toolbox/zokrates_js.md @@ -8,22 +8,22 @@ npm install zokrates-js ## Importing -##### ES modules +#### ES modules ```js import { initialize } from "zokrates-js"; ``` -##### CommonJS +#### CommonJS ```js let { initialize } = await import("zokrates-js"); ``` -##### CDN +#### CDN ```html - +