Merge branch 'develop' into bigint-poc
This commit is contained in:
commit
ce7708d7c6
33 changed files with 398 additions and 164 deletions
172
Cargo.lock
generated
172
Cargo.lock
generated
|
@ -487,9 +487,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bellperson"
|
||||
version = "0.24.1"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1a8623f815c0b1fd89efd9b5f4afbb937f91f51c1ebe3f6dda399c69fa938f3"
|
||||
checksum = "93eaee4b4753554139ae52ecf0e8b8c128cbc561b32e1bfaa32f70cba8518c1f"
|
||||
dependencies = [
|
||||
"bincode 1.3.3",
|
||||
"blake2s_simd 1.0.1",
|
||||
|
@ -499,11 +499,11 @@ dependencies = [
|
|||
"digest 0.10.6",
|
||||
"ec-gpu",
|
||||
"ec-gpu-gen",
|
||||
"ff",
|
||||
"group",
|
||||
"ff 0.13.0",
|
||||
"group 0.13.0",
|
||||
"log",
|
||||
"memmap2",
|
||||
"pairing",
|
||||
"pairing 0.23.0",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"rayon",
|
||||
|
@ -695,15 +695,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "blstrs"
|
||||
version = "0.6.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ecb6f3a9429706971633edf4b84f922aba9d2e3a7d71bfb450337e64ccb7df0"
|
||||
checksum = "33149fccb7f93271f0192614b884430cf274e880506bbd171cbc8918dcc95b14"
|
||||
dependencies = [
|
||||
"blst",
|
||||
"byte-slice-cast",
|
||||
"ff",
|
||||
"group",
|
||||
"pairing",
|
||||
"ff 0.13.0",
|
||||
"group 0.13.0",
|
||||
"pairing 0.23.0",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"subtle 2.5.0",
|
||||
|
@ -1137,16 +1137,16 @@ checksum = "bd63582de2b59ea1aa48d7c1941b5d87618d95484397521b3acdfa0e1e9f5e45"
|
|||
|
||||
[[package]]
|
||||
name = "ec-gpu-gen"
|
||||
version = "0.5.2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd09bf9d5313ad60379f70250590bccc10f7a04e2773062ac13255a37022584e"
|
||||
checksum = "892df2aa20abec5b816e15d5d6383892ca142077708efa3067dd3ac44b75c664"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"crossbeam-channel 0.5.8",
|
||||
"ec-gpu",
|
||||
"execute",
|
||||
"ff",
|
||||
"group",
|
||||
"ff 0.13.0",
|
||||
"group 0.13.0",
|
||||
"hex 0.4.3",
|
||||
"log",
|
||||
"num_cpus",
|
||||
|
@ -1350,6 +1350,16 @@ name = "ff"
|
|||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"byteorder",
|
||||
|
@ -1372,9 +1382,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ff_derive"
|
||||
version = "0.12.1"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17db6fa0748f1f66e9dbafba1881009b50614948c0e900f59083afff2f8d784b"
|
||||
checksum = "e9f54704be45ed286151c5e11531316eaef5b8f5af7d597b806fdb8af108d84a"
|
||||
dependencies = [
|
||||
"addchain",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -1400,23 +1410,6 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fil_pasta_curves"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3303ea3c462ab949ab95b49f6e6d255d8d9396ebd4f1626ccb34c7037615aa8f"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"ff",
|
||||
"group",
|
||||
"hex 0.4.3",
|
||||
"lazy_static",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixed-hash"
|
||||
version = "0.7.0"
|
||||
|
@ -1445,7 +1438,7 @@ version = "0.10.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||
dependencies = [
|
||||
"spin",
|
||||
"spin 0.9.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1610,7 +1603,18 @@ version = "0.12.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
|
||||
dependencies = [
|
||||
"ff",
|
||||
"ff 0.12.1",
|
||||
"rand_core 0.6.4",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||
dependencies = [
|
||||
"ff 0.13.0",
|
||||
"rand 0.8.5",
|
||||
"rand_core 0.6.4",
|
||||
"rand_xorshift",
|
||||
|
@ -1841,6 +1845,9 @@ name = "lazy_static"
|
|||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
dependencies = [
|
||||
"spin 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
|
@ -1873,19 +1880,6 @@ dependencies = [
|
|||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lurk-pasta-msm"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12992280292a2a4ff84591308c426029245d49094c75df079b286f1bb8496e6c"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"fil_pasta_curves",
|
||||
"semolina",
|
||||
"sppark",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
|
@ -1936,20 +1930,19 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "neptune"
|
||||
version = "8.1.1"
|
||||
version = "9.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d47b29bc49c7d957eb446e298f96cd7088829e2d7a549ab04b36bc82434e27b"
|
||||
checksum = "4227e5557caad6d2a910b7770f2479f0c9aeb8ddc1dc537623cb6ffec7f01d31"
|
||||
dependencies = [
|
||||
"bellperson",
|
||||
"blake2s_simd 0.5.11",
|
||||
"blstrs",
|
||||
"byteorder",
|
||||
"ff",
|
||||
"fil_pasta_curves",
|
||||
"ff 0.13.0",
|
||||
"generic-array 0.14.7",
|
||||
"itertools 0.8.2",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"pasta_curves",
|
||||
"serde",
|
||||
"trait-set",
|
||||
]
|
||||
|
@ -1962,25 +1955,25 @@ checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
|||
|
||||
[[package]]
|
||||
name = "nova-snark"
|
||||
version = "0.20.3"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09c8cf02c93500dee9244cd73547f20d133ca6d3fbbe9eae0205e5b2db05f36"
|
||||
checksum = "d6247c61ab29e5da01c8f80403c25c40956045f0343d79793a2675bf7775dd80"
|
||||
dependencies = [
|
||||
"bellperson",
|
||||
"bincode 1.3.3",
|
||||
"bitvec",
|
||||
"byteorder",
|
||||
"digest 0.8.1",
|
||||
"ff",
|
||||
"fil_pasta_curves",
|
||||
"ff 0.13.0",
|
||||
"flate2",
|
||||
"generic-array 0.14.7",
|
||||
"itertools 0.9.0",
|
||||
"lurk-pasta-msm",
|
||||
"neptune",
|
||||
"num-bigint 0.4.3",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
"pasta-msm",
|
||||
"pasta_curves",
|
||||
"rand_chacha",
|
||||
"rand_core 0.6.4",
|
||||
"rayon",
|
||||
|
@ -2128,7 +2121,16 @@ version = "0.22.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b"
|
||||
dependencies = [
|
||||
"group",
|
||||
"group 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pairing"
|
||||
version = "0.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f"
|
||||
dependencies = [
|
||||
"group 0.13.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2168,6 +2170,36 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pasta-msm"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e85d75eba3e7e9ee3bd11342b669185e194dadda3557934bc1000d9b87159d3"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pasta_curves",
|
||||
"semolina",
|
||||
"sppark",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pasta_curves"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095"
|
||||
dependencies = [
|
||||
"blake2b_simd",
|
||||
"ff 0.13.0",
|
||||
"group 0.13.0",
|
||||
"hex 0.4.3",
|
||||
"lazy_static",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
"subtle 2.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.12"
|
||||
|
@ -2670,9 +2702,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "semolina"
|
||||
version = "0.1.2"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e90759f733a01b95d6ba70180b954d1d96e3e7e11f86c3fb0da0231300972e05"
|
||||
checksum = "2b0111fd4fa831becb0606b9a2285ef3bee3c6a70d690209b8ae9514e9befe23"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"glob 0.3.1",
|
||||
|
@ -2849,6 +2881,12 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
|
@ -3669,12 +3707,12 @@ name = "zokrates_bellperson"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bellperson",
|
||||
"ff",
|
||||
"fil_pasta_curves",
|
||||
"ff 0.13.0",
|
||||
"getrandom",
|
||||
"hex 0.4.3",
|
||||
"nova-snark",
|
||||
"pairing",
|
||||
"pairing 0.22.0",
|
||||
"pasta_curves",
|
||||
"rand 0.4.6",
|
||||
"serde",
|
||||
"typed-arena",
|
||||
|
@ -3822,14 +3860,14 @@ dependencies = [
|
|||
"bellman_ce",
|
||||
"bellperson",
|
||||
"bincode 0.8.0",
|
||||
"ff",
|
||||
"fil_pasta_curves",
|
||||
"ff 0.13.0",
|
||||
"lazy_static",
|
||||
"nova-snark",
|
||||
"num-bigint 0.2.6",
|
||||
"num-integer",
|
||||
"num-traits 0.2.15",
|
||||
"pairing",
|
||||
"pairing 0.22.0",
|
||||
"pasta_curves",
|
||||
"rand 0.4.6",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
|
|
1
changelogs/unreleased/1313-schaeff
Normal file
1
changelogs/unreleased/1313-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Propagate embed call
|
1
changelogs/unreleased/1315-schaeff
Normal file
1
changelogs/unreleased/1315-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Short-circuit on compile-time constant branch conditions
|
1
changelogs/unreleased/1317-dark64
Normal file
1
changelogs/unreleased/1317-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Fix invalid constant in mimc7
|
1
changelogs/unreleased/1318-dark64
Normal file
1
changelogs/unreleased/1318-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Allow composite type in assembly assignment statement
|
1
changelogs/unreleased/1326-dark64
Normal file
1
changelogs/unreleased/1326-dark64
Normal file
|
@ -0,0 +1 @@
|
|||
Detect division by zero on compile-time
|
|
@ -33,6 +33,7 @@ pub enum Error {
|
|||
InvalidValue(String),
|
||||
OutOfBounds(u128, u128),
|
||||
VariableLength(String),
|
||||
DivisionByZero,
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
|
@ -47,6 +48,9 @@ impl fmt::Display for Error {
|
|||
index, size
|
||||
),
|
||||
Error::VariableLength(message) => write!(f, "{}", message),
|
||||
Error::DivisionByZero => {
|
||||
write!(f, "Division by zero detected during static analysis",)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +59,7 @@ impl fmt::Display for Error {
|
|||
pub struct Propagator<'ast, T> {
|
||||
// constants keeps track of constant expressions
|
||||
// we currently do not support partially constant expressions: `field [x, 1][1]` is not considered constant, `field [0, 1][1]` is
|
||||
constants: Constants<'ast, T>,
|
||||
pub constants: Constants<'ast, T>,
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Propagator<'ast, T> {
|
||||
|
@ -181,26 +185,22 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for Propagator<'ast, T> {
|
|||
_: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> Result<ConditionalOrExpression<'ast, T, E>, Self::Error> {
|
||||
Ok(
|
||||
match (
|
||||
self.fold_boolean_expression(*e.condition)?,
|
||||
e.consequence.fold(self)?,
|
||||
e.alternative.fold(self)?,
|
||||
) {
|
||||
(BooleanExpression::Value(v), consequence, _) if v.value => {
|
||||
Ok(match self.fold_boolean_expression(*e.condition)? {
|
||||
BooleanExpression::Value(v) if v.value => {
|
||||
ConditionalOrExpression::Expression(e.consequence.fold(self)?.into_inner())
|
||||
}
|
||||
BooleanExpression::Value(v) if !v.value => {
|
||||
ConditionalOrExpression::Expression(e.alternative.fold(self)?.into_inner())
|
||||
}
|
||||
condition => match (e.consequence.fold(self)?, e.alternative.fold(self)?) {
|
||||
(consequence, alternative) if consequence == alternative => {
|
||||
ConditionalOrExpression::Expression(consequence.into_inner())
|
||||
}
|
||||
(BooleanExpression::Value(v), _, alternative) if !v.value => {
|
||||
ConditionalOrExpression::Expression(alternative.into_inner())
|
||||
}
|
||||
(_, consequence, alternative) if consequence == alternative => {
|
||||
ConditionalOrExpression::Expression(consequence.into_inner())
|
||||
}
|
||||
(condition, consequence, alternative) => ConditionalOrExpression::Conditional(
|
||||
(consequence, alternative) => ConditionalOrExpression::Conditional(
|
||||
ConditionalExpression::new(condition, consequence, alternative, e.kind),
|
||||
),
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_assembly_assignment(
|
||||
|
@ -944,12 +944,16 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for Propagator<'ast, T> {
|
|||
let left = self.fold_field_expression(*e.left)?;
|
||||
let right = self.fold_field_expression(*e.right)?;
|
||||
|
||||
Ok(match (left, right) {
|
||||
(FieldElementExpression::Value(n1), FieldElementExpression::Value(n2)) => {
|
||||
FieldElementExpression::Value(ValueExpression::new(n1.value / n2.value))
|
||||
match (left, right) {
|
||||
(_, FieldElementExpression::Value(n)) if n.value == T::from(0) => {
|
||||
Err(Error::DivisionByZero)
|
||||
}
|
||||
(e1, e2) => e1 / e2,
|
||||
})
|
||||
(e, FieldElementExpression::Value(n)) if n.value == T::from(1) => Ok(e),
|
||||
(FieldElementExpression::Value(n1), FieldElementExpression::Value(n2)) => Ok(
|
||||
FieldElementExpression::Value(ValueExpression::new(n1.value / n2.value)),
|
||||
),
|
||||
(e1, e2) => Ok(e1 / e2),
|
||||
}
|
||||
}
|
||||
FieldElementExpression::IDiv(e) => {
|
||||
let left = self.fold_field_expression(*e.left)?;
|
||||
|
@ -1620,14 +1624,30 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn div() {
|
||||
let e = FieldElementExpression::div(
|
||||
FieldElementExpression::value(Bn128Field::from(6)),
|
||||
FieldElementExpression::value(Bn128Field::from(2)),
|
||||
let mut propagator = Propagator::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::div(
|
||||
FieldElementExpression::value(Bn128Field::from(6)),
|
||||
FieldElementExpression::value(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(FieldElementExpression::value(Bn128Field::from(3)))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Propagator::default().fold_field_expression(e),
|
||||
Ok(FieldElementExpression::value(Bn128Field::from(3)))
|
||||
propagator.fold_field_expression(FieldElementExpression::div(
|
||||
FieldElementExpression::identifier("a".into()),
|
||||
FieldElementExpression::value(Bn128Field::from(1)),
|
||||
)),
|
||||
Ok(FieldElementExpression::identifier("a".into()))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::div(
|
||||
FieldElementExpression::value(Bn128Field::from(6)),
|
||||
FieldElementExpression::value(Bn128Field::from(0)),
|
||||
)),
|
||||
Err(Error::DivisionByZero)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,8 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
|
||||
let return_value = self.fold_expression(return_value)?;
|
||||
|
||||
let return_value = self.propagator.fold_expression(return_value)?;
|
||||
|
||||
Ok(FunctionCallOrExpression::Expression(
|
||||
E::from(return_value).into_inner(),
|
||||
))
|
||||
|
@ -226,22 +228,28 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> {
|
|||
FunctionCallExpression::<_, E>::new(e.function_key, generics, arguments)
|
||||
))),
|
||||
Err(InlineError::Flat(embed, generics, output_type)) => {
|
||||
let identifier = self.ssa.issue_next_identifier(CoreIdentifier::Call(0));
|
||||
let identifier = self.ssa.issue_next_identifier(CoreIdentifier::Call);
|
||||
|
||||
let var = Variable::new(identifier.clone(), output_type);
|
||||
|
||||
let v: TypedAssignee<'ast, T> = var.clone().into();
|
||||
|
||||
self.statement_buffer.push(
|
||||
TypedStatement::embed_call_definition(
|
||||
v,
|
||||
EmbedCall::new(embed, generics, arguments),
|
||||
)
|
||||
.span(span),
|
||||
);
|
||||
Ok(FunctionCallOrExpression::Expression(
|
||||
E::identifier(identifier).span(span),
|
||||
))
|
||||
let definition = TypedStatement::embed_call_definition(
|
||||
v,
|
||||
EmbedCall::new(embed, generics, arguments),
|
||||
)
|
||||
.span(span);
|
||||
|
||||
let definition = self.propagator.fold_statement(definition)?;
|
||||
|
||||
self.statement_buffer.extend(definition);
|
||||
|
||||
let e = match self.propagator.constants.get(&identifier) {
|
||||
Some(v) => E::try_from(v.clone()).unwrap().into_inner(),
|
||||
None => E::identifier(identifier),
|
||||
};
|
||||
|
||||
Ok(FunctionCallOrExpression::Expression(e.span(span)))
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -64,12 +64,14 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
&mut self,
|
||||
f: ZirFunction<'ast, T>,
|
||||
) -> Result<ZirFunction<'ast, T>, Self::Error> {
|
||||
let (arguments, inputs) = f
|
||||
.arguments
|
||||
.into_iter()
|
||||
.zip(f.signature.inputs.iter().cloned())
|
||||
.filter(|(p, _)| !self.constants.contains_key(&p.id.id))
|
||||
.unzip();
|
||||
Ok(ZirFunction {
|
||||
arguments: f
|
||||
.arguments
|
||||
.into_iter()
|
||||
.filter(|p| !self.constants.contains_key(&p.id.id))
|
||||
.collect(),
|
||||
arguments,
|
||||
statements: f
|
||||
.statements
|
||||
.into_iter()
|
||||
|
@ -78,7 +80,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
.into_iter()
|
||||
.flatten()
|
||||
.collect(),
|
||||
..f
|
||||
signature: f.signature.inputs(inputs),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::fmt;
|
|||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)]
|
||||
pub struct RefCall {
|
||||
pub index: usize,
|
||||
pub argument_count: usize,
|
||||
pub signature: (usize, usize),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, Hash, Eq)]
|
||||
|
@ -39,7 +39,7 @@ impl<'ast, T> fmt::Display for Solver<'ast, T> {
|
|||
Solver::ShaCh => write!(f, "ShaCh"),
|
||||
Solver::EuclideanDiv => write!(f, "EuclideanDiv"),
|
||||
Solver::Zir(_) => write!(f, "Zir(..)"),
|
||||
Solver::Ref(call) => write!(f, "Ref@{}({})", call.index, call.argument_count),
|
||||
Solver::Ref(call) => write!(f, "Ref@{}", call.index),
|
||||
#[cfg(feature = "bellman")]
|
||||
Solver::Sha256Round => write!(f, "Sha256Round"),
|
||||
#[cfg(feature = "ark")]
|
||||
|
@ -59,8 +59,8 @@ impl<'ast, T> Solver<'ast, T> {
|
|||
Solver::ShaAndXorAndXorAnd => (3, 1),
|
||||
Solver::ShaCh => (3, 1),
|
||||
Solver::EuclideanDiv => (2, 2),
|
||||
Solver::Zir(f) => (f.arguments.len(), 1),
|
||||
Solver::Ref(c) => (c.argument_count, 1),
|
||||
Solver::Zir(f) => (f.signature.inputs.len(), f.signature.outputs.len()),
|
||||
Solver::Ref(c) => c.signature,
|
||||
#[cfg(feature = "bellman")]
|
||||
Solver::Sha256Round => (768, 26935),
|
||||
#[cfg(feature = "ark")]
|
||||
|
|
|
@ -31,9 +31,9 @@ impl<'ast, T: Field> Folder<'ast, T> for SolverIndexer<'ast, T> {
|
|||
&mut self,
|
||||
d: DirectiveStatement<'ast, T>,
|
||||
) -> Vec<Statement<'ast, T>> {
|
||||
let signature = d.solver.get_signature();
|
||||
let res = match d.solver {
|
||||
Solver::Zir(f) => {
|
||||
let argument_count = f.arguments.len();
|
||||
let h = hash(&f);
|
||||
let index = match self.index_map.entry(h) {
|
||||
Entry::Occupied(v) => *v.get(),
|
||||
|
@ -46,10 +46,7 @@ impl<'ast, T: Field> Folder<'ast, T> for SolverIndexer<'ast, T> {
|
|||
};
|
||||
DirectiveStatement::new(
|
||||
d.outputs,
|
||||
Solver::Ref(RefCall {
|
||||
index,
|
||||
argument_count,
|
||||
}),
|
||||
Solver::Ref(RefCall { index, signature }),
|
||||
d.inputs,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ pub type SourceIdentifier<'ast> = std::borrow::Cow<'ast, str>;
|
|||
pub enum CoreIdentifier<'ast> {
|
||||
#[serde(borrow)]
|
||||
Source(ShadowedIdentifier<'ast>),
|
||||
Call(usize),
|
||||
Call,
|
||||
Constant(CanonicalConstantIdentifier<'ast>),
|
||||
Condition(usize),
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ impl<'ast> fmt::Display for CoreIdentifier<'ast> {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CoreIdentifier::Source(s) => write!(f, "{}", s),
|
||||
CoreIdentifier::Call(i) => write!(f, "#CALL_RETURN_AT_INDEX_{}", i),
|
||||
CoreIdentifier::Call => write!(f, "#CALL_RETURN"),
|
||||
CoreIdentifier::Constant(c) => write!(f, "{}/{}", c.module.display(), c.id),
|
||||
CoreIdentifier::Condition(i) => write!(f, "#CONDITION_{}", i),
|
||||
}
|
||||
|
|
|
@ -3486,6 +3486,20 @@ impl<'ast, T: Field> Block<'ast, T> for StructExpression<'ast, T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Block<'ast, T> for TypedExpression<'ast, T> {
|
||||
fn block(statements: Vec<TypedStatement<'ast, T>>, value: Self) -> Self {
|
||||
match value {
|
||||
TypedExpression::Boolean(e) => BooleanExpression::block(statements, e).into(),
|
||||
TypedExpression::FieldElement(e) => FieldElementExpression::block(statements, e).into(),
|
||||
TypedExpression::Uint(e) => UExpression::block(statements, e).into(),
|
||||
TypedExpression::Array(e) => ArrayExpression::block(statements, e).into(),
|
||||
TypedExpression::Struct(e) => StructExpression::block(statements, e).into(),
|
||||
TypedExpression::Tuple(e) => TupleExpression::block(statements, e).into(),
|
||||
TypedExpression::Int(e) => unreachable!("{}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Constant: Sized {
|
||||
// return whether this is constant
|
||||
fn is_constant(&self) -> bool;
|
||||
|
|
|
@ -942,6 +942,23 @@ impl<S> GType<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: PartialEq> GType<S> {
|
||||
pub fn is_composite_of_field(&self) -> bool {
|
||||
match self {
|
||||
GType::Array(array_type) => array_type.ty.is_composite_of_field(),
|
||||
GType::Tuple(tuple_typle) => tuple_typle
|
||||
.elements
|
||||
.iter()
|
||||
.all(|e| e.is_composite_of_field()),
|
||||
GType::Struct(struct_type) => struct_type
|
||||
.members
|
||||
.iter()
|
||||
.all(|m| m.ty.is_composite_of_field()),
|
||||
other => other.eq(&Self::FieldElement),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display + PartialEq + fmt::Debug> Type<'ast, T> {
|
||||
pub fn can_be_specialized_to(&self, other: &DeclarationType<'ast, T>) -> bool {
|
||||
use self::GType::*;
|
||||
|
|
|
@ -282,7 +282,7 @@ impl<'ast, T: fmt::Display> fmt::Display for MultipleDefinitionStatement<'ast, T
|
|||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, " = {};", self.rhs)
|
||||
write!(f, " = {}", self.rhs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,7 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> {
|
|||
write!(f, ";")
|
||||
}
|
||||
ZirStatement::Definition(ref s) => {
|
||||
write!(f, "{}", s)
|
||||
write!(f, "{};", s)
|
||||
}
|
||||
ZirStatement::IfElse(ref s) => {
|
||||
writeln!(f, "if {} {{", s.condition)?;
|
||||
|
@ -441,7 +441,7 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> {
|
|||
}
|
||||
}
|
||||
ZirStatement::MultipleDefinition(ref s) => {
|
||||
write!(f, "{}", s)
|
||||
write!(f, "{};", s)
|
||||
}
|
||||
ZirStatement::Log(ref e) => write!(
|
||||
f,
|
||||
|
|
|
@ -9,13 +9,13 @@ edition = "2021"
|
|||
zokrates_field = { version = "0.5", path = "../zokrates_field", features = ["bellperson_extensions"] }
|
||||
zokrates_ast = { version = "0.1", path = "../zokrates_ast", features = ["bellperson"] }
|
||||
# zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", default-features = false }
|
||||
bellperson = { package = "bellperson", version = "^0.24", default-features = false }
|
||||
bellperson = { package = "bellperson", version = "^0.25", default-features = false }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }#
|
||||
getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] }
|
||||
hex = "0.4.2"
|
||||
pairing = "0.22"
|
||||
ff = { version = "0.12.0", default-features = false }
|
||||
nova-snark = { version = "0.20.3" }
|
||||
ff = { version = "0.13.0", default-features = false }
|
||||
nova-snark = { version = "0.21.0" }
|
||||
zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
|
@ -26,7 +26,7 @@ rand_0_4 = { version = "0.4", package = "rand" }
|
|||
getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] }
|
||||
hex = "0.4.2"
|
||||
pairing = "0.22"
|
||||
pasta_curves = { version = "0.5.2", features = ["repr-c", "serde"], package = "fil_pasta_curves"}
|
||||
pasta_curves = { version = "0.5", features = ["repr-c", "serde"] }
|
||||
zokrates_core = { version = "0.7.3", path = "../zokrates_core" }
|
||||
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ pub fn verify<T: NovaField>(
|
|||
arguments: Vec<T>,
|
||||
) -> Result<Vec<T>, Error> {
|
||||
let z0_primary: Vec<_> = arguments.into_iter().map(|a| a.into_bellperson()).collect();
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::one()];
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::ONE];
|
||||
|
||||
proof
|
||||
.proof
|
||||
|
@ -149,7 +149,7 @@ pub fn verify_compressed<'ast, T: NovaField>(
|
|||
step_count: usize,
|
||||
) -> bool {
|
||||
let z0_primary: Vec<_> = arguments.into_iter().map(|a| a.into_bellperson()).collect();
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::one()];
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::ONE];
|
||||
|
||||
proof
|
||||
.verify(vk, step_count, z0_primary, z0_secondary)
|
||||
|
@ -166,7 +166,7 @@ pub fn prove<'ast, T: NovaField>(
|
|||
let c_primary = NovaComputation::try_from(Computation::without_witness(program))?;
|
||||
let c_secondary = TrivialTestCircuit::default();
|
||||
let z0_primary: Vec<_> = arguments.into_iter().map(|a| a.into_bellperson()).collect();
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::one()];
|
||||
let z0_secondary = vec![<<T as Cycle>::Point as Group>::Base::ONE];
|
||||
|
||||
for steps_private in steps {
|
||||
let mut c_primary = c_primary.clone();
|
||||
|
|
|
@ -17,9 +17,19 @@ Assigning a value, in general, should be combined with adding a constraint:
|
|||
{{#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.
|
||||
> Note that operator `<--` is used for unconstrained assignment and can be easily misused. This operator does not generate constraints, which could result in unconstrained variables in the constraint system.
|
||||
|
||||
In some cases we can combine the witness assignment and constraint generation with the `<==` operator:
|
||||
Unconstrained assignment `<--` allows assignment to variables with complex types. The type must consist of field elements only (eg. `field[3]`):
|
||||
|
||||
```zok
|
||||
field[3] mut c = [0; 3];
|
||||
asm {
|
||||
c <-- [2, 2, 4];
|
||||
c[0] * c[1] === c[2];
|
||||
}
|
||||
```
|
||||
|
||||
In some cases we can combine the witness assignment and constraint generation with the `<==` operator (constrained assignment):
|
||||
|
||||
```zok
|
||||
asm {
|
||||
|
@ -36,6 +46,8 @@ asm {
|
|||
}
|
||||
```
|
||||
|
||||
In the case of constrained assignment `<==`, both sides of the statement have to be of type `field`.
|
||||
|
||||
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:
|
||||
|
|
|
@ -25,7 +25,7 @@ Booleans are available in ZoKrates. When a boolean is used as a parameter of the
|
|||
|
||||
### `u8/u16/u32/u64`
|
||||
|
||||
Unsigned integers represent positive numbers of the interval `[0, 2 ** bitwidth[`, where `bitwidth` is specified in the type's name, e.g., 32 bits in the case of u32. Their arithmetics are defined modulo `2 ** bitwidth`.
|
||||
Unsigned integers represent positive numbers of the interval `[0, 2 ** bitwidth)`, where `bitwidth` is specified in the type's name, e.g., 32 bits in the case of u32. Their arithmetics are defined modulo `2 ** bitwidth`.
|
||||
|
||||
Internally, they use a binary encoding, which makes them particularly efficient for implementing programs that operate on that binary representation, e.g., the SHA256 hash function.
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
def main(bool a) {
|
||||
bool mut b = false;
|
||||
asm {
|
||||
b <-- a;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
def main() {
|
||||
field[2] mut a = [0; 2];
|
||||
asm {
|
||||
a <== [1, 2];
|
||||
}
|
||||
}
|
|
@ -1793,20 +1793,32 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
AssemblyStatement::Assignment(assignee, expression, constrained) => {
|
||||
let assignee = self.check_assignee(assignee, module_id, types)?;
|
||||
let e = self.check_expression(expression, module_id, types)?;
|
||||
|
||||
let e = FieldElementExpression::try_from_typed(e).map_err(|e| ErrorInner {
|
||||
span: Some(span),
|
||||
message: format!(
|
||||
"Expected right hand side of an assembly assignment to be of type field, found {}",
|
||||
e.get_type(),
|
||||
),
|
||||
let e = TypedExpression::align_to_type(e, &assignee.get_type()).map_err(|e| {
|
||||
ErrorInner {
|
||||
span: Some(span),
|
||||
message: format!(
|
||||
"Expected value of type `{}`, found `{}` of type `{}`",
|
||||
e.1,
|
||||
e.0,
|
||||
e.0.get_type()
|
||||
),
|
||||
}
|
||||
})?;
|
||||
|
||||
match constrained {
|
||||
true => {
|
||||
let e = FieldElementExpression::block(vec![], e);
|
||||
match assignee.get_type() {
|
||||
Type::FieldElement => Ok(vec![
|
||||
true => match assignee.get_type() {
|
||||
// in case of `lhs <== rhs` we expect lhs and rhs to be of type field
|
||||
Type::FieldElement => {
|
||||
let e = FieldElementExpression::try_from_typed(e).map_err(|e| ErrorInner {
|
||||
span: Some(span),
|
||||
message: format!(
|
||||
"Expected right hand side of an assembly constrained assignment to be of type field, found {}",
|
||||
e.get_type(),
|
||||
),
|
||||
})?;
|
||||
|
||||
let e = FieldElementExpression::block(vec![], e);
|
||||
Ok(vec![
|
||||
TypedAssemblyStatement::assignment(
|
||||
assignee.clone(),
|
||||
e.clone().into(),
|
||||
|
@ -1818,18 +1830,28 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
SourceMetadata::new(module_id.display().to_string(), span.from),
|
||||
)
|
||||
.with_span(span),
|
||||
]),
|
||||
ty => Err(ErrorInner {
|
||||
span: Some(span),
|
||||
message: format!("Assignee must be of type field, found {}", ty),
|
||||
}),
|
||||
])
|
||||
}
|
||||
}
|
||||
ty => Err(ErrorInner {
|
||||
span: Some(span),
|
||||
message: format!("Assignee must be of type field, found {}", ty),
|
||||
}),
|
||||
},
|
||||
false => {
|
||||
let e = FieldElementExpression::block(vec![], e);
|
||||
Ok(vec![
|
||||
TypedAssemblyStatement::assignment(assignee, e.into()).with_span(span)
|
||||
])
|
||||
// we can allow composite types in case of `<--` as no constraints are generated from this type of statement
|
||||
// a composite type should only consist of field types
|
||||
match e.get_type().is_composite_of_field() {
|
||||
true => {
|
||||
let e = TypedExpression::block(vec![], e);
|
||||
Ok(vec![
|
||||
TypedAssemblyStatement::assignment(assignee, e).with_span(span)
|
||||
])
|
||||
},
|
||||
false => Err(ErrorInner {
|
||||
span: Some(span),
|
||||
message: "Assignee must be of type field or a composite type of field elements".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
zokrates_core_test/tests/tests/assembly/assignment.json
Normal file
16
zokrates_core_test/tests/tests/assembly/assignment.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"curves": ["Bn128"],
|
||||
"max_constraint_count": 4,
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["1", "2"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": ["3", "2"]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
15
zokrates_core_test/tests/tests/assembly/assignment.zok
Normal file
15
zokrates_core_test/tests/tests/assembly/assignment.zok
Normal file
|
@ -0,0 +1,15 @@
|
|||
def foo(field a, field b) -> field[2] {
|
||||
field c = a + b;
|
||||
field d = a * b;
|
||||
return [c, d];
|
||||
}
|
||||
|
||||
def main(field a, field b) -> field[2] {
|
||||
field[2] mut c = [0; 2];
|
||||
asm {
|
||||
c <-- foo(a, b);
|
||||
a + b === c[0];
|
||||
a * b === c[1];
|
||||
}
|
||||
return c;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"curves": ["Bn128"],
|
||||
"max_constraint_count": 1,
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": ["2", "2", "4"]
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
def main(field a, field b, field c) {
|
||||
field[2] mut out = [0; 2];
|
||||
asm {
|
||||
out <-- [a, b];
|
||||
out[0] * out[1] === c;
|
||||
}
|
||||
}
|
3
zokrates_core_test/tests/tests/constant_condition.json
Normal file
3
zokrates_core_test/tests/tests/constant_condition.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"tests": []
|
||||
}
|
6
zokrates_core_test/tests/tests/constant_condition.zok
Normal file
6
zokrates_core_test/tests/tests/constant_condition.zok
Normal file
|
@ -0,0 +1,6 @@
|
|||
def main() {
|
||||
field[2] a = [0; 2];
|
||||
for u32 i in 1..2 {
|
||||
field b = (i == 1) ? 0 : a[i - 2];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/constants/propagate_embed.zok",
|
||||
"max_constraint_count": 2,
|
||||
"tests": []
|
||||
}
|
16
zokrates_core_test/tests/tests/constants/propagate_embed.zok
Normal file
16
zokrates_core_test/tests/tests/constants/propagate_embed.zok
Normal file
|
@ -0,0 +1,16 @@
|
|||
import "utils/casts/field_to_u32";
|
||||
from "EMBED" import unpack;
|
||||
|
||||
def foo<N>() -> field {
|
||||
return 1;
|
||||
}
|
||||
|
||||
def main() -> field {
|
||||
u32 N = field_to_u32(1);
|
||||
for u32 i in 0..N {
|
||||
log("{}", i);
|
||||
}
|
||||
bool[1] B = unpack(1);
|
||||
u32 P = B[0] ? 1 : 0;
|
||||
return foo::<N>() + foo::<P>();
|
||||
}
|
|
@ -24,11 +24,11 @@ num-integer = { version = "0.1", default-features = false }
|
|||
bellman_ce = { version = "^0.3", default-features = false, optional = true }
|
||||
|
||||
# bellperson
|
||||
bellperson = { version = "0.24", default-features = false, optional = true }
|
||||
bellperson = { version = "0.25", default-features = false, optional = true }
|
||||
pairing = { version = "0.22", default-features = false, optional = true }
|
||||
ff = { version = "0.12.0", default-features = false, optional = true }
|
||||
pasta_curves = { version = "0.5.2", features = ["repr-c", "serde"], package = "fil_pasta_curves", optional = true }
|
||||
nova-snark = { version = "0.20.3", optional = true }
|
||||
ff = { version = "0.13.0", default-features = false, optional = true }
|
||||
pasta_curves = { version = "0.5", features = ["repr-c", "serde"], optional = true }
|
||||
nova-snark = { version = "0.21.0", optional = true }
|
||||
|
||||
# ark
|
||||
ark-ff = { version = "^0.3.0", default-features = false }
|
||||
|
|
|
@ -523,7 +523,7 @@ mod tests {
|
|||
let id = IdentifierExpression::new(Identifier::internal(0usize));
|
||||
|
||||
// (field i0) -> i0 * i0
|
||||
let solvers = vec![Solver::Zir(ZirFunction {
|
||||
let solver = Solver::Zir(ZirFunction {
|
||||
arguments: vec![Parameter::new(Variable::field_element(id.id.clone()), true)],
|
||||
statements: vec![ZirStatement::ret(vec![FieldElementExpression::mul(
|
||||
FieldElementExpression::Identifier(id.clone()),
|
||||
|
@ -533,13 +533,16 @@ mod tests {
|
|||
signature: Signature::new()
|
||||
.inputs(vec![Type::FieldElement])
|
||||
.outputs(vec![Type::FieldElement]),
|
||||
})];
|
||||
});
|
||||
|
||||
let signature = solver.get_signature();
|
||||
let solvers = vec![solver];
|
||||
|
||||
let inputs = vec![Bn128Field::from(2)];
|
||||
let res = Interpreter::execute_solver(
|
||||
&Solver::Ref(RefCall {
|
||||
index: 0,
|
||||
argument_count: 1,
|
||||
signature,
|
||||
}),
|
||||
&inputs,
|
||||
&solvers,
|
||||
|
|
|
@ -89,7 +89,7 @@ const field[91] C = [
|
|||
4212716923652881254737947578600828255798948993302968210248673545442808456151,
|
||||
7594017890037021425366623750593200398174488805473151513558919864633711506220,
|
||||
18979889247746272055963929241596362599320706910852082477600815822482192194401,
|
||||
1360213922981323134938688511315690179366171918090039581890971975815045550053
|
||||
13602139229813231349386885113156901793661719180900395818909719758150455500533
|
||||
];
|
||||
|
||||
def main<R>(field x_in, field k) -> field {
|
||||
|
@ -109,4 +109,4 @@ def main<R>(field x_in, field k) -> field {
|
|||
}
|
||||
|
||||
return t6[R - 1] * t + k;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue