Merge pull request #1151 from Zokrates/split-to-crates
Split project into crates
This commit is contained in:
commit
80f4aa4939
167 changed files with 3536 additions and 13572 deletions
|
@ -47,17 +47,10 @@ jobs:
|
|||
no_output_timeout: 1h
|
||||
command: WITH_LIBSNARK=1 RUSTFLAGS="-D warnings" ./test.sh
|
||||
- save-sccache-cache
|
||||
cpp_format:
|
||||
docker:
|
||||
- image: zokrates/env:latest
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Check cpp format (clang-format)
|
||||
command: run-clang-format.py -r $(pwd)/zokrates_core/lib
|
||||
wasm_test:
|
||||
docker:
|
||||
- image: zokrates/env:latest
|
||||
resource_class: large
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
|
@ -68,8 +61,8 @@ jobs:
|
|||
- run:
|
||||
name: Test on firefox
|
||||
command: |
|
||||
cd zokrates_core
|
||||
wasm-pack test --firefox --headless -- --no-default-features --features "wasm ark"
|
||||
cd zokrates_test
|
||||
wasm-pack test --firefox --headless
|
||||
- save-sccache-cache
|
||||
integration_test:
|
||||
docker:
|
||||
|
@ -255,7 +248,6 @@ workflows:
|
|||
jobs:
|
||||
- build
|
||||
- test
|
||||
- cpp_format
|
||||
- wasm_test
|
||||
- integration_test
|
||||
- zokrates_js_build
|
||||
|
@ -314,7 +306,6 @@ workflows:
|
|||
requires:
|
||||
- build
|
||||
- test
|
||||
- cpp_format
|
||||
- wasm_test
|
||||
- integration_test
|
||||
- zokrates_js_build
|
||||
|
|
490
Cargo.lock
generated
490
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -11,6 +11,13 @@ members = [
|
|||
"zokrates_test",
|
||||
"zokrates_core_test",
|
||||
"zokrates_solidity_test",
|
||||
"zokrates_ark",
|
||||
"zokrates_ast",
|
||||
"zokrates_interpreter",
|
||||
"zokrates_embed",
|
||||
"zokrates_bellman",
|
||||
"zokrates_proof_systems",
|
||||
"zokrates_js",
|
||||
]
|
||||
|
||||
exclude = ["zokrates_js"]
|
||||
exclude = []
|
|
@ -15,14 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
curl \
|
||||
build-essential \
|
||||
software-properties-common \
|
||||
cmake \
|
||||
gnupg \
|
||||
libboost-all-dev \
|
||||
libgmp3-dev \
|
||||
libprocps-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
clang-format \
|
||||
python-is-python3 \
|
||||
python-markdown \
|
||||
&& add-apt-repository ppa:mozillateam/ppa \
|
||||
|
|
6
build.sh
6
build.sh
|
@ -3,8 +3,4 @@
|
|||
# Exit if any subcommand fails
|
||||
set -e
|
||||
|
||||
if [ -n "$WITH_LIBSNARK" ]; then
|
||||
cargo build --package zokrates_cli --features="libsnark"
|
||||
else
|
||||
cargo build --package zokrates_cli
|
||||
fi
|
||||
cargo build --package zokrates_cli
|
|
@ -4,8 +4,4 @@
|
|||
set -e
|
||||
export RUSTFLAGS="--remap-path-prefix=$PWD="
|
||||
|
||||
if [ -n "$WITH_LIBSNARK" ]; then
|
||||
cargo build --release --package zokrates_cli --features="libsnark"
|
||||
else
|
||||
cargo build --release --package zokrates_cli
|
||||
fi
|
||||
cargo build --release --package zokrates_cli
|
||||
|
|
1
changelogs/unreleased/1151-schaeff
Normal file
1
changelogs/unreleased/1151-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Split codebase into smaller crates
|
1
changelogs/unreleased/1153-schaeff
Normal file
1
changelogs/unreleased/1153-schaeff
Normal file
|
@ -0,0 +1 @@
|
|||
Drop support for libsnark
|
|
@ -4,11 +4,6 @@ MAINTAINER JacobEberhardt <jacob.eberhardt@tu-berlin.de>, Thibaut Schaeffer <thi
|
|||
|
||||
RUN useradd -u 1000 -m zokrates
|
||||
|
||||
ENV WITH_LIBSNARK=1
|
||||
|
||||
COPY ./scripts/install_libsnark_prerequisites.sh /tmp/
|
||||
RUN /tmp/install_libsnark_prerequisites.sh
|
||||
|
||||
COPY ./scripts/install_solcjs_deb.sh /tmp/
|
||||
RUN /tmp/install_solcjs_deb.sh
|
||||
|
||||
|
|
|
@ -3,8 +3,4 @@
|
|||
# Exit if any subcommand fails
|
||||
set -e
|
||||
|
||||
if [ -n "$WITH_LIBSNARK" ]; then
|
||||
cargo test -j 4 --release --package zokrates_cli --features="libsnark" -- --ignored
|
||||
else
|
||||
cargo test -j 4 --release --package zokrates_cli -- --ignored
|
||||
fi
|
||||
cargo test -j 4 --release --package zokrates_cli -- --ignored
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
# Usage: ./clang-format.sh zokrates_core/lib
|
||||
|
||||
dir=$1
|
||||
|
||||
for file in $dir/*.cpp $dir/*.hpp $dir/*.tcc; do
|
||||
clang-format -i -style=WebKit -verbose $file
|
||||
done
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit if any subcommand fails
|
||||
set -e
|
||||
|
||||
apt-get update
|
||||
apt-get install -qq curl zlib1g-dev build-essential python
|
||||
apt-get install -qq cmake g++ pkg-config jq
|
||||
apt-get install -qq libcurl4-openssl-dev libelf-dev libdw-dev binutils-dev libiberty-dev
|
||||
cargo install cargo-kcov
|
||||
cargo kcov --print-install-kcov-sh | sh
|
||||
cd zokrates_fs_resolver && WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark cargo kcov && cd ..
|
||||
cd zokrates_core && WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark cargo kcov && cd ..
|
||||
cd zokrates_cli && WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark cargo kcov && cd ..
|
||||
cd zokrates_field && WITH_LIBSNARK=1 LIBSNARK_SOURCE_PATH=$HOME/libsnark cargo kcov && cd ..
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
echo "Uploaded code coverage"
|
6
test.sh
6
test.sh
|
@ -3,10 +3,4 @@
|
|||
# Exit if any subcommand fails
|
||||
set -e
|
||||
|
||||
if [ -n "$WITH_LIBSNARK" ]; then
|
||||
# run specifically the libsnark tests inside zokrates_core
|
||||
cargo test -j 4 --release --package zokrates_core --features="libsnark" libsnark -- --test-threads=1
|
||||
fi
|
||||
|
||||
# run all tests without libsnark on
|
||||
cargo test -j 4 --release
|
|
@ -4,9 +4,14 @@ version = "0.1.7"
|
|||
authors = ["Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
default = ["ark", "bellman"]
|
||||
ark = ["zokrates_ast/ark"]
|
||||
bellman = ["zokrates_ast/bellman"]
|
||||
|
||||
[dependencies]
|
||||
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
|
||||
zokrates_core = { version = "0.6", path = "../zokrates_core", default-features = false }
|
||||
zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false }
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
|
|
|
@ -15,7 +15,7 @@ impl<T: Field> Encode<T> for Inputs<T> {
|
|||
}
|
||||
|
||||
use std::fmt;
|
||||
use zokrates_core::typed_absy::types::{ConcreteType, UBitwidth};
|
||||
use zokrates_ast::typed::types::{ConcreteType, UBitwidth};
|
||||
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -380,9 +380,7 @@ pub fn parse_strict_json<T: Field>(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use zokrates_core::typed_absy::types::{
|
||||
ConcreteStructMember, ConcreteStructType, ConcreteType,
|
||||
};
|
||||
use zokrates_ast::typed::types::{ConcreteStructMember, ConcreteStructType, ConcreteType};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
||||
|
|
34
zokrates_ark/Cargo.toml
Normal file
34
zokrates_ark/Cargo.toml
Normal file
|
@ -0,0 +1,34 @@
|
|||
[package]
|
||||
name = "zokrates_ark"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
|
||||
zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false }
|
||||
zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", default-features = false }
|
||||
|
||||
ark-ff = { version = "^0.3.0", default-features = false }
|
||||
ark-ec = { version = "^0.3.0", default-features = false }
|
||||
ark-bn254 = { version = "^0.3.0", features = ["curve"], default-features = false }
|
||||
ark-bls12-377 = { version = "^0.3.0", features = ["curve"], default-features = false }
|
||||
ark-bw6-761 = { version = "^0.3.0", default-features = false }
|
||||
ark-gm17 = { version = "^0.3.0", default-features = false }
|
||||
ark-groth16 = { version = "^0.3.0", default-features = false }
|
||||
ark-serialize = { version = "^0.3.0", default-features = false }
|
||||
ark-relations = { version = "^0.3.0", default-features = false }
|
||||
ark-marlin = { git = "https://github.com/arkworks-rs/marlin", rev = "63cfd82", default-features = false }
|
||||
ark-poly = { version = "^0.3.0", default-features = false }
|
||||
ark-poly-commit = { version = "^0.3.0", default-features = false }
|
||||
ark-crypto-primitives = { version = "^0.3.0", default-features = false }
|
||||
sha3 = { version = "0.9" }
|
||||
digest = { version = "0.9" }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
hex = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter", features = ["ark"] }
|
||||
|
||||
|
163
zokrates_ark/src/gm17.rs
Normal file
163
zokrates_ark/src/gm17.rs
Normal file
|
@ -0,0 +1,163 @@
|
|||
use ark_crypto_primitives::SNARK;
|
||||
use ark_gm17::{
|
||||
prepare_verifying_key, verify_proof, PreparedVerifyingKey, Proof as ArkProof, ProvingKey,
|
||||
VerifyingKey, GM17 as ArkGM17,
|
||||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
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 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<T: Field + ArkFieldExtensions> NonUniversalBackend<T, GM17> for Ark {
|
||||
fn setup<I: IntoIterator<Item = Statement<T>>>(
|
||||
program: ProgIterator<T, I>,
|
||||
) -> SetupKeypair<T, GM17> {
|
||||
let computation = Computation::without_witness(program);
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let (pk, vk) = ArkGM17::<T::ArkEngine>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
pk.serialize_uncompressed(&mut pk_vec).unwrap();
|
||||
|
||||
let vk = VerificationKey {
|
||||
h: parse_g2::<T>(&vk.h_g2),
|
||||
g_alpha: parse_g1::<T>(&vk.g_alpha_g1),
|
||||
h_beta: parse_g2::<T>(&vk.h_beta_g2),
|
||||
g_gamma: parse_g1::<T>(&vk.g_gamma_g1),
|
||||
h_gamma: parse_g2::<T>(&vk.h_gamma_g2),
|
||||
query: vk.query.iter().map(|g1| parse_g1::<T>(g1)).collect(),
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk_vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> Backend<T, GM17> for Ark {
|
||||
fn generate_proof<I: IntoIterator<Item = Statement<T>>>(
|
||||
program: ProgIterator<T, I>,
|
||||
witness: Witness<T>,
|
||||
proving_key: Vec<u8>,
|
||||
) -> Proof<T, GM17> {
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let inputs = computation
|
||||
.public_inputs_values()
|
||||
.iter()
|
||||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pk = ProvingKey::<<T as ArkFieldExtensions>::ArkEngine>::deserialize_uncompressed(
|
||||
&mut proving_key.as_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let proof = ArkGM17::<T::ArkEngine>::prove(&pk, computation, rng).unwrap();
|
||||
|
||||
let proof_points = ProofPoints {
|
||||
a: parse_g1::<T>(&proof.a),
|
||||
b: parse_g2::<T>(&proof.b),
|
||||
c: parse_g1::<T>(&proof.c),
|
||||
};
|
||||
|
||||
Proof::new(proof_points, inputs)
|
||||
}
|
||||
|
||||
fn verify(vk: <GM17 as Scheme<T>>::VerificationKey, proof: Proof<T, GM17>) -> bool {
|
||||
let vk = VerifyingKey {
|
||||
h_g2: serialization::to_g2::<T>(vk.h),
|
||||
g_alpha_g1: serialization::to_g1::<T>(vk.g_alpha),
|
||||
h_beta_g2: serialization::to_g2::<T>(vk.h_beta),
|
||||
g_gamma_g1: serialization::to_g1::<T>(vk.g_gamma),
|
||||
h_gamma_g2: serialization::to_g2::<T>(vk.h_gamma),
|
||||
query: vk
|
||||
.query
|
||||
.into_iter()
|
||||
.map(serialization::to_g1::<T>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let ark_proof = ArkProof {
|
||||
a: serialization::to_g1::<T>(proof.proof.a),
|
||||
b: serialization::to_g2::<T>(proof.proof.b),
|
||||
c: serialization::to_g1::<T>(proof.proof.c),
|
||||
};
|
||||
|
||||
let pvk: PreparedVerifyingKey<<T as ArkFieldExtensions>::ArkEngine> =
|
||||
prepare_verifying_key(&vk);
|
||||
|
||||
let public_inputs: Vec<_> = proof
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|s| {
|
||||
T::try_from_str(s.trim_start_matches("0x"), 16)
|
||||
.unwrap()
|
||||
.into_ark()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
verify_proof(&pvk, &ark_proof, &public_inputs).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
use super::*;
|
||||
use zokrates_field::{Bls12_377Field, Bw6_761Field};
|
||||
|
||||
#[test]
|
||||
fn verify_bls12_377_field() {
|
||||
let program: Prog<Bls12_377Field> = Prog {
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bls12_377Field, GM17>>::setup(program.clone());
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bls12_377Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bls12_377Field, GM17>>::generate_proof(program, witness, keypair.pk);
|
||||
let ans = <Ark as Backend<Bls12_377Field, GM17>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_bw6_761_field() {
|
||||
let program: Prog<Bw6_761Field> = Prog {
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, GM17>>::setup(program.clone());
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bw6_761Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Ark as Backend<Bw6_761Field, GM17>>::generate_proof(program, witness, keypair.pk);
|
||||
let ans = <Ark as Backend<Bw6_761Field, GM17>>::verify(keypair.vk, proof);
|
||||
|
||||
assert!(ans);
|
||||
}
|
||||
}
|
|
@ -1,25 +1,24 @@
|
|||
use crate::proof_system::{Backend, NonUniversalBackend, NotBw6_761Field, Proof, SetupKeypair};
|
||||
use ark_crypto_primitives::SNARK;
|
||||
use ark_groth16::{
|
||||
prepare_verifying_key, verify_proof, Groth16, PreparedVerifyingKey, Proof as ArkProof,
|
||||
ProvingKey, VerifyingKey,
|
||||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use zokrates_field::ArkFieldExtensions;
|
||||
use zokrates_field::Field;
|
||||
use zokrates_field::{ArkFieldExtensions, Bw6_761Field};
|
||||
use zokrates_proof_systems::{Backend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
|
||||
use crate::ir::{ProgIterator, Statement, Witness};
|
||||
use crate::proof_system::ark::Computation;
|
||||
use crate::proof_system::ark::{parse_fr, serialization, Ark};
|
||||
use crate::proof_system::ark::{parse_g1, parse_g2};
|
||||
use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16};
|
||||
use crate::proof_system::Scheme;
|
||||
use ark_bw6_761::BW6_761;
|
||||
use crate::Computation;
|
||||
use crate::{parse_fr, serialization, Ark};
|
||||
use crate::{parse_g1, parse_g2};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16};
|
||||
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<T: Field + ArkFieldExtensions + NotBw6_761Field> Backend<T, G16> for Ark {
|
||||
impl<T: Field + ArkFieldExtensions> Backend<T, G16> for Ark {
|
||||
fn generate_proof<I: IntoIterator<Item = Statement<T>>>(
|
||||
program: ProgIterator<T, I>,
|
||||
witness: Witness<T>,
|
||||
|
@ -86,7 +85,7 @@ impl<T: Field + ArkFieldExtensions + NotBw6_761Field> Backend<T, G16> for Ark {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions + NotBw6_761Field> NonUniversalBackend<T, G16> for Ark {
|
||||
impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, G16> for Ark {
|
||||
fn setup<I: IntoIterator<Item = Statement<T>>>(
|
||||
program: ProgIterator<T, I>,
|
||||
) -> SetupKeypair<T, G16> {
|
||||
|
@ -112,108 +111,11 @@ impl<T: Field + ArkFieldExtensions + NotBw6_761Field> NonUniversalBackend<T, G16
|
|||
}
|
||||
}
|
||||
|
||||
impl Backend<Bw6_761Field, G16> for Ark {
|
||||
fn generate_proof<I: IntoIterator<Item = Statement<Bw6_761Field>>>(
|
||||
program: ProgIterator<Bw6_761Field, I>,
|
||||
witness: Witness<Bw6_761Field>,
|
||||
proving_key: Vec<u8>,
|
||||
) -> Proof<Bw6_761Field, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let computation = Computation::with_witness(program, witness);
|
||||
|
||||
let inputs = computation
|
||||
.public_inputs_values()
|
||||
.iter()
|
||||
.map(parse_fr::<Bw6_761Field>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pk =
|
||||
ProvingKey::<BW6_761>::deserialize_uncompressed(&mut proving_key.as_slice()).unwrap();
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let proof = Groth16::<BW6_761>::prove(&pk, computation, rng).unwrap();
|
||||
|
||||
let proof_points = ProofPoints {
|
||||
a: parse_g1::<Bw6_761Field>(&proof.a),
|
||||
b: parse_g2::<Bw6_761Field>(&proof.b),
|
||||
c: parse_g1::<Bw6_761Field>(&proof.c),
|
||||
};
|
||||
|
||||
Proof::new(proof_points, inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
vk: <G16 as Scheme<Bw6_761Field>>::VerificationKey,
|
||||
proof: Proof<Bw6_761Field, G16>,
|
||||
) -> bool {
|
||||
let vk = VerifyingKey {
|
||||
alpha_g1: serialization::to_g1::<Bw6_761Field>(vk.alpha),
|
||||
beta_g2: serialization::to_g2::<Bw6_761Field>(vk.beta),
|
||||
gamma_g2: serialization::to_g2::<Bw6_761Field>(vk.gamma),
|
||||
delta_g2: serialization::to_g2::<Bw6_761Field>(vk.delta),
|
||||
gamma_abc_g1: vk
|
||||
.gamma_abc
|
||||
.into_iter()
|
||||
.map(serialization::to_g1::<Bw6_761Field>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let pvk: PreparedVerifyingKey<BW6_761> = prepare_verifying_key(&vk);
|
||||
let ark_proof = ArkProof {
|
||||
a: serialization::to_g1::<Bw6_761Field>(proof.proof.a),
|
||||
b: serialization::to_g2::<Bw6_761Field>(proof.proof.b),
|
||||
c: serialization::to_g1::<Bw6_761Field>(proof.proof.c),
|
||||
};
|
||||
|
||||
let public_inputs: Vec<_> = proof
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|s| {
|
||||
Bw6_761Field::try_from_str(s.trim_start_matches("0x"), 16)
|
||||
.unwrap()
|
||||
.into_ark()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
verify_proof(&pvk, &ark_proof, &public_inputs).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl NonUniversalBackend<Bw6_761Field, G16> for Ark {
|
||||
fn setup<I: IntoIterator<Item = Statement<Bw6_761Field>>>(
|
||||
program: ProgIterator<Bw6_761Field, I>,
|
||||
) -> SetupKeypair<Bw6_761Field, G16> {
|
||||
println!("{}", G16_WARNING);
|
||||
|
||||
let computation = Computation::without_witness(program);
|
||||
|
||||
let rng = &mut StdRng::from_entropy();
|
||||
let (pk, vk) = Groth16::<BW6_761>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
pk.serialize_uncompressed(&mut pk_vec).unwrap();
|
||||
|
||||
let vk = VerificationKey {
|
||||
alpha: parse_g1::<Bw6_761Field>(&vk.alpha_g1),
|
||||
beta: parse_g2::<Bw6_761Field>(&vk.beta_g2),
|
||||
gamma: parse_g2::<Bw6_761Field>(&vk.gamma_g2),
|
||||
delta: parse_g2::<Bw6_761Field>(&vk.delta_g2),
|
||||
gamma_abc: vk
|
||||
.gamma_abc_g1
|
||||
.iter()
|
||||
.map(parse_g1::<Bw6_761Field>)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk_vec)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::flat_absy::{FlatParameter, FlatVariable};
|
||||
use crate::ir::{Interpreter, Prog, Statement};
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
use super::*;
|
||||
use zokrates_field::{Bls12_377Field, Bw6_761Field};
|
||||
|
@ -221,12 +123,9 @@ mod tests {
|
|||
#[test]
|
||||
fn verify_bls12_377_field() {
|
||||
let program: Prog<Bls12_377Field> = Prog {
|
||||
arguments: vec![FlatParameter::public(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::new(0),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bls12_377Field, G16>>::setup(program.clone());
|
||||
|
@ -246,12 +145,9 @@ mod tests {
|
|||
#[test]
|
||||
fn verify_bw6_761_field() {
|
||||
let program: Prog<Bw6_761Field> = Prog {
|
||||
arguments: vec![FlatParameter::public(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::new(0),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Ark as NonUniversalBackend<Bw6_761Field, G16>>::setup(program.clone());
|
|
@ -2,14 +2,14 @@ pub mod gm17;
|
|||
pub mod groth16;
|
||||
pub mod marlin;
|
||||
|
||||
use crate::flat_absy::FlatVariable;
|
||||
use crate::ir::{CanonicalLinComb, ProgIterator, Statement, Witness};
|
||||
use ark_ec::PairingEngine;
|
||||
use ark_relations::r1cs::{
|
||||
ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, LinearCombination,
|
||||
SynthesisError, Variable,
|
||||
SynthesisError, Variable as ArkVariable,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
use zokrates_ast::common::Variable;
|
||||
use zokrates_ast::ir::{CanonicalLinComb, ProgIterator, Statement, Witness};
|
||||
use zokrates_field::{ArkFieldExtensions, Field};
|
||||
|
||||
pub use self::parse::*;
|
||||
|
@ -41,7 +41,7 @@ impl<T, I: IntoIterator<Item = Statement<T>>> Computation<T, I> {
|
|||
fn ark_combination<T: Field + ArkFieldExtensions>(
|
||||
l: CanonicalLinComb<T>,
|
||||
cs: &mut ConstraintSystem<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
|
||||
symbols: &mut BTreeMap<FlatVariable, Variable>,
|
||||
symbols: &mut BTreeMap<Variable, ArkVariable>,
|
||||
witness: &mut Witness<T>,
|
||||
) -> LinearCombination<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr> {
|
||||
l.0.into_iter()
|
||||
|
@ -72,23 +72,35 @@ fn ark_combination<T: Field + ArkFieldExtensions>(
|
|||
.fold(LinearCombination::zero(), |acc, e| acc + e)
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>> ProgIterator<T, I> {
|
||||
pub fn generate_constraints(
|
||||
impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>> Computation<T, I> {
|
||||
pub fn public_inputs_values(&self) -> Vec<<T::ArkEngine as PairingEngine>::Fr> {
|
||||
self.program
|
||||
.public_inputs(self.witness.as_ref().unwrap())
|
||||
.iter()
|
||||
.map(|v| v.clone().into_ark())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>>
|
||||
ConstraintSynthesizer<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>
|
||||
for Computation<T, I>
|
||||
{
|
||||
fn generate_constraints(
|
||||
self,
|
||||
cs: ConstraintSystemRef<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
|
||||
witness: Option<Witness<T>>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
// mapping from IR variables
|
||||
let mut symbols = BTreeMap::new();
|
||||
|
||||
let mut witness = witness.unwrap_or_else(Witness::empty);
|
||||
let mut witness = self.witness.unwrap_or_else(Witness::empty);
|
||||
|
||||
assert!(symbols.insert(FlatVariable::one(), ConstraintSystem::<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::one()).is_none());
|
||||
assert!(symbols.insert(Variable::one(), ConstraintSystem::<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::one()).is_none());
|
||||
|
||||
match cs {
|
||||
ConstraintSystemRef::CS(rc) => {
|
||||
let mut cs = rc.borrow_mut();
|
||||
symbols.extend(self.arguments.iter().enumerate().map(|(_, p)| {
|
||||
symbols.extend(self.program.arguments.iter().enumerate().map(|(_, p)| {
|
||||
let wire = match p.private {
|
||||
true => cs.new_witness_variable(|| {
|
||||
Ok(witness
|
||||
|
@ -109,7 +121,7 @@ impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>> ProgIt
|
|||
(p.id, wire)
|
||||
}));
|
||||
|
||||
for statement in self.statements {
|
||||
for statement in self.program.statements {
|
||||
if let Statement::Constraint(quad, lin, _) = statement {
|
||||
let a = ark_combination(
|
||||
quad.left.clone().into_canonical(),
|
||||
|
@ -141,32 +153,11 @@ impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>> ProgIt
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>> Computation<T, I> {
|
||||
pub fn public_inputs_values(&self) -> Vec<<T::ArkEngine as PairingEngine>::Fr> {
|
||||
self.program
|
||||
.public_inputs(self.witness.as_ref().unwrap())
|
||||
.iter()
|
||||
.map(|v| v.clone().into_ark())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Field + ArkFieldExtensions, I: IntoIterator<Item = Statement<T>>>
|
||||
ConstraintSynthesizer<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>
|
||||
for Computation<T, I>
|
||||
{
|
||||
fn generate_constraints(
|
||||
self,
|
||||
cs: ConstraintSystemRef<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
self.program.generate_constraints(cs, self.witness)
|
||||
}
|
||||
}
|
||||
|
||||
mod parse {
|
||||
use super::*;
|
||||
use crate::proof_system::{Fr, G1Affine, G2Affine, G2AffineFq};
|
||||
use ark_ff::ToBytes;
|
||||
use zokrates_field::G2Type;
|
||||
use zokrates_proof_systems::{Fr, G1Affine, G2Affine, G2AffineFq, G2AffineFq2};
|
||||
|
||||
pub fn parse_g1<T: Field + ArkFieldExtensions>(
|
||||
e: &<T::ArkEngine as PairingEngine>::G1Affine,
|
||||
|
@ -196,48 +187,46 @@ mod parse {
|
|||
e.write(&mut bytes).unwrap();
|
||||
|
||||
let length = bytes.len() - 1; // [x, y, infinity] - infinity
|
||||
let element_length = length / 4;
|
||||
|
||||
let mut elements = vec![];
|
||||
for i in 0..4 {
|
||||
let start = i * element_length;
|
||||
let end = start + element_length;
|
||||
let mut e = bytes[start..end].to_vec();
|
||||
e.reverse();
|
||||
elements.push(e);
|
||||
match T::G2_TYPE {
|
||||
G2Type::Fq2 => {
|
||||
let element_length = length / 4;
|
||||
|
||||
let mut elements = vec![];
|
||||
for i in 0..4 {
|
||||
let start = i * element_length;
|
||||
let end = start + element_length;
|
||||
let mut e = bytes[start..end].to_vec();
|
||||
e.reverse();
|
||||
elements.push(e);
|
||||
}
|
||||
|
||||
G2Affine::Fq2(G2AffineFq2(
|
||||
(
|
||||
format!("0x{}", hex::encode(&elements[0])),
|
||||
format!("0x{}", hex::encode(&elements[1])),
|
||||
),
|
||||
(
|
||||
format!("0x{}", hex::encode(&elements[2])),
|
||||
format!("0x{}", hex::encode(&elements[3])),
|
||||
),
|
||||
))
|
||||
}
|
||||
G2Type::Fq => {
|
||||
let element_length = length / 2;
|
||||
|
||||
let mut x = bytes[0..element_length].to_vec();
|
||||
let mut y = bytes[element_length..length].to_vec();
|
||||
|
||||
x.reverse();
|
||||
y.reverse();
|
||||
|
||||
G2Affine::Fq(G2AffineFq(
|
||||
format!("0x{}", hex::encode(&x)),
|
||||
format!("0x{}", hex::encode(&y)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
G2Affine(
|
||||
(
|
||||
format!("0x{}", hex::encode(&elements[0])),
|
||||
format!("0x{}", hex::encode(&elements[1])),
|
||||
),
|
||||
(
|
||||
format!("0x{}", hex::encode(&elements[2])),
|
||||
format!("0x{}", hex::encode(&elements[3])),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_g2_fq<T: ArkFieldExtensions>(
|
||||
e: &<T::ArkEngine as PairingEngine>::G2Affine,
|
||||
) -> G2AffineFq {
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
e.write(&mut bytes).unwrap();
|
||||
|
||||
let length = bytes.len() - 1; // [x, y, infinity] - infinity
|
||||
let element_length = length / 2;
|
||||
|
||||
let mut x = bytes[0..element_length].to_vec();
|
||||
let mut y = bytes[element_length..length].to_vec();
|
||||
|
||||
x.reverse();
|
||||
y.reverse();
|
||||
|
||||
G2AffineFq(
|
||||
format!("0x{}", hex::encode(&x)),
|
||||
format!("0x{}", hex::encode(&y)),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_fr<T: ArkFieldExtensions>(e: &<T::ArkEngine as PairingEngine>::Fr) -> Fr {
|
||||
|
@ -250,10 +239,10 @@ mod parse {
|
|||
}
|
||||
|
||||
pub mod serialization {
|
||||
use crate::proof_system::{G1Affine, G2Affine, G2AffineFq};
|
||||
use ark_ec::PairingEngine;
|
||||
use ark_ff::FromBytes;
|
||||
use zokrates_field::ArkFieldExtensions;
|
||||
use zokrates_proof_systems::{G1Affine, G2Affine};
|
||||
|
||||
#[inline]
|
||||
fn decode_hex(value: String) -> Vec<u8> {
|
||||
|
@ -273,22 +262,21 @@ pub mod serialization {
|
|||
|
||||
pub fn to_g2<T: ArkFieldExtensions>(g2: G2Affine) -> <T::ArkEngine as PairingEngine>::G2Affine {
|
||||
let mut bytes = vec![];
|
||||
bytes.append(&mut decode_hex((g2.0).0));
|
||||
bytes.append(&mut decode_hex((g2.0).1));
|
||||
bytes.append(&mut decode_hex((g2.1).0));
|
||||
bytes.append(&mut decode_hex((g2.1).1));
|
||||
bytes.push(0u8); // infinity flag
|
||||
|
||||
<T::ArkEngine as PairingEngine>::G2Affine::read(&*bytes).unwrap()
|
||||
}
|
||||
|
||||
pub fn to_g2_fq<T: ArkFieldExtensions>(
|
||||
g2: G2AffineFq,
|
||||
) -> <T::ArkEngine as PairingEngine>::G2Affine {
|
||||
let mut bytes = vec![];
|
||||
bytes.append(&mut decode_hex(g2.0));
|
||||
bytes.append(&mut decode_hex(g2.1));
|
||||
bytes.push(0u8); // infinity flag
|
||||
match g2 {
|
||||
G2Affine::Fq(g2) => {
|
||||
bytes.append(&mut decode_hex(g2.0));
|
||||
bytes.append(&mut decode_hex(g2.1));
|
||||
bytes.push(0u8); // infinity flag
|
||||
}
|
||||
G2Affine::Fq2(g2) => {
|
||||
bytes.append(&mut decode_hex((g2.0).0));
|
||||
bytes.append(&mut decode_hex((g2.0).1));
|
||||
bytes.append(&mut decode_hex((g2.1).0));
|
||||
bytes.append(&mut decode_hex((g2.1).1));
|
||||
bytes.push(0u8); // infinity flag
|
||||
}
|
||||
};
|
||||
|
||||
<T::ArkEngine as PairingEngine>::G2Affine::read(&*bytes).unwrap()
|
||||
}
|
|
@ -23,13 +23,13 @@ use std::marker::PhantomData;
|
|||
|
||||
use zokrates_field::{ArkFieldExtensions, Field};
|
||||
|
||||
use crate::ir::{ProgIterator, Statement, Witness};
|
||||
use crate::proof_system::ark::Ark;
|
||||
use crate::proof_system::ark::Computation;
|
||||
use crate::proof_system::ark::{parse_fr, parse_g1, parse_g2, serialization};
|
||||
use crate::proof_system::marlin::{self, KZGVerifierKey, ProofPoints, VerificationKey};
|
||||
use crate::proof_system::Scheme;
|
||||
use crate::proof_system::{Backend, Proof, SetupKeypair, UniversalBackend};
|
||||
use crate::Ark;
|
||||
use crate::Computation;
|
||||
use crate::{parse_fr, parse_g1, parse_g2, serialization};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::marlin::{self, KZGVerifierKey, ProofPoints, VerificationKey};
|
||||
use zokrates_proof_systems::Scheme;
|
||||
use zokrates_proof_systems::{Backend, Proof, SetupKeypair, UniversalBackend};
|
||||
|
||||
const MINIMUM_CONSTRAINT_COUNT: usize = 2;
|
||||
|
||||
|
@ -386,27 +386,28 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::flat_absy::{FlatParameter, FlatVariable};
|
||||
use crate::ir::{Interpreter, Prog, QuadComb, Statement};
|
||||
use zokrates_ast::flat::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, QuadComb, Statement};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
use super::*;
|
||||
use crate::proof_system::scheme::Marlin;
|
||||
use zokrates_field::{Bls12_377Field, Bw6_761Field};
|
||||
use zokrates_proof_systems::Marlin;
|
||||
|
||||
#[test]
|
||||
fn verify_bls12_377_field() {
|
||||
let program: Prog<Bls12_377Field> = Prog {
|
||||
arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::private(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
),
|
||||
FlatVariable::new(1),
|
||||
Variable::new(1),
|
||||
),
|
||||
Statement::constraint(FlatVariable::new(1), FlatVariable::public(0)),
|
||||
Statement::constraint(Variable::new(1), Variable::public(0)),
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -429,17 +430,17 @@ mod tests {
|
|||
#[test]
|
||||
fn verify_bw6_761_field() {
|
||||
let program: Prog<Bw6_761Field> = Prog {
|
||||
arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::private(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
),
|
||||
FlatVariable::new(1),
|
||||
Variable::new(1),
|
||||
),
|
||||
Statement::constraint(FlatVariable::new(1), FlatVariable::public(0)),
|
||||
Statement::constraint(Variable::new(1), Variable::public(0)),
|
||||
],
|
||||
};
|
||||
|
26
zokrates_ast/Cargo.toml
Normal file
26
zokrates_ast/Cargo.toml
Normal file
|
@ -0,0 +1,26 @@
|
|||
[package]
|
||||
name = "zokrates_ast"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = ["bellman", "ark"]
|
||||
bellman = ["zokrates_field/bellman", "pairing_ce", "zokrates_embed/bellman"]
|
||||
ark = ["ark-bls12-377", "zokrates_embed/ark"]
|
||||
|
||||
[dependencies]
|
||||
zokrates_pest_ast = { version = "0.2.0", path = "../zokrates_pest_ast" }
|
||||
cfg-if = "0.1"
|
||||
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
csv = "1"
|
||||
serde_cbor = "0.11.2"
|
||||
num-bigint = { version = "0.2", default-features = false }
|
||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
zokrates_embed = { version = "0.1.0", path = "../zokrates_embed", default-features = false }
|
||||
pairing_ce = { version = "^0.21", optional = true }
|
||||
ark-bls12-377 = { version = "^0.3.0", features = ["curve"], default-features = false, optional = true }
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
use crate::absy::{
|
||||
types::{UnresolvedSignature, UnresolvedType},
|
||||
ConstantGenericNode, Expression,
|
||||
};
|
||||
use crate::flat_absy::{
|
||||
FlatDirective, FlatExpression, FlatFunctionIterator, FlatParameter, FlatStatement,
|
||||
FlatVariable, RuntimeError,
|
||||
};
|
||||
use crate::solvers::Solver;
|
||||
use crate::typed_absy::types::{
|
||||
use crate::common::{Parameter, RuntimeError, Solver, Variable};
|
||||
use crate::flat::{FlatDirective, FlatExpression, FlatFunctionIterator, FlatStatement};
|
||||
use crate::typed::types::{
|
||||
ConcreteGenericsAssignment, DeclarationConstant, DeclarationSignature, DeclarationType,
|
||||
GenericIdentifier,
|
||||
};
|
||||
use crate::untyped::{
|
||||
types::{UnresolvedSignature, UnresolvedType},
|
||||
ConstantGenericNode, Expression,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -321,7 +318,7 @@ fn flat_expression_from_vec<T: Field>(v: &[(usize, T)]) -> FlatExpression<T> {
|
|||
let (key, val) = v[0].clone();
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(val),
|
||||
box FlatExpression::Identifier(FlatVariable::new(key)),
|
||||
box FlatExpression::Identifier(Variable::new(key)),
|
||||
)
|
||||
}
|
||||
n => {
|
||||
|
@ -380,14 +377,14 @@ pub fn sha256_round<T: Field>(
|
|||
.clone()
|
||||
.into_iter()
|
||||
.chain(current_hash_argument_indices.clone())
|
||||
.map(|i| FlatParameter {
|
||||
id: FlatVariable::new(i),
|
||||
.map(|i| Parameter {
|
||||
id: Variable::new(i),
|
||||
private: true,
|
||||
})
|
||||
.collect();
|
||||
// define a binding of the first variable in the constraint system to one
|
||||
let one_binding_statement = FlatStatement::Condition(
|
||||
FlatVariable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
FlatExpression::Number(T::from(1)),
|
||||
RuntimeError::BellmanOneBinding,
|
||||
);
|
||||
|
@ -395,8 +392,8 @@ pub fn sha256_round<T: Field>(
|
|||
// bind input and current_hash to inputs
|
||||
input_indices.chain(current_hash_indices).zip(input_argument_indices.clone().into_iter().chain(current_hash_argument_indices.clone())).map(|(cs_index, argument_index)| {
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(cs_index).into(),
|
||||
FlatVariable::new(argument_index).into(),
|
||||
Variable::new(cs_index).into(),
|
||||
Variable::new(argument_index).into(),
|
||||
RuntimeError::BellmanInputBinding
|
||||
)
|
||||
});
|
||||
|
@ -415,14 +412,14 @@ pub fn sha256_round<T: Field>(
|
|||
});
|
||||
|
||||
// define which subset of the witness is returned
|
||||
let outputs = output_indices.map(|o| FlatExpression::Identifier(FlatVariable::new(o)));
|
||||
let outputs = output_indices.map(|o| FlatExpression::Identifier(Variable::new(o)));
|
||||
// insert a directive to set the witness based on the bellman gadget and inputs
|
||||
let directive_statement = FlatStatement::Directive(FlatDirective {
|
||||
outputs: cs_indices.map(FlatVariable::new).collect(),
|
||||
outputs: cs_indices.map(Variable::new).collect(),
|
||||
inputs: input_argument_indices
|
||||
.into_iter()
|
||||
.chain(current_hash_argument_indices)
|
||||
.map(|i| FlatVariable::new(i).into())
|
||||
.map(|i| Variable::new(i).into())
|
||||
.collect(),
|
||||
solver: Solver::Sha256Round,
|
||||
});
|
||||
|
@ -430,7 +427,7 @@ pub fn sha256_round<T: Field>(
|
|||
let return_statements = outputs
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, e)| FlatStatement::Definition(FlatVariable::public(index), e));
|
||||
.map(|(index, e)| FlatStatement::Definition(Variable::public(index), e));
|
||||
let statements = std::iter::once(directive_statement)
|
||||
.chain(std::iter::once(one_binding_statement))
|
||||
.chain(input_binding_statements)
|
||||
|
@ -468,15 +465,15 @@ pub fn snark_verify_bls12_377<T: Field>(
|
|||
|
||||
let input_arguments = input_argument_indices
|
||||
.clone()
|
||||
.map(|i| FlatParameter::private(FlatVariable::new(i)));
|
||||
.map(|i| Parameter::private(Variable::new(i)));
|
||||
|
||||
let proof_arguments = proof_argument_indices
|
||||
.clone()
|
||||
.map(|i| FlatParameter::private(FlatVariable::new(i)));
|
||||
.map(|i| Parameter::private(Variable::new(i)));
|
||||
|
||||
let vk_arguments = vk_argument_indices
|
||||
.clone()
|
||||
.map(|i| FlatParameter::private(FlatVariable::new(i)));
|
||||
.map(|i| Parameter::private(Variable::new(i)));
|
||||
|
||||
let arguments = input_arguments
|
||||
.chain(proof_arguments)
|
||||
|
@ -484,7 +481,7 @@ pub fn snark_verify_bls12_377<T: Field>(
|
|||
.collect();
|
||||
|
||||
let one_binding_statement = FlatStatement::Condition(
|
||||
FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
FlatExpression::Identifier(Variable::new(0)),
|
||||
FlatExpression::Number(T::from(1)),
|
||||
RuntimeError::ArkOneBinding,
|
||||
);
|
||||
|
@ -500,8 +497,8 @@ pub fn snark_verify_bls12_377<T: Field>(
|
|||
)
|
||||
.map(|(cs_index, argument_index)| {
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(cs_index).into(),
|
||||
FlatVariable::new(argument_index).into(),
|
||||
Variable::new(cs_index).into(),
|
||||
Variable::new(argument_index).into(),
|
||||
RuntimeError::ArkInputBinding,
|
||||
)
|
||||
})
|
||||
|
@ -524,17 +521,17 @@ pub fn snark_verify_bls12_377<T: Field>(
|
|||
.collect();
|
||||
|
||||
let return_statement = FlatStatement::Definition(
|
||||
FlatVariable::public(0),
|
||||
FlatExpression::Identifier(FlatVariable::new(out_index)),
|
||||
Variable::public(0),
|
||||
FlatExpression::Identifier(Variable::new(out_index)),
|
||||
);
|
||||
|
||||
// insert a directive to set the witness
|
||||
let directive_statement = FlatStatement::Directive(FlatDirective {
|
||||
outputs: cs_indices.map(FlatVariable::new).collect(),
|
||||
outputs: cs_indices.map(Variable::new).collect(),
|
||||
inputs: input_argument_indices
|
||||
.chain(proof_argument_indices)
|
||||
.chain(vk_argument_indices)
|
||||
.map(|i| FlatVariable::new(i).into())
|
||||
.map(|i| Variable::new(i).into())
|
||||
.collect(),
|
||||
solver: Solver::SnarkVerifyBls12377(n),
|
||||
});
|
||||
|
@ -553,11 +550,11 @@ pub fn snark_verify_bls12_377<T: Field>(
|
|||
}
|
||||
|
||||
fn use_variable(
|
||||
layout: &mut HashMap<String, FlatVariable>,
|
||||
layout: &mut HashMap<String, Variable>,
|
||||
name: String,
|
||||
index: &mut usize,
|
||||
) -> FlatVariable {
|
||||
let var = FlatVariable::new(*index);
|
||||
) -> Variable {
|
||||
let var = Variable::new(*index);
|
||||
layout.insert(name, var);
|
||||
*index += 1;
|
||||
var
|
||||
|
@ -578,8 +575,8 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
|
||||
let mut layout = HashMap::new();
|
||||
|
||||
let arguments = vec![FlatParameter {
|
||||
id: FlatVariable::new(0),
|
||||
let arguments = vec![Parameter {
|
||||
id: Variable::new(0),
|
||||
private: true,
|
||||
}];
|
||||
|
||||
|
@ -591,7 +588,7 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
&mut counter,
|
||||
))];
|
||||
|
||||
let directive_outputs: Vec<FlatVariable> = (0..bit_width)
|
||||
let directive_outputs: Vec<Variable> = (0..bit_width)
|
||||
.map(|index| use_variable(&mut layout, format!("o{}", index), &mut counter))
|
||||
.collect();
|
||||
|
||||
|
@ -607,7 +604,7 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
// o253, o252, ... o{253 - (bit_width - 1)} are bits
|
||||
let mut statements: Vec<FlatStatement<T>> = (0..bit_width)
|
||||
.map(|index| {
|
||||
let bit = FlatExpression::Identifier(FlatVariable::new(bit_width - index));
|
||||
let bit = FlatExpression::Identifier(Variable::new(bit_width - index));
|
||||
FlatStatement::Condition(
|
||||
bit.clone(),
|
||||
FlatExpression::Mult(box bit.clone(), box bit.clone()),
|
||||
|
@ -623,7 +620,7 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
lhs_sum = FlatExpression::Add(
|
||||
box lhs_sum,
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(FlatVariable::new(bit_width - i)),
|
||||
box FlatExpression::Identifier(Variable::new(bit_width - i)),
|
||||
box FlatExpression::Number(T::from(2).pow(i)),
|
||||
),
|
||||
);
|
||||
|
@ -632,7 +629,7 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
statements.push(FlatStatement::Condition(
|
||||
lhs_sum,
|
||||
FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(FlatVariable::new(0)),
|
||||
box FlatExpression::Identifier(Variable::new(0)),
|
||||
box FlatExpression::Number(T::from(1)),
|
||||
),
|
||||
RuntimeError::Sum,
|
||||
|
@ -651,7 +648,7 @@ pub fn unpack_to_bitwidth<T: Field>(
|
|||
outputs
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, e)| FlatStatement::Definition(FlatVariable::public(index), e)),
|
||||
.map(|(index, e)| FlatStatement::Definition(Variable::public(index), e)),
|
||||
);
|
||||
|
||||
FlatFunctionIterator {
|
||||
|
@ -675,18 +672,15 @@ mod tests {
|
|||
let unpack =
|
||||
unpack_to_bitwidth::<Bn128Field>(Bn128Field::get_required_bits()).collect();
|
||||
|
||||
assert_eq!(
|
||||
unpack.arguments,
|
||||
vec![FlatParameter::private(FlatVariable::new(0))]
|
||||
);
|
||||
assert_eq!(unpack.arguments, vec![Parameter::private(Variable::new(0))]);
|
||||
assert_eq!(
|
||||
unpack.statements[0],
|
||||
FlatStatement::Directive(FlatDirective::new(
|
||||
(0..Bn128Field::get_required_bits())
|
||||
.map(|i| FlatVariable::new(i + 1))
|
||||
.map(|i| Variable::new(i + 1))
|
||||
.collect(),
|
||||
Solver::bits(Bn128Field::get_required_bits()),
|
||||
vec![FlatVariable::new(0)]
|
||||
vec![Variable::new(0)]
|
||||
))
|
||||
);
|
||||
assert_eq!(
|
||||
|
@ -700,7 +694,6 @@ mod tests {
|
|||
#[cfg(test)]
|
||||
mod sha256 {
|
||||
use super::*;
|
||||
use crate::ir::Interpreter;
|
||||
|
||||
#[test]
|
||||
fn generate_sha256_constraints() {
|
||||
|
@ -729,14 +722,14 @@ mod tests {
|
|||
// function input should be offset by variable_count
|
||||
assert_eq!(
|
||||
compiled.arguments[0].id,
|
||||
FlatVariable::new(directive.outputs.len() + 1)
|
||||
Variable::new(directive.outputs.len() + 1)
|
||||
);
|
||||
|
||||
// bellman variable #0: index 0 should equal 1
|
||||
assert_eq!(
|
||||
compiled.statements[1],
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(0).into(),
|
||||
Variable::new(0).into(),
|
||||
FlatExpression::Number(Bn128Field::from(1)),
|
||||
RuntimeError::BellmanOneBinding
|
||||
)
|
||||
|
@ -746,22 +739,11 @@ mod tests {
|
|||
assert_eq!(
|
||||
compiled.statements[2],
|
||||
FlatStatement::Condition(
|
||||
FlatVariable::new(1).into(),
|
||||
FlatVariable::new(26936).into(),
|
||||
Variable::new(1).into(),
|
||||
Variable::new(26936).into(),
|
||||
RuntimeError::BellmanInputBinding
|
||||
)
|
||||
);
|
||||
|
||||
let input: Vec<_> = (0..512)
|
||||
.map(|_| 0)
|
||||
.chain((0..256).map(|_| 1))
|
||||
.map(Bn128Field::from)
|
||||
.collect();
|
||||
|
||||
let ir = crate::ir::from_flat::from_flat(compiled);
|
||||
|
||||
let interpreter = Interpreter::default();
|
||||
interpreter.execute(ir, &input).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
91
zokrates_ast/src/common/error.rs
Normal file
91
zokrates_ast/src/common/error.rs
Normal file
|
@ -0,0 +1,91 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
|
||||
pub enum RuntimeError {
|
||||
BellmanConstraint,
|
||||
BellmanOneBinding,
|
||||
BellmanInputBinding,
|
||||
ArkConstraint,
|
||||
ArkOneBinding,
|
||||
ArkInputBinding,
|
||||
Bitness,
|
||||
Sum,
|
||||
Equal,
|
||||
Le,
|
||||
BranchIsolation,
|
||||
ConstantLtBitness,
|
||||
ConstantLtSum,
|
||||
LtBitness,
|
||||
LtSum,
|
||||
LtFinalBitness,
|
||||
LtFinalSum,
|
||||
LtSymetric,
|
||||
Or,
|
||||
Xor,
|
||||
Inverse,
|
||||
Euclidean,
|
||||
ShaXor,
|
||||
Division,
|
||||
SourceAssertion(String),
|
||||
ArgumentBitness,
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
||||
impl From<crate::zir::RuntimeError> for RuntimeError {
|
||||
fn from(error: crate::zir::RuntimeError) -> Self {
|
||||
match error {
|
||||
crate::zir::RuntimeError::SourceAssertion(s) => RuntimeError::SourceAssertion(s),
|
||||
crate::zir::RuntimeError::SelectRangeCheck => RuntimeError::SelectRangeCheck,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
pub fn is_malicious(&self) -> bool {
|
||||
use RuntimeError::*;
|
||||
|
||||
!matches!(
|
||||
self,
|
||||
SourceAssertion(_) | Inverse | LtSum | SelectRangeCheck | ArgumentBitness
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use RuntimeError::*;
|
||||
|
||||
let msg = match self {
|
||||
BellmanConstraint => "Bellman constraint is unsatisfied",
|
||||
BellmanOneBinding => "Bellman ~one binding is unsatisfied",
|
||||
BellmanInputBinding => "Bellman input binding is unsatisfied",
|
||||
ArkConstraint => "Ark constraint is unsatisfied",
|
||||
ArkOneBinding => "Ark ~one binding is unsatisfied",
|
||||
ArkInputBinding => "Ark input binding is unsatisfied",
|
||||
Bitness => "Bitness check failed",
|
||||
Sum => "Sum check failed",
|
||||
Equal => "Equal check failed",
|
||||
Le => "Constant Le check failed",
|
||||
BranchIsolation => "Branch isolation failed",
|
||||
ConstantLtBitness => "Bitness check failed in constant Lt check",
|
||||
ConstantLtSum => "Sum check failed in constant Lt check",
|
||||
LtBitness => "Bitness check failed in Lt check",
|
||||
LtSum => "Sum check failed in Lt check",
|
||||
LtFinalBitness => "Bitness check failed in final Lt check",
|
||||
LtFinalSum => "Sum check failed in final Lt check",
|
||||
LtSymetric => "Symetrical check failed in Lt check",
|
||||
Or => "Or check failed",
|
||||
Xor => "Xor check failed",
|
||||
Inverse => "Division by zero",
|
||||
Euclidean => "Euclidean check failed",
|
||||
ShaXor => "Internal Sha check failed",
|
||||
Division => "Division check failed",
|
||||
SourceAssertion(m) => m.as_str(),
|
||||
ArgumentBitness => "Argument bitness check failed",
|
||||
SelectRangeCheck => "Out of bounds array access",
|
||||
};
|
||||
|
||||
write!(f, "{}", msg)
|
||||
}
|
||||
}
|
11
zokrates_ast/src/common/mod.rs
Normal file
11
zokrates_ast/src/common/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
pub mod embed;
|
||||
mod error;
|
||||
mod parameter;
|
||||
mod solvers;
|
||||
mod variable;
|
||||
|
||||
pub use self::embed::FlatEmbed;
|
||||
pub use self::error::RuntimeError;
|
||||
pub use self::parameter::Parameter;
|
||||
pub use self::solvers::Solver;
|
||||
pub use self::variable::Variable;
|
|
@ -1,47 +1,44 @@
|
|||
use crate::flat_absy::flat_variable::FlatVariable;
|
||||
use super::variable::Variable;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Serialize, Deserialize, Hash, Eq, PartialEq, Clone, Copy)]
|
||||
pub struct FlatParameter {
|
||||
pub id: FlatVariable,
|
||||
pub struct Parameter {
|
||||
pub id: Variable,
|
||||
pub private: bool,
|
||||
}
|
||||
|
||||
impl FlatParameter {
|
||||
fn new(id: FlatVariable, private: bool) -> Self {
|
||||
FlatParameter { id, private }
|
||||
impl Parameter {
|
||||
fn new(id: Variable, private: bool) -> Self {
|
||||
Parameter { id, private }
|
||||
}
|
||||
|
||||
pub fn public(v: FlatVariable) -> Self {
|
||||
pub fn public(v: Variable) -> Self {
|
||||
Self::new(v, false)
|
||||
}
|
||||
|
||||
pub fn private(v: FlatVariable) -> Self {
|
||||
pub fn private(v: Variable) -> Self {
|
||||
Self::new(v, true)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FlatParameter {
|
||||
impl fmt::Display for Parameter {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let visibility = if self.private { "private " } else { "" };
|
||||
write!(f, "{}{}", visibility, self.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FlatParameter {
|
||||
impl fmt::Debug for Parameter {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "FlatParameter(id: {:?})", self.id)
|
||||
write!(f, "Parameter(id: {:?})", self.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl FlatParameter {
|
||||
pub fn apply_substitution(
|
||||
self,
|
||||
substitution: &HashMap<FlatVariable, FlatVariable>,
|
||||
) -> FlatParameter {
|
||||
FlatParameter {
|
||||
impl Parameter {
|
||||
pub fn apply_substitution(self, substitution: &HashMap<Variable, Variable>) -> Parameter {
|
||||
Parameter {
|
||||
id: *substitution.get(&self.id).unwrap(),
|
||||
private: self.private,
|
||||
}
|
|
@ -7,23 +7,23 @@ use std::fmt;
|
|||
// id == 0 for ~one
|
||||
// id < 0 for public outputs
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Hash, Eq, Ord, PartialOrd, Copy)]
|
||||
pub struct FlatVariable {
|
||||
pub struct Variable {
|
||||
id: isize,
|
||||
}
|
||||
|
||||
impl FlatVariable {
|
||||
impl Variable {
|
||||
pub fn new(id: usize) -> Self {
|
||||
FlatVariable {
|
||||
Variable {
|
||||
id: 1 + id as isize,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn one() -> Self {
|
||||
FlatVariable { id: 0 }
|
||||
Variable { id: 0 }
|
||||
}
|
||||
|
||||
pub fn public(id: usize) -> Self {
|
||||
FlatVariable {
|
||||
Variable {
|
||||
id: -(id as isize) - 1,
|
||||
}
|
||||
}
|
||||
|
@ -35,21 +35,21 @@ impl FlatVariable {
|
|||
|
||||
pub fn try_from_human_readable(s: &str) -> Result<Self, &str> {
|
||||
if s == "~one" {
|
||||
return Ok(FlatVariable::one());
|
||||
return Ok(Variable::one());
|
||||
}
|
||||
|
||||
let mut public = s.split("~out_");
|
||||
match public.nth(1) {
|
||||
Some(v) => {
|
||||
let v = v.parse().map_err(|_| s)?;
|
||||
Ok(FlatVariable::public(v))
|
||||
Ok(Variable::public(v))
|
||||
}
|
||||
None => {
|
||||
let mut private = s.split('_');
|
||||
match private.nth(1) {
|
||||
Some(v) => {
|
||||
let v = v.parse().map_err(|_| s)?;
|
||||
Ok(FlatVariable::new(v))
|
||||
Ok(Variable::new(v))
|
||||
}
|
||||
None => Err(s),
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ impl FlatVariable {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FlatVariable {
|
||||
impl fmt::Display for Variable {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.id {
|
||||
0 => write!(f, "~one"),
|
||||
|
@ -68,7 +68,7 @@ impl fmt::Display for FlatVariable {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FlatVariable {
|
||||
impl fmt::Debug for Variable {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.id {
|
||||
0 => write!(f, "~one"),
|
||||
|
@ -78,8 +78,8 @@ impl fmt::Debug for FlatVariable {
|
|||
}
|
||||
}
|
||||
|
||||
impl FlatVariable {
|
||||
pub fn apply_substitution(self, substitution: &HashMap<FlatVariable, FlatVariable>) -> &Self {
|
||||
impl Variable {
|
||||
pub fn apply_substitution(self, substitution: &HashMap<Variable, Variable>) -> &Self {
|
||||
substitution.get(&self).unwrap()
|
||||
}
|
||||
|
||||
|
@ -94,18 +94,18 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn one() {
|
||||
assert_eq!(format!("{}", FlatVariable::one()), "~one");
|
||||
assert_eq!(format!("{}", Variable::one()), "~one");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn public() {
|
||||
assert_eq!(format!("{}", FlatVariable::public(0)), "~out_0");
|
||||
assert_eq!(format!("{}", FlatVariable::public(42)), "~out_42");
|
||||
assert_eq!(format!("{}", Variable::public(0)), "~out_0");
|
||||
assert_eq!(format!("{}", Variable::public(42)), "~out_42");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private() {
|
||||
assert_eq!(format!("{}", FlatVariable::new(0)), "_0");
|
||||
assert_eq!(format!("{}", FlatVariable::new(42)), "_42");
|
||||
assert_eq!(format!("{}", Variable::new(0)), "_0");
|
||||
assert_eq!(format!("{}", Variable::new(42)), "_42");
|
||||
}
|
||||
}
|
107
zokrates_ast/src/flat/folder.rs
Normal file
107
zokrates_ast/src/flat/folder.rs
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Generic walk through an IR AST. Not mutating in place
|
||||
|
||||
use super::*;
|
||||
use crate::common::Variable;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait Folder<T: Field>: Sized {
|
||||
fn fold_program(&mut self, p: FlatProg<T>) -> FlatProg<T> {
|
||||
fold_program(self, p)
|
||||
}
|
||||
|
||||
fn fold_argument(&mut self, p: Parameter) -> Parameter {
|
||||
fold_argument(self, p)
|
||||
}
|
||||
|
||||
fn fold_variable(&mut self, v: Variable) -> Variable {
|
||||
fold_variable(self, v)
|
||||
}
|
||||
|
||||
fn fold_statement(&mut self, s: FlatStatement<T>) -> Vec<FlatStatement<T>> {
|
||||
fold_statement(self, s)
|
||||
}
|
||||
|
||||
fn fold_expression(&mut self, e: FlatExpression<T>) -> FlatExpression<T> {
|
||||
fold_expression(self, e)
|
||||
}
|
||||
|
||||
fn fold_directive(&mut self, d: FlatDirective<T>) -> FlatDirective<T> {
|
||||
fold_directive(self, d)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_program<T: Field, F: Folder<T>>(f: &mut F, p: FlatProg<T>) -> FlatProg<T> {
|
||||
FlatProg {
|
||||
arguments: p
|
||||
.arguments
|
||||
.into_iter()
|
||||
.map(|a| f.fold_argument(a))
|
||||
.collect(),
|
||||
statements: p
|
||||
.statements
|
||||
.into_iter()
|
||||
.flat_map(|s| f.fold_statement(s))
|
||||
.collect(),
|
||||
return_count: p.return_count,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_statement<T: Field, F: Folder<T>>(
|
||||
f: &mut F,
|
||||
s: FlatStatement<T>,
|
||||
) -> Vec<FlatStatement<T>> {
|
||||
match s {
|
||||
FlatStatement::Condition(left, right, error) => vec![FlatStatement::Condition(
|
||||
f.fold_expression(left),
|
||||
f.fold_expression(right),
|
||||
error,
|
||||
)],
|
||||
FlatStatement::Definition(v, e) => vec![FlatStatement::Definition(
|
||||
f.fold_variable(v),
|
||||
f.fold_expression(e),
|
||||
)],
|
||||
FlatStatement::Directive(d) => vec![FlatStatement::Directive(f.fold_directive(d))],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_expression<T: Field, F: Folder<T>>(
|
||||
f: &mut F,
|
||||
e: FlatExpression<T>,
|
||||
) -> FlatExpression<T> {
|
||||
match e {
|
||||
FlatExpression::Number(n) => FlatExpression::Number(n),
|
||||
FlatExpression::Identifier(id) => FlatExpression::Identifier(f.fold_variable(id)),
|
||||
FlatExpression::Add(box left, box right) => {
|
||||
FlatExpression::Add(box f.fold_expression(left), box f.fold_expression(right))
|
||||
}
|
||||
FlatExpression::Sub(box left, box right) => {
|
||||
FlatExpression::Sub(box f.fold_expression(left), box f.fold_expression(right))
|
||||
}
|
||||
FlatExpression::Mult(box left, box right) => {
|
||||
FlatExpression::Mult(box f.fold_expression(left), box f.fold_expression(right))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_directive<T: Field, F: Folder<T>>(f: &mut F, ds: FlatDirective<T>) -> FlatDirective<T> {
|
||||
FlatDirective {
|
||||
inputs: ds
|
||||
.inputs
|
||||
.into_iter()
|
||||
.map(|e| f.fold_expression(e))
|
||||
.collect(),
|
||||
outputs: ds.outputs.into_iter().map(|o| f.fold_variable(o)).collect(),
|
||||
..ds
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_argument<T: Field, F: Folder<T>>(f: &mut F, a: Parameter) -> Parameter {
|
||||
Parameter {
|
||||
id: f.fold_variable(a.id),
|
||||
private: a.private,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_variable<T: Field, F: Folder<T>>(_f: &mut F, v: Variable) -> Variable {
|
||||
v
|
||||
}
|
|
@ -5,99 +5,17 @@
|
|||
//! @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>
|
||||
//! @date 2017
|
||||
|
||||
pub mod flat_parameter;
|
||||
pub mod flat_variable;
|
||||
pub mod folder;
|
||||
|
||||
pub use self::flat_parameter::FlatParameter;
|
||||
pub use self::flat_variable::FlatVariable;
|
||||
pub use crate::common::Parameter;
|
||||
pub use crate::common::RuntimeError;
|
||||
pub use crate::common::Variable;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::solvers::Solver;
|
||||
use crate::common::Solver;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use zokrates_field::Field;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
|
||||
pub enum RuntimeError {
|
||||
BellmanConstraint,
|
||||
BellmanOneBinding,
|
||||
BellmanInputBinding,
|
||||
ArkConstraint,
|
||||
ArkOneBinding,
|
||||
ArkInputBinding,
|
||||
Bitness,
|
||||
Sum,
|
||||
Equal,
|
||||
Le,
|
||||
BranchIsolation,
|
||||
ConstantLtBitness,
|
||||
ConstantLtSum,
|
||||
LtBitness,
|
||||
LtSum,
|
||||
LtFinalBitness,
|
||||
LtFinalSum,
|
||||
LtSymetric,
|
||||
Or,
|
||||
Xor,
|
||||
Inverse,
|
||||
Euclidean,
|
||||
ShaXor,
|
||||
Division,
|
||||
SourceAssertion(String),
|
||||
ArgumentBitness,
|
||||
SelectRangeCheck,
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
pub(crate) fn is_malicious(&self) -> bool {
|
||||
use RuntimeError::*;
|
||||
|
||||
!matches!(
|
||||
self,
|
||||
SourceAssertion(_) | Inverse | LtSum | SelectRangeCheck | ArgumentBitness
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use RuntimeError::*;
|
||||
|
||||
let msg = match self {
|
||||
BellmanConstraint => "Bellman constraint is unsatisfied",
|
||||
BellmanOneBinding => "Bellman ~one binding is unsatisfied",
|
||||
BellmanInputBinding => "Bellman input binding is unsatisfied",
|
||||
ArkConstraint => "Ark constraint is unsatisfied",
|
||||
ArkOneBinding => "Ark ~one binding is unsatisfied",
|
||||
ArkInputBinding => "Ark input binding is unsatisfied",
|
||||
Bitness => "Bitness check failed",
|
||||
Sum => "Sum check failed",
|
||||
Equal => "Equal check failed",
|
||||
Le => "Constant Le check failed",
|
||||
BranchIsolation => "Branch isolation failed",
|
||||
ConstantLtBitness => "Bitness check failed in constant Lt check",
|
||||
ConstantLtSum => "Sum check failed in constant Lt check",
|
||||
LtBitness => "Bitness check failed in Lt check",
|
||||
LtSum => "Sum check failed in Lt check",
|
||||
LtFinalBitness => "Bitness check failed in final Lt check",
|
||||
LtFinalSum => "Sum check failed in final Lt check",
|
||||
LtSymetric => "Symetrical check failed in Lt check",
|
||||
Or => "Or check failed",
|
||||
Xor => "Xor check failed",
|
||||
Inverse => "Division by zero",
|
||||
Euclidean => "Euclidean check failed",
|
||||
ShaXor => "Internal Sha check failed",
|
||||
Division => "Division check failed",
|
||||
SourceAssertion(m) => m.as_str(),
|
||||
ArgumentBitness => "Argument bitness check failed",
|
||||
SelectRangeCheck => "Out of bounds array access",
|
||||
};
|
||||
|
||||
write!(f, "{}", msg)
|
||||
}
|
||||
}
|
||||
|
||||
pub type FlatProg<T> = FlatFunction<T>;
|
||||
|
||||
pub type FlatFunction<T> = FlatFunctionIterator<T, Vec<FlatStatement<T>>>;
|
||||
|
@ -107,7 +25,7 @@ pub type FlatProgIterator<T, I> = FlatFunctionIterator<T, I>;
|
|||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub struct FlatFunctionIterator<T, I: IntoIterator<Item = FlatStatement<T>>> {
|
||||
/// Arguments of the function
|
||||
pub arguments: Vec<FlatParameter>,
|
||||
pub arguments: Vec<Parameter>,
|
||||
/// Vector of statements that are executed when running the function
|
||||
pub statements: I,
|
||||
/// Number of outputs
|
||||
|
@ -157,7 +75,7 @@ impl<T: Field> fmt::Display for FlatFunction<T> {
|
|||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub enum FlatStatement<T> {
|
||||
Condition(FlatExpression<T>, FlatExpression<T>, RuntimeError),
|
||||
Definition(FlatVariable, FlatExpression<T>),
|
||||
Definition(Variable, FlatExpression<T>),
|
||||
Directive(FlatDirective<T>),
|
||||
}
|
||||
|
||||
|
@ -176,7 +94,7 @@ impl<T: Field> fmt::Display for FlatStatement<T> {
|
|||
impl<T: Field> FlatStatement<T> {
|
||||
pub fn apply_substitution(
|
||||
self,
|
||||
substitution: &HashMap<FlatVariable, FlatVariable>,
|
||||
substitution: &HashMap<Variable, Variable>,
|
||||
) -> FlatStatement<T> {
|
||||
match self {
|
||||
FlatStatement::Definition(id, x) => FlatStatement::Definition(
|
||||
|
@ -213,13 +131,13 @@ impl<T: Field> FlatStatement<T> {
|
|||
#[derive(Clone, Hash, Debug, PartialEq, Eq)]
|
||||
pub struct FlatDirective<T> {
|
||||
pub inputs: Vec<FlatExpression<T>>,
|
||||
pub outputs: Vec<FlatVariable>,
|
||||
pub outputs: Vec<Variable>,
|
||||
pub solver: Solver,
|
||||
}
|
||||
|
||||
impl<T> FlatDirective<T> {
|
||||
pub fn new<E: Into<FlatExpression<T>>>(
|
||||
outputs: Vec<FlatVariable>,
|
||||
outputs: Vec<Variable>,
|
||||
solver: Solver,
|
||||
inputs: Vec<E>,
|
||||
) -> Self {
|
||||
|
@ -257,7 +175,7 @@ impl<T: Field> fmt::Display for FlatDirective<T> {
|
|||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum FlatExpression<T> {
|
||||
Number(T),
|
||||
Identifier(FlatVariable),
|
||||
Identifier(Variable),
|
||||
Add(Box<FlatExpression<T>>, Box<FlatExpression<T>>),
|
||||
Sub(Box<FlatExpression<T>>, Box<FlatExpression<T>>),
|
||||
Mult(Box<FlatExpression<T>>, Box<FlatExpression<T>>),
|
||||
|
@ -272,7 +190,7 @@ impl<T> From<T> for FlatExpression<T> {
|
|||
impl<T: Field> FlatExpression<T> {
|
||||
pub fn apply_substitution(
|
||||
self,
|
||||
substitution: &HashMap<FlatVariable, FlatVariable>,
|
||||
substitution: &HashMap<Variable, Variable>,
|
||||
) -> FlatExpression<T> {
|
||||
match self {
|
||||
e @ FlatExpression::Number(_) => e,
|
||||
|
@ -328,8 +246,8 @@ impl<T: Field> fmt::Display for FlatExpression<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Field> From<FlatVariable> for FlatExpression<T> {
|
||||
fn from(v: FlatVariable) -> FlatExpression<T> {
|
||||
impl<T: Field> From<Variable> for FlatExpression<T> {
|
||||
fn from(v: Variable) -> FlatExpression<T> {
|
||||
FlatExpression::Identifier(v)
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
use crate::flat_absy::FlatParameter;
|
||||
use crate::flat_absy::FlatVariable;
|
||||
use crate::ir::folder::Folder;
|
||||
use crate::ir::Directive;
|
||||
use crate::ir::Parameter;
|
||||
use crate::ir::ProgIterator;
|
||||
use crate::ir::Statement;
|
||||
use crate::ir::Variable;
|
||||
use std::collections::HashSet;
|
||||
use zokrates_field::Field;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct UnconstrainedVariableDetector {
|
||||
pub(self) variables: HashSet<FlatVariable>,
|
||||
pub(self) variables: HashSet<Variable>,
|
||||
}
|
||||
|
||||
impl UnconstrainedVariableDetector {
|
||||
|
@ -33,10 +33,10 @@ impl UnconstrainedVariableDetector {
|
|||
}
|
||||
|
||||
impl<T: Field> Folder<T> for UnconstrainedVariableDetector {
|
||||
fn fold_argument(&mut self, p: FlatParameter) -> FlatParameter {
|
||||
fn fold_argument(&mut self, p: Parameter) -> Parameter {
|
||||
p
|
||||
}
|
||||
fn fold_variable(&mut self, v: FlatVariable) -> FlatVariable {
|
||||
fn fold_variable(&mut self, v: Variable) -> Variable {
|
||||
self.variables.remove(&v);
|
||||
v
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
use crate::flat_absy::FlatVariable;
|
||||
use super::Witness;
|
||||
use crate::common::Variable;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::btree_map::{BTreeMap, Entry};
|
||||
use std::fmt;
|
||||
|
@ -54,10 +55,10 @@ impl<T: Field> fmt::Display for QuadComb<T> {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)]
|
||||
pub struct LinComb<T>(pub Vec<(FlatVariable, T)>);
|
||||
pub struct LinComb<T>(pub Vec<(Variable, T)>);
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Debug, Serialize, Deserialize)]
|
||||
pub struct CanonicalLinComb<T>(pub BTreeMap<FlatVariable, T>);
|
||||
pub struct CanonicalLinComb<T>(pub BTreeMap<Variable, T>);
|
||||
|
||||
#[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Debug, Serialize, Deserialize)]
|
||||
pub struct CanonicalQuadComb<T> {
|
||||
|
@ -81,7 +82,7 @@ impl<T> From<CanonicalLinComb<T>> for LinComb<T> {
|
|||
}
|
||||
|
||||
impl<T> LinComb<T> {
|
||||
pub fn summand<U: Into<T>>(mult: U, var: FlatVariable) -> LinComb<T> {
|
||||
pub fn summand<U: Into<T>>(mult: U, var: Variable) -> LinComb<T> {
|
||||
let res = vec![(var, mult.into())];
|
||||
|
||||
LinComb(res)
|
||||
|
@ -105,7 +106,7 @@ impl<T: Field> LinComb<T> {
|
|||
// take the first variable in the lincomb
|
||||
let first = &self.0[0].0;
|
||||
|
||||
if first != &FlatVariable::one() {
|
||||
if first != &Variable::one() {
|
||||
return Err(self);
|
||||
}
|
||||
|
||||
|
@ -119,7 +120,13 @@ impl<T: Field> LinComb<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn try_summand(self) -> Result<(FlatVariable, T), Self> {
|
||||
pub fn is_assignee(&self, witness: &Witness<T>) -> bool {
|
||||
self.0.len() == 1
|
||||
&& self.0.get(0).unwrap().1 == T::from(1)
|
||||
&& !witness.0.contains_key(&self.0.get(0).unwrap().0)
|
||||
}
|
||||
|
||||
pub fn try_summand(self) -> Result<(Variable, T), Self> {
|
||||
match self.0.len() {
|
||||
// if the lincomb is empty, it is not reduceable to a summand
|
||||
0 => Err(self),
|
||||
|
@ -143,7 +150,7 @@ impl<T: Field> LinComb<T> {
|
|||
}
|
||||
|
||||
pub fn one() -> LinComb<T> {
|
||||
Self::summand(1, FlatVariable::one())
|
||||
Self::summand(1, Variable::one())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,8 +219,8 @@ impl<T: Field> fmt::Display for LinComb<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Field> From<FlatVariable> for LinComb<T> {
|
||||
fn from(v: FlatVariable) -> LinComb<T> {
|
||||
impl<T: Field> From<Variable> for LinComb<T> {
|
||||
fn from(v: Variable) -> LinComb<T> {
|
||||
let r = vec![(v, T::one())];
|
||||
LinComb(r)
|
||||
}
|
||||
|
@ -277,32 +284,32 @@ mod tests {
|
|||
#[test]
|
||||
fn add_zero() {
|
||||
let a: LinComb<Bn128Field> = LinComb::zero();
|
||||
let b: LinComb<Bn128Field> = FlatVariable::new(42).into();
|
||||
let b: LinComb<Bn128Field> = Variable::new(42).into();
|
||||
let c = a + b.clone();
|
||||
assert_eq!(c, b);
|
||||
}
|
||||
#[test]
|
||||
fn add() {
|
||||
let a: LinComb<Bn128Field> = FlatVariable::new(42).into();
|
||||
let b: LinComb<Bn128Field> = FlatVariable::new(42).into();
|
||||
let a: LinComb<Bn128Field> = Variable::new(42).into();
|
||||
let b: LinComb<Bn128Field> = Variable::new(42).into();
|
||||
let c = a + b;
|
||||
|
||||
let expected_vec = vec![
|
||||
(FlatVariable::new(42), Bn128Field::from(1)),
|
||||
(FlatVariable::new(42), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(1)),
|
||||
];
|
||||
|
||||
assert_eq!(c, LinComb(expected_vec));
|
||||
}
|
||||
#[test]
|
||||
fn sub() {
|
||||
let a: LinComb<Bn128Field> = FlatVariable::new(42).into();
|
||||
let b: LinComb<Bn128Field> = FlatVariable::new(42).into();
|
||||
let a: LinComb<Bn128Field> = Variable::new(42).into();
|
||||
let b: LinComb<Bn128Field> = Variable::new(42).into();
|
||||
let c = a - b;
|
||||
|
||||
let expected_vec = vec![
|
||||
(FlatVariable::new(42), Bn128Field::from(1)),
|
||||
(FlatVariable::new(42), Bn128Field::from(-1)),
|
||||
(Variable::new(42), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(-1)),
|
||||
];
|
||||
|
||||
assert_eq!(c, LinComb(expected_vec));
|
||||
|
@ -311,7 +318,7 @@ mod tests {
|
|||
#[test]
|
||||
fn display() {
|
||||
let a: LinComb<Bn128Field> =
|
||||
LinComb::from(FlatVariable::new(42)) + LinComb::summand(3, FlatVariable::new(21));
|
||||
LinComb::from(Variable::new(42)) + LinComb::summand(3, Variable::new(21));
|
||||
assert_eq!(&a.to_string(), "1 * _42 + 3 * _21");
|
||||
let zero: LinComb<Bn128Field> = LinComb::zero();
|
||||
assert_eq!(&zero.to_string(), "0");
|
||||
|
@ -322,8 +329,8 @@ mod tests {
|
|||
use super::*;
|
||||
#[test]
|
||||
fn from_linear() {
|
||||
let a: LinComb<Bn128Field> = LinComb::summand(3, FlatVariable::new(42))
|
||||
+ LinComb::summand(4, FlatVariable::new(33));
|
||||
let a: LinComb<Bn128Field> =
|
||||
LinComb::summand(3, Variable::new(42)) + LinComb::summand(4, Variable::new(33));
|
||||
let expected = QuadComb {
|
||||
left: LinComb::one(),
|
||||
right: a.clone(),
|
||||
|
@ -344,14 +351,14 @@ mod tests {
|
|||
#[test]
|
||||
fn display() {
|
||||
let a: QuadComb<Bn128Field> = QuadComb {
|
||||
left: LinComb::summand(3, FlatVariable::new(42))
|
||||
+ LinComb::summand(4, FlatVariable::new(33)),
|
||||
right: LinComb::summand(1, FlatVariable::new(21)),
|
||||
left: LinComb::summand(3, Variable::new(42))
|
||||
+ LinComb::summand(4, Variable::new(33)),
|
||||
right: LinComb::summand(1, Variable::new(21)),
|
||||
};
|
||||
assert_eq!(&a.to_string(), "(3 * _42 + 4 * _33) * (1 * _21)");
|
||||
let a: QuadComb<Bn128Field> = QuadComb {
|
||||
left: LinComb::zero(),
|
||||
right: LinComb::summand(1, FlatVariable::new(21)),
|
||||
right: LinComb::summand(1, Variable::new(21)),
|
||||
};
|
||||
assert_eq!(&a.to_string(), "(0) * (1 * _21)");
|
||||
}
|
||||
|
@ -363,19 +370,19 @@ mod tests {
|
|||
#[test]
|
||||
fn try_summand() {
|
||||
let summand = LinComb(vec![
|
||||
(FlatVariable::new(42), Bn128Field::from(1)),
|
||||
(FlatVariable::new(42), Bn128Field::from(2)),
|
||||
(FlatVariable::new(42), Bn128Field::from(3)),
|
||||
(Variable::new(42), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(2)),
|
||||
(Variable::new(42), Bn128Field::from(3)),
|
||||
]);
|
||||
assert_eq!(
|
||||
summand.try_summand(),
|
||||
Ok((FlatVariable::new(42), Bn128Field::from(6)))
|
||||
Ok((Variable::new(42), Bn128Field::from(6)))
|
||||
);
|
||||
|
||||
let not_summand = LinComb(vec![
|
||||
(FlatVariable::new(41), Bn128Field::from(1)),
|
||||
(FlatVariable::new(42), Bn128Field::from(2)),
|
||||
(FlatVariable::new(42), Bn128Field::from(3)),
|
||||
(Variable::new(41), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(2)),
|
||||
(Variable::new(42), Bn128Field::from(3)),
|
||||
]);
|
||||
assert!(not_summand.try_summand().is_err());
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Generic walk through an IR AST. Not mutating in place
|
||||
|
||||
use crate::flat_absy::flat_variable::FlatVariable;
|
||||
use crate::ir::*;
|
||||
use super::*;
|
||||
use crate::common::Variable;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait Folder<T: Field>: Sized {
|
||||
|
@ -9,11 +9,11 @@ pub trait Folder<T: Field>: Sized {
|
|||
fold_program(self, p)
|
||||
}
|
||||
|
||||
fn fold_argument(&mut self, p: FlatParameter) -> FlatParameter {
|
||||
fn fold_argument(&mut self, p: Parameter) -> Parameter {
|
||||
fold_argument(self, p)
|
||||
}
|
||||
|
||||
fn fold_variable(&mut self, v: FlatVariable) -> FlatVariable {
|
||||
fn fold_variable(&mut self, v: Variable) -> Variable {
|
||||
fold_variable(self, v)
|
||||
}
|
||||
|
||||
|
@ -91,13 +91,13 @@ pub fn fold_directive<T: Field, F: Folder<T>>(f: &mut F, ds: Directive<T>) -> Di
|
|||
}
|
||||
}
|
||||
|
||||
pub fn fold_argument<T: Field, F: Folder<T>>(f: &mut F, a: FlatParameter) -> FlatParameter {
|
||||
FlatParameter {
|
||||
pub fn fold_argument<T: Field, F: Folder<T>>(f: &mut F, a: Parameter) -> Parameter {
|
||||
Parameter {
|
||||
id: f.fold_variable(a.id),
|
||||
private: a.private,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_variable<T: Field, F: Folder<T>>(_f: &mut F, v: FlatVariable) -> FlatVariable {
|
||||
pub fn fold_variable<T: Field, F: Folder<T>>(_f: &mut F, v: Variable) -> Variable {
|
||||
v
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
use crate::flat_absy::{
|
||||
FlatDirective, FlatExpression, FlatProgIterator, FlatStatement, FlatVariable,
|
||||
};
|
||||
use crate::flat::{FlatDirective, FlatExpression, FlatProgIterator, FlatStatement, Variable};
|
||||
use crate::ir::{Directive, LinComb, ProgIterator, QuadComb, Statement};
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -33,7 +31,7 @@ impl<T: Field> From<FlatExpression<T>> for LinComb<T> {
|
|||
fn from(flat_expression: FlatExpression<T>) -> LinComb<T> {
|
||||
match flat_expression {
|
||||
FlatExpression::Number(ref n) if *n == T::from(0) => LinComb::zero(),
|
||||
FlatExpression::Number(n) => LinComb::summand(n, FlatVariable::one()),
|
||||
FlatExpression::Number(n) => LinComb::summand(n, Variable::one()),
|
||||
FlatExpression::Identifier(id) => LinComb::from(id),
|
||||
FlatExpression::Add(box e1, box e2) => LinComb::from(e1) + LinComb::from(e2),
|
||||
FlatExpression::Sub(box e1, box e2) => LinComb::from(e1) - LinComb::from(e2),
|
||||
|
@ -48,7 +46,7 @@ impl<T: Field> From<FlatExpression<T>> for LinComb<T> {
|
|||
FlatExpression::Mult(
|
||||
box FlatExpression::Number(n1),
|
||||
box FlatExpression::Number(n2),
|
||||
) => LinComb::summand(n1 * n2, FlatVariable::one()),
|
||||
) => LinComb::summand(n1 * n2, Variable::one()),
|
||||
e => unreachable!("{}", e),
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +107,7 @@ mod tests {
|
|||
fn one() {
|
||||
// 1
|
||||
let one = FlatExpression::Number(Bn128Field::from(1));
|
||||
let expected: LinComb<Bn128Field> = FlatVariable::one().into();
|
||||
let expected: LinComb<Bn128Field> = Variable::one().into();
|
||||
assert_eq!(LinComb::from(one), expected);
|
||||
}
|
||||
|
||||
|
@ -117,7 +115,7 @@ mod tests {
|
|||
fn forty_two() {
|
||||
// 42
|
||||
let one = FlatExpression::Number(Bn128Field::from(42));
|
||||
let expected: LinComb<Bn128Field> = LinComb::summand(42, FlatVariable::one());
|
||||
let expected: LinComb<Bn128Field> = LinComb::summand(42, Variable::one());
|
||||
assert_eq!(LinComb::from(one), expected);
|
||||
}
|
||||
|
||||
|
@ -125,11 +123,11 @@ mod tests {
|
|||
fn add() {
|
||||
// x + y
|
||||
let add = FlatExpression::Add(
|
||||
box FlatExpression::Identifier(FlatVariable::new(42)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(21)),
|
||||
box FlatExpression::Identifier(Variable::new(42)),
|
||||
box FlatExpression::Identifier(Variable::new(21)),
|
||||
);
|
||||
let expected: LinComb<Bn128Field> =
|
||||
LinComb::summand(1, FlatVariable::new(42)) + LinComb::summand(1, FlatVariable::new(21));
|
||||
LinComb::summand(1, Variable::new(42)) + LinComb::summand(1, Variable::new(21));
|
||||
assert_eq!(LinComb::from(add), expected);
|
||||
}
|
||||
|
||||
|
@ -139,15 +137,15 @@ mod tests {
|
|||
let add = FlatExpression::Add(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(Bn128Field::from(42)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(42)),
|
||||
box FlatExpression::Identifier(Variable::new(42)),
|
||||
),
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Number(Bn128Field::from(21)),
|
||||
box FlatExpression::Identifier(FlatVariable::new(21)),
|
||||
box FlatExpression::Identifier(Variable::new(21)),
|
||||
),
|
||||
);
|
||||
let expected: LinComb<Bn128Field> = LinComb::summand(42, FlatVariable::new(42))
|
||||
+ LinComb::summand(21, FlatVariable::new(21));
|
||||
let expected: LinComb<Bn128Field> =
|
||||
LinComb::summand(42, Variable::new(42)) + LinComb::summand(21, Variable::new(21));
|
||||
assert_eq!(LinComb::from(add), expected);
|
||||
}
|
||||
|
||||
|
@ -156,16 +154,16 @@ mod tests {
|
|||
// x*42 + y*21
|
||||
let add = FlatExpression::Add(
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(FlatVariable::new(42)),
|
||||
box FlatExpression::Identifier(Variable::new(42)),
|
||||
box FlatExpression::Number(Bn128Field::from(42)),
|
||||
),
|
||||
box FlatExpression::Mult(
|
||||
box FlatExpression::Identifier(FlatVariable::new(21)),
|
||||
box FlatExpression::Identifier(Variable::new(21)),
|
||||
box FlatExpression::Number(Bn128Field::from(21)),
|
||||
),
|
||||
);
|
||||
let expected: LinComb<Bn128Field> = LinComb::summand(42, FlatVariable::new(42))
|
||||
+ LinComb::summand(21, FlatVariable::new(21));
|
||||
let expected: LinComb<Bn128Field> =
|
||||
LinComb::summand(42, Variable::new(42)) + LinComb::summand(21, Variable::new(21));
|
||||
assert_eq!(LinComb::from(add), expected);
|
||||
}
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
use crate::flat_absy::flat_parameter::FlatParameter;
|
||||
use crate::flat_absy::{FlatVariable, RuntimeError};
|
||||
use crate::solvers::Solver;
|
||||
//use crate::solvers::Solver;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use zokrates_field::Field;
|
||||
|
||||
mod check;
|
||||
mod expression;
|
||||
pub mod folder;
|
||||
pub mod from_flat;
|
||||
mod interpreter;
|
||||
mod serialize;
|
||||
pub mod smtlib2;
|
||||
pub mod visitor;
|
||||
|
@ -18,8 +16,11 @@ mod witness;
|
|||
pub use self::expression::QuadComb;
|
||||
pub use self::expression::{CanonicalLinComb, LinComb};
|
||||
pub use self::serialize::ProgEnum;
|
||||
pub use crate::common::Parameter;
|
||||
pub use crate::common::RuntimeError;
|
||||
pub use crate::common::Solver;
|
||||
pub use crate::common::Variable;
|
||||
|
||||
pub use self::interpreter::{Error, ExecutionResult, Interpreter};
|
||||
pub use self::witness::Witness;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Hash, PartialEq, Eq)]
|
||||
|
@ -29,7 +30,7 @@ pub enum Statement<T> {
|
|||
}
|
||||
|
||||
impl<T: Field> Statement<T> {
|
||||
pub fn definition<U: Into<QuadComb<T>>>(v: FlatVariable, e: U) -> Self {
|
||||
pub fn definition<U: Into<QuadComb<T>>>(v: Variable, e: U) -> Self {
|
||||
Statement::Constraint(e.into(), v.into(), None)
|
||||
}
|
||||
|
||||
|
@ -41,7 +42,7 @@ impl<T: Field> Statement<T> {
|
|||
#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)]
|
||||
pub struct Directive<T> {
|
||||
pub inputs: Vec<QuadComb<T>>,
|
||||
pub outputs: Vec<FlatVariable>,
|
||||
pub outputs: Vec<Variable>,
|
||||
pub solver: Solver,
|
||||
}
|
||||
|
||||
|
@ -78,13 +79,13 @@ pub type Prog<T> = ProgIterator<T, Vec<Statement<T>>>;
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
|
||||
pub struct ProgIterator<T, I: IntoIterator<Item = Statement<T>>> {
|
||||
pub arguments: Vec<FlatParameter>,
|
||||
pub arguments: Vec<Parameter>,
|
||||
pub return_count: usize,
|
||||
pub statements: I,
|
||||
}
|
||||
|
||||
impl<T, I: IntoIterator<Item = Statement<T>>> ProgIterator<T, I> {
|
||||
pub fn new(arguments: Vec<FlatParameter>, statements: I, return_count: usize) -> Self {
|
||||
pub fn new(arguments: Vec<Parameter>, statements: I, return_count: usize) -> Self {
|
||||
Self {
|
||||
arguments,
|
||||
return_count,
|
||||
|
@ -100,8 +101,8 @@ impl<T, I: IntoIterator<Item = Statement<T>>> ProgIterator<T, I> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn returns(&self) -> Vec<FlatVariable> {
|
||||
(0..self.return_count).map(FlatVariable::public).collect()
|
||||
pub fn returns(&self) -> Vec<Variable> {
|
||||
(0..self.return_count).map(Variable::public).collect()
|
||||
}
|
||||
|
||||
pub fn public_count(&self) -> usize {
|
||||
|
@ -140,7 +141,7 @@ impl<T> Prog<T> {
|
|||
impl<T: Field> fmt::Display for Prog<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let returns = (0..self.return_count)
|
||||
.map(FlatVariable::public)
|
||||
.map(Variable::public)
|
||||
.map(|e| format!("{}", e))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
|
@ -158,6 +159,15 @@ impl<T: Field> fmt::Display for Prog<T> {
|
|||
for s in &self.statements {
|
||||
writeln!(f, "\t{}", s)?;
|
||||
}
|
||||
writeln!(
|
||||
f,
|
||||
"\treturn {}",
|
||||
(0..self.return_count)
|
||||
.map(Variable::public)
|
||||
.map(|e| format!("{}", e))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)?;
|
||||
|
||||
writeln!(f, "\treturn {}", returns)?;
|
||||
writeln!(f, "}}")
|
||||
|
@ -176,10 +186,10 @@ mod tests {
|
|||
fn print_constraint() {
|
||||
let c: Statement<Bn128Field> = Statement::Constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
FlatVariable::new(42).into(),
|
||||
FlatVariable::new(42).into(),
|
||||
Variable::new(42).into(),
|
||||
Variable::new(42).into(),
|
||||
),
|
||||
FlatVariable::new(42).into(),
|
||||
Variable::new(42).into(),
|
||||
None,
|
||||
);
|
||||
assert_eq!(format!("{}", c), "(1 * _42) * (1 * _42) == 1 * _42")
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
ir::{ProgIterator, Statement},
|
||||
static_analysis::UnconstrainedVariableDetector,
|
||||
};
|
||||
use crate::ir::check::UnconstrainedVariableDetector;
|
||||
|
||||
use super::{ProgIterator, Statement};
|
||||
use serde_cbor::{self, StreamDeserializer};
|
||||
use std::io::{Read, Write};
|
||||
use zokrates_field::*;
|
||||
|
@ -60,7 +59,7 @@ impl<T: Field, I: IntoIterator<Item = Statement<T>>> ProgIterator<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<W: Write>(self, mut w: W) -> Result<usize, DynamicError> {
|
||||
use crate::ir::folder::Folder;
|
||||
use super::folder::Folder;
|
||||
|
||||
w.write_all(ZOKRATES_MAGIC)?;
|
||||
w.write_all(ZOKRATES_VERSION_2)?;
|
||||
|
@ -137,7 +136,7 @@ impl<'de, R: Read>
|
|||
struct ArgumentsVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for ArgumentsVisitor {
|
||||
type Value = Vec<crate::ir::FlatParameter>;
|
||||
type Value = Vec<super::Parameter>;
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter.write_str("seq of flat param")
|
||||
}
|
||||
|
@ -239,13 +238,13 @@ impl<'de, R: Read>
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ir;
|
||||
use crate::ir::Prog;
|
||||
use std::io::{Cursor, Seek, SeekFrom};
|
||||
use zokrates_field::{Bls12_381Field, Bn128Field};
|
||||
|
||||
#[test]
|
||||
fn ser_deser_v2() {
|
||||
let p: ir::Prog<Bn128Field> = ir::Prog::default();
|
||||
let p: Prog<Bn128Field> = Prog::default();
|
||||
|
||||
let mut buffer = Cursor::new(vec![]);
|
||||
p.clone().serialize(&mut buffer).unwrap();
|
||||
|
@ -258,7 +257,7 @@ mod tests {
|
|||
|
||||
assert_eq!(ProgEnum::Bn128Program(p), deserialized_p.collect());
|
||||
|
||||
let p: ir::Prog<Bls12_381Field> = ir::Prog::default();
|
||||
let p: Prog<Bls12_381Field> = Prog::default();
|
||||
|
||||
let mut buffer = Cursor::new(vec![]);
|
||||
p.clone().serialize(&mut buffer).unwrap();
|
|
@ -21,11 +21,11 @@ impl<T: Field> fmt::Display for SMTLib2Display<'_, T> {
|
|||
}
|
||||
|
||||
struct FlatVariableCollector {
|
||||
variables: BTreeSet<FlatVariable>,
|
||||
variables: BTreeSet<Variable>,
|
||||
}
|
||||
|
||||
impl<T: Field> Visitor<T> for FlatVariableCollector {
|
||||
fn visit_variable(&mut self, v: &FlatVariable) {
|
||||
fn visit_variable(&mut self, v: &Variable) {
|
||||
self.variables.insert(*v);
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,10 @@ impl<T: Field> Visitor<T> for FlatVariableCollector {
|
|||
impl<T: Field> SMTLib2 for Prog<T> {
|
||||
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut collector = FlatVariableCollector {
|
||||
variables: BTreeSet::<FlatVariable>::new(),
|
||||
variables: BTreeSet::<Variable>::new(),
|
||||
};
|
||||
collector.visit_module(self);
|
||||
collector.variables.insert(FlatVariable::one());
|
||||
collector.variables.insert(Variable::one());
|
||||
|
||||
writeln!(f, "; Auto generated by ZoKrates")?;
|
||||
writeln!(
|
||||
|
@ -122,7 +122,7 @@ impl<T: Field> SMTLib2 for LinComb<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl SMTLib2 for FlatVariable {
|
||||
impl SMTLib2 for Variable {
|
||||
fn to_smtlib2(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "|{}|", self)
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
// Generic walk through an IR AST. Not mutating in place
|
||||
|
||||
use crate::flat_absy::flat_variable::FlatVariable;
|
||||
use crate::ir::*;
|
||||
use super::*;
|
||||
use crate::common::Variable;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait Visitor<T: Field>: Sized {
|
||||
|
@ -9,11 +9,11 @@ pub trait Visitor<T: Field>: Sized {
|
|||
visit_module(self, p)
|
||||
}
|
||||
|
||||
fn visit_argument(&mut self, p: &FlatParameter) {
|
||||
fn visit_argument(&mut self, p: &Parameter) {
|
||||
visit_argument(self, p)
|
||||
}
|
||||
|
||||
fn visit_variable(&mut self, v: &FlatVariable) {
|
||||
fn visit_variable(&mut self, v: &Variable) {
|
||||
visit_variable(self, v)
|
||||
}
|
||||
|
||||
|
@ -85,11 +85,11 @@ pub fn visit_directive<T: Field, F: Visitor<T>>(f: &mut F, ds: &Directive<T>) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn visit_argument<T: Field, F: Visitor<T>>(f: &mut F, a: &FlatParameter) {
|
||||
pub fn visit_argument<T: Field, F: Visitor<T>>(f: &mut F, a: &Parameter) {
|
||||
f.visit_variable(&a.id)
|
||||
}
|
||||
|
||||
pub fn visit_variable<T: Field, F: Visitor<T>>(_f: &mut F, _v: &FlatVariable) {}
|
||||
pub fn visit_variable<T: Field, F: Visitor<T>>(_f: &mut F, _v: &Variable) {}
|
||||
|
||||
pub fn visit_value<T: Field, F: Visitor<T>>(_f: &mut F, _v: &T) {}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
use crate::flat_absy::FlatVariable;
|
||||
use crate::common::Variable;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::{Read, Write};
|
||||
use zokrates_field::Field;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Witness<T>(pub BTreeMap<FlatVariable, T>);
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
pub struct Witness<T>(pub BTreeMap<Variable, T>);
|
||||
|
||||
impl<T: Field> Witness<T> {
|
||||
pub fn return_values(&self) -> Vec<T> {
|
||||
|
@ -17,11 +17,15 @@ impl<T: Field> Witness<T> {
|
|||
.collect::<HashMap<_, _>>();
|
||||
|
||||
(0..out.len())
|
||||
.map(|i| *out.get(&FlatVariable::public(i)).unwrap())
|
||||
.map(|i| *out.get(&Variable::public(i)).unwrap())
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, var: Variable, val: T) -> Option<T> {
|
||||
self.0.insert(var, val)
|
||||
}
|
||||
|
||||
pub fn format_outputs(&self) -> String {
|
||||
self.0
|
||||
.iter()
|
||||
|
@ -63,13 +67,12 @@ impl<T: Field> Witness<T> {
|
|||
.deserialize::<(String, String)>()
|
||||
.map(|r| {
|
||||
r.map(|(variable, value)| {
|
||||
let variable =
|
||||
FlatVariable::try_from_human_readable(&variable).map_err(|why| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Invalid variable in witness: {}", why),
|
||||
)
|
||||
})?;
|
||||
let variable = Variable::try_from_human_readable(&variable).map_err(|why| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!("Invalid variable in witness: {}", why),
|
||||
)
|
||||
})?;
|
||||
let value = T::try_from_dec_str(&value).map_err(|_| {
|
||||
io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
|
@ -83,7 +86,7 @@ impl<T: Field> Witness<T> {
|
|||
e => io::Error::new(io::ErrorKind::Other, format!("{:?}", e)),
|
||||
})?
|
||||
})
|
||||
.collect::<io::Result<BTreeMap<FlatVariable, T>>>()?;
|
||||
.collect::<io::Result<BTreeMap<Variable, T>>>()?;
|
||||
|
||||
Ok(Witness(map))
|
||||
}
|
||||
|
@ -116,9 +119,9 @@ mod tests {
|
|||
fn serialize_deserialize() {
|
||||
let w = Witness(
|
||||
vec![
|
||||
(FlatVariable::new(42), Bn128Field::from(42)),
|
||||
(FlatVariable::public(8), Bn128Field::from(8)),
|
||||
(FlatVariable::one(), Bn128Field::from(1)),
|
||||
(Variable::new(42), Bn128Field::from(42)),
|
||||
(Variable::public(8), Bn128Field::from(8)),
|
||||
(Variable::one(), Bn128Field::from(1)),
|
||||
]
|
||||
.into_iter()
|
||||
.collect(),
|
10
zokrates_ast/src/lib.rs
Normal file
10
zokrates_ast/src/lib.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
#![feature(box_patterns, box_syntax)]
|
||||
|
||||
pub mod common;
|
||||
pub mod flat;
|
||||
pub mod ir;
|
||||
pub mod typed;
|
||||
pub mod untyped;
|
||||
pub mod zir;
|
||||
|
||||
pub use common::Solver;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::typed_absy::types::{ConcreteSignature, ConcreteType};
|
||||
use crate::typed::types::{ConcreteSignature, ConcreteType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
|
@ -30,12 +30,12 @@ impl Abi {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::typed_absy::types::{
|
||||
use crate::typed::types::{
|
||||
ConcreteArrayType, ConcreteFunctionKey, ConcreteStructMember, ConcreteStructType,
|
||||
GTupleType, UBitwidth,
|
||||
};
|
||||
use crate::typed_absy::DeclarationType;
|
||||
use crate::typed_absy::{
|
||||
use crate::typed::DeclarationType;
|
||||
use crate::typed::{
|
||||
parameter::DeclarationParameter, variable::DeclarationVariable, ConcreteTupleType,
|
||||
ConcreteType, TypedFunction, TypedFunctionSymbol, TypedFunctionSymbolDeclaration,
|
||||
TypedModule, TypedProgram,
|
|
@ -1,7 +1,7 @@
|
|||
// Generic walk through a typed AST. Not mutating in place
|
||||
|
||||
use crate::typed_absy::types::*;
|
||||
use crate::typed_absy::*;
|
||||
use crate::typed::types::*;
|
||||
use crate::typed::*;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait Fold<'ast, T: Field>: Sized {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::typed_absy::CanonicalConstantIdentifier;
|
||||
use crate::typed::CanonicalConstantIdentifier;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
use crate::typed_absy::types::{
|
||||
use crate::typed::types::{
|
||||
ArrayType, DeclarationArrayType, DeclarationConstant, DeclarationStructMember,
|
||||
DeclarationStructType, DeclarationTupleType, DeclarationType, GArrayType, GStructType,
|
||||
GTupleType, GType, GenericIdentifier, StructType, TupleType, Type,
|
||||
};
|
||||
use crate::typed_absy::UBitwidth;
|
||||
use crate::typed_absy::{
|
||||
use crate::typed::UBitwidth;
|
||||
use crate::typed::{
|
||||
ArrayExpression, ArrayExpressionInner, BooleanExpression, Conditional, ConditionalExpression,
|
||||
Expr, FieldElementExpression, Select, SelectExpression, StructExpression,
|
||||
StructExpressionInner, TupleExpression, TupleExpressionInner, Typed, TypedExpression,
|
||||
|
@ -791,7 +791,7 @@ impl<'ast, T> From<BigUint> for IntExpression<'ast, T> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::typed_absy::ConditionalKind;
|
||||
use crate::typed::ConditionalKind;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
|
@ -25,28 +25,29 @@ pub use self::types::{
|
|||
GArrayType, GStructType, GType, GenericIdentifier, Signature, StructType, TupleType, Type,
|
||||
UBitwidth,
|
||||
};
|
||||
use crate::parser::Position;
|
||||
use crate::typed_absy::types::{ConcreteGenericsAssignment, IntoType};
|
||||
|
||||
use crate::typed::types::{ConcreteGenericsAssignment, IntoType};
|
||||
use crate::untyped::Position;
|
||||
|
||||
pub use self::variable::{ConcreteVariable, DeclarationVariable, GVariable, Variable};
|
||||
use std::marker::PhantomData;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub use crate::typed_absy::integer::IntExpression;
|
||||
pub use crate::typed_absy::uint::{bitwidth, UExpression, UExpressionInner, UMetadata};
|
||||
pub use crate::typed::integer::IntExpression;
|
||||
pub use crate::typed::uint::{bitwidth, UExpression, UExpressionInner, UMetadata};
|
||||
|
||||
use crate::embed::FlatEmbed;
|
||||
use crate::common::FlatEmbed;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fmt;
|
||||
|
||||
pub use crate::typed_absy::types::{ArrayType, FunctionKey, MemberId};
|
||||
pub use crate::typed::types::{ArrayType, FunctionKey, MemberId};
|
||||
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub use self::folder::Folder;
|
||||
use crate::typed_absy::abi::{Abi, AbiInput};
|
||||
use crate::typed::abi::{Abi, AbiInput};
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
|
||||
pub use self::identifier::Identifier;
|
||||
|
@ -85,12 +86,6 @@ pub struct TypedProgram<'ast, T> {
|
|||
pub main: OwnedTypedModuleId,
|
||||
}
|
||||
|
||||
impl<'ast, T> TypedProgram<'ast, T> {
|
||||
pub fn main_function(&self) -> TypedFunction<'ast, T> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> TypedProgram<'ast, T> {
|
||||
pub fn abi(&self) -> Abi {
|
||||
let main = &self.modules[&self.main]
|
||||
|
@ -109,7 +104,7 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
|
|||
.iter()
|
||||
.map(|p| {
|
||||
types::ConcreteType::try_from(
|
||||
crate::typed_absy::types::try_from_g_type::<
|
||||
crate::typed::types::try_from_g_type::<
|
||||
DeclarationConstant<'ast, T>,
|
||||
UExpression<'ast, T>,
|
||||
>(p.id._type.clone())
|
||||
|
@ -124,10 +119,9 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
|
|||
})
|
||||
.collect(),
|
||||
output: types::ConcreteType::try_from(
|
||||
crate::typed_absy::types::try_from_g_type::<
|
||||
DeclarationConstant<'ast, T>,
|
||||
UExpression<'ast, T>,
|
||||
>(*main.signature.output.clone())
|
||||
types::try_from_g_type::<DeclarationConstant<'ast, T>, UExpression<'ast, T>>(
|
||||
*main.signature.output.clone(),
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
|
@ -2153,7 +2147,7 @@ impl<'ast, T: Clone> Member<'ast, T> for UExpression<'ast, T> {
|
|||
fn member(s: StructExpression<'ast, T>, id: MemberId) -> Self {
|
||||
let ty = s.ty().members.iter().find(|member| id == member.id);
|
||||
let bitwidth = match ty {
|
||||
Some(crate::typed_absy::types::StructMember {
|
||||
Some(crate::typed::types::StructMember {
|
||||
ty: box Type::Uint(bitwidth),
|
||||
..
|
||||
}) => *bitwidth,
|
||||
|
@ -2167,7 +2161,7 @@ impl<'ast, T: Clone> Member<'ast, T> for ArrayExpression<'ast, T> {
|
|||
fn member(s: StructExpression<'ast, T>, id: MemberId) -> Self {
|
||||
let ty = s.ty().members.iter().find(|member| id == member.id);
|
||||
let (ty, size) = match ty {
|
||||
Some(crate::typed_absy::types::StructMember {
|
||||
Some(crate::typed::types::StructMember {
|
||||
ty: box Type::Array(array_ty),
|
||||
..
|
||||
}) => (*array_ty.ty.clone(), array_ty.size.clone()),
|
||||
|
@ -2181,7 +2175,7 @@ impl<'ast, T: Clone> Member<'ast, T> for StructExpression<'ast, T> {
|
|||
fn member(s: StructExpression<'ast, T>, id: MemberId) -> Self {
|
||||
let ty = s.ty().members.iter().find(|member| id == member.id);
|
||||
let struct_ty = match ty {
|
||||
Some(crate::typed_absy::types::StructMember {
|
||||
Some(crate::typed::types::StructMember {
|
||||
ty: box Type::Struct(struct_ty),
|
||||
..
|
||||
}) => struct_ty.clone(),
|
||||
|
@ -2195,7 +2189,7 @@ impl<'ast, T: Clone> Member<'ast, T> for TupleExpression<'ast, T> {
|
|||
fn member(s: StructExpression<'ast, T>, id: MemberId) -> Self {
|
||||
let ty = s.ty().members.iter().find(|member| id == member.id);
|
||||
let tuple_ty = match ty {
|
||||
Some(crate::typed_absy::types::StructMember {
|
||||
Some(crate::typed::types::StructMember {
|
||||
ty: box Type::Tuple(tuple_ty),
|
||||
..
|
||||
}) => tuple_ty.clone(),
|
|
@ -1,5 +1,5 @@
|
|||
use crate::typed_absy::types::DeclarationConstant;
|
||||
use crate::typed_absy::GVariable;
|
||||
use crate::typed::types::DeclarationConstant;
|
||||
use crate::typed::GVariable;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -8,7 +8,6 @@ pub struct GParameter<'ast, S> {
|
|||
pub private: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl<'ast, S> From<GVariable<'ast, S>> for GParameter<'ast, S> {
|
||||
fn from(v: GVariable<'ast, S>) -> Self {
|
||||
GParameter {
|
|
@ -1,7 +1,7 @@
|
|||
// Generic walk through a typed AST. Not mutating in place
|
||||
|
||||
use crate::typed_absy::types::*;
|
||||
use crate::typed_absy::*;
|
||||
use crate::typed::types::*;
|
||||
use crate::typed::*;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait ResultFold<'ast, T: Field>: Sized {
|
|
@ -1,7 +1,7 @@
|
|||
use crate::typed_absy::{
|
||||
use crate::typed::{
|
||||
CoreIdentifier, Identifier, OwnedTypedModuleId, TypedExpression, UExpression, UExpressionInner,
|
||||
};
|
||||
use crate::typed_absy::{TryFrom, TryInto};
|
||||
use crate::typed::{TryFrom, TryInto};
|
||||
use serde::{de::Error, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
|
@ -1,5 +1,5 @@
|
|||
use crate::typed_absy::types::UBitwidth;
|
||||
use crate::typed_absy::*;
|
||||
use crate::typed::types::UBitwidth;
|
||||
use crate::typed::*;
|
||||
use std::ops::{Add, Div, Mul, Neg, Not, Rem, Sub};
|
||||
use zokrates_field::Field;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
use crate::typed_absy::types::{DeclarationConstant, GStructType, UBitwidth};
|
||||
use crate::typed_absy::types::{GType, SpecializationError};
|
||||
use crate::typed_absy::Identifier;
|
||||
use crate::typed_absy::UExpression;
|
||||
use crate::typed_absy::{TryFrom, TryInto};
|
||||
use crate::typed::types::{DeclarationConstant, GStructType, UBitwidth};
|
||||
use crate::typed::types::{GType, SpecializationError};
|
||||
use crate::typed::Identifier;
|
||||
use crate::typed::UExpression;
|
||||
use crate::typed::{TryFrom, TryInto};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Hash, Eq, PartialOrd, Ord, Debug)]
|
||||
|
@ -45,7 +45,7 @@ impl<'ast, T> From<ConcreteVariable<'ast>> for Variable<'ast, T> {
|
|||
pub fn try_from_g_variable<T: TryInto<U>, U>(
|
||||
v: GVariable<T>,
|
||||
) -> Result<GVariable<U>, SpecializationError> {
|
||||
let _type = crate::typed_absy::types::try_from_g_type(v._type)?;
|
||||
let _type = crate::typed::types::try_from_g_type(v._type)?;
|
||||
|
||||
Ok(GVariable {
|
||||
_type,
|
1249
zokrates_ast/src/untyped/from_ast.rs
Normal file
1249
zokrates_ast/src/untyped/from_ast.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -8,14 +8,16 @@
|
|||
mod from_ast;
|
||||
mod node;
|
||||
pub mod parameter;
|
||||
mod position;
|
||||
pub mod types;
|
||||
pub mod variable;
|
||||
|
||||
pub use crate::absy::node::{Node, NodeValue};
|
||||
pub use crate::absy::parameter::{Parameter, ParameterNode};
|
||||
use crate::absy::types::{UnresolvedSignature, UnresolvedType, UserTypeId};
|
||||
pub use crate::absy::variable::{Variable, VariableNode};
|
||||
use crate::embed::FlatEmbed;
|
||||
pub use self::node::{Node, NodeValue};
|
||||
pub use self::parameter::{Parameter, ParameterNode};
|
||||
pub use self::position::Position;
|
||||
use self::types::{UnresolvedSignature, UnresolvedType, UserTypeId};
|
||||
pub use self::variable::{Variable, VariableNode};
|
||||
use crate::common::FlatEmbed;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use std::fmt;
|
|
@ -1,4 +1,3 @@
|
|||
use crate::parser::Position;
|
||||
use std::fmt;
|
||||
use zokrates_pest_ast::Span;
|
||||
|
||||
|
@ -53,7 +52,6 @@ pub trait NodeValue: fmt::Display + fmt::Debug + Sized + PartialEq {
|
|||
Node::new(start, end, self)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn mock(self) -> Node<Self> {
|
||||
Node::new(Position::mock(), Position::mock(), self)
|
||||
}
|
||||
|
@ -81,8 +79,7 @@ impl<V: NodeValue> From<V> for Node<V> {
|
|||
}
|
||||
}
|
||||
|
||||
use crate::absy::types::UnresolvedType;
|
||||
use crate::absy::*;
|
||||
use super::*;
|
||||
|
||||
impl<'ast> NodeValue for Expression<'ast> {}
|
||||
impl<'ast> NodeValue for Assignee<'ast> {}
|
|
@ -1,4 +1,4 @@
|
|||
use crate::absy::{Node, VariableNode};
|
||||
use super::{Node, VariableNode};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
|
@ -1,5 +1,5 @@
|
|||
use crate::absy::ExpressionNode;
|
||||
use crate::absy::UnresolvedTypeNode;
|
||||
use super::ExpressionNode;
|
||||
use super::UnresolvedTypeNode;
|
||||
use std::fmt;
|
||||
|
||||
pub type Identifier<'ast> = &'ast str;
|
||||
|
@ -76,10 +76,10 @@ impl<'ast> UnresolvedType<'ast> {
|
|||
pub use self::signature::UnresolvedSignature;
|
||||
|
||||
mod signature {
|
||||
use crate::absy::ConstantGenericNode;
|
||||
use crate::untyped::ConstantGenericNode;
|
||||
use std::fmt;
|
||||
|
||||
use crate::absy::UnresolvedTypeNode;
|
||||
use crate::untyped::UnresolvedTypeNode;
|
||||
|
||||
#[derive(Clone, PartialEq, Default)]
|
||||
pub struct UnresolvedSignature<'ast> {
|
|
@ -1,8 +1,8 @@
|
|||
use crate::absy::types::UnresolvedType;
|
||||
use crate::absy::{Node, UnresolvedTypeNode};
|
||||
use super::types::UnresolvedType;
|
||||
use super::{Node, UnresolvedTypeNode};
|
||||
use std::fmt;
|
||||
|
||||
use crate::absy::Identifier;
|
||||
use super::Identifier;
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct Variable<'ast> {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::typed_absy;
|
||||
use crate::typed as typed_absy;
|
||||
use crate::zir;
|
||||
|
||||
impl From<typed_absy::types::ConcreteSignature> for zir::types::Signature {
|
|
@ -1,7 +1,7 @@
|
|||
use crate::zir::types::MemberId;
|
||||
use std::fmt;
|
||||
|
||||
use crate::typed_absy::Identifier as CoreIdentifier;
|
||||
use crate::typed::Identifier as CoreIdentifier;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||
pub enum Identifier<'ast> {
|
|
@ -10,9 +10,9 @@ mod variable;
|
|||
pub use self::parameter::Parameter;
|
||||
pub use self::types::Type;
|
||||
pub use self::variable::Variable;
|
||||
use crate::common::FlatEmbed;
|
||||
pub use crate::zir::uint::{ShouldReduce, UExpression, UExpressionInner, UMetadata};
|
||||
|
||||
use crate::embed::FlatEmbed;
|
||||
use crate::zir::types::Signature;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
|
@ -102,6 +102,12 @@ impl fmt::Display for RuntimeError {
|
|||
}
|
||||
}
|
||||
|
||||
impl RuntimeError {
|
||||
pub fn mock() -> Self {
|
||||
RuntimeError::SourceAssertion(String::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// A statement in a `ZirFunction`
|
||||
#[derive(Clone, PartialEq, Hash, Eq, Debug)]
|
||||
pub enum ZirStatement<'ast, T> {
|
|
@ -4,12 +4,14 @@ use crate::zir::BooleanExpression;
|
|||
use zokrates_field::Field;
|
||||
|
||||
impl<'ast, T: Field> UExpression<'ast, T> {
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn add(self, other: Self) -> UExpression<'ast, T> {
|
||||
let bitwidth = self.bitwidth;
|
||||
assert_eq!(bitwidth, other.bitwidth);
|
||||
UExpressionInner::Add(box self, box other).annotate(bitwidth)
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn sub(self, other: Self) -> UExpression<'ast, T> {
|
||||
let bitwidth = self.bitwidth;
|
||||
assert_eq!(bitwidth, other.bitwidth);
|
||||
|
@ -27,12 +29,14 @@ impl<'ast, T: Field> UExpression<'ast, T> {
|
|||
UExpressionInner::Mult(box self, box other).annotate(bitwidth)
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn div(self, other: Self) -> UExpression<'ast, T> {
|
||||
let bitwidth = self.bitwidth;
|
||||
assert_eq!(bitwidth, other.bitwidth);
|
||||
UExpressionInner::Div(box self, box other).annotate(bitwidth)
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn rem(self, other: Self) -> UExpression<'ast, T> {
|
||||
let bitwidth = self.bitwidth;
|
||||
assert_eq!(bitwidth, other.bitwidth);
|
||||
|
@ -45,6 +49,7 @@ impl<'ast, T: Field> UExpression<'ast, T> {
|
|||
UExpressionInner::Xor(box self, box other).annotate(bitwidth)
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn not(self) -> UExpression<'ast, T> {
|
||||
let bitwidth = self.bitwidth;
|
||||
UExpressionInner::Not(box self).annotate(bitwidth)
|
28
zokrates_bellman/Cargo.toml
Normal file
28
zokrates_bellman/Cargo.toml
Normal file
|
@ -0,0 +1,28 @@
|
|||
[package]
|
||||
name = "zokrates_bellman"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
wasm = ["bellman/nolog", "bellman/wasm"]
|
||||
multicore = ["bellman/multicore", "phase2/multicore"]
|
||||
|
||||
[dependencies]
|
||||
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
|
||||
zokrates_ast = { version = "0.1", path = "../zokrates_ast", default-features = false }
|
||||
zokrates_proof_systems = { version = "0.1", path = "../zokrates_proof_systems", default-features = false }
|
||||
|
||||
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"] }
|
||||
hex = "0.4.2"
|
||||
|
||||
[dev-dependencies]
|
||||
zokrates_interpreter = { version = "0.1", path = "../zokrates_interpreter", features = ["bellman"] }
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -4,19 +4,19 @@ use bellman::groth16::{
|
|||
};
|
||||
use pairing::{ff::to_hex, CurveAffine, Engine};
|
||||
|
||||
use crate::proof_system::{Backend, MpcBackend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
use zokrates_field::BellmanFieldExtensions;
|
||||
use zokrates_field::Field;
|
||||
use zokrates_proof_systems::{Backend, MpcBackend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
|
||||
use crate::ir::{ProgIterator, Statement, Witness};
|
||||
use crate::proof_system::bellman::Bellman;
|
||||
use crate::proof_system::bellman::Computation;
|
||||
use crate::proof_system::bellman::{parse_g1, parse_g2};
|
||||
use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16};
|
||||
use crate::proof_system::Scheme;
|
||||
use crate::Bellman;
|
||||
use crate::Computation;
|
||||
use crate::{parse_g1, parse_g2};
|
||||
use phase2::MPCParameters;
|
||||
use rand_0_4::Rng;
|
||||
use std::io::{Read, Write};
|
||||
use zokrates_ast::ir::{ProgIterator, Statement, Witness};
|
||||
use zokrates_proof_systems::groth16::{ProofPoints, VerificationKey, G16};
|
||||
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.";
|
||||
|
||||
|
@ -155,8 +155,8 @@ impl<T: Field + BellmanFieldExtensions> MpcBackend<T, G16> for Bellman {
|
|||
|
||||
pub mod serialization {
|
||||
use super::*;
|
||||
use crate::proof_system::{G1Affine, G2Affine};
|
||||
use pairing::from_hex;
|
||||
use zokrates_proof_systems::{G1Affine, G2Affine};
|
||||
|
||||
pub fn parameters_to_verification_key<T: Field + BellmanFieldExtensions>(
|
||||
parameters: &Parameters<T::BellmanEngine>,
|
||||
|
@ -186,29 +186,32 @@ pub mod serialization {
|
|||
pub fn to_g2<T: BellmanFieldExtensions>(
|
||||
g2: G2Affine,
|
||||
) -> <T::BellmanEngine as Engine>::G2Affine {
|
||||
let x = T::new_fq2(&(g2.0).0, &(g2.0).1);
|
||||
let y = T::new_fq2(&(g2.1).0, &(g2.1).1);
|
||||
<T::BellmanEngine as Engine>::G2Affine::from_xy_unchecked(x, y)
|
||||
match g2 {
|
||||
G2Affine::Fq2(g2) => {
|
||||
let x = T::new_fq2(&(g2.0).0, &(g2.0).1);
|
||||
let y = T::new_fq2(&(g2.1).0, &(g2.1).1);
|
||||
<T::BellmanEngine as Engine>::G2Affine::from_xy_unchecked(x, y)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
use super::*;
|
||||
use crate::flat_absy::{FlatParameter, FlatVariable};
|
||||
use crate::ir::{Interpreter, Prog, Statement};
|
||||
use zokrates_ast::common::{Parameter, Variable};
|
||||
use zokrates_ast::ir::{Prog, Statement};
|
||||
|
||||
#[test]
|
||||
fn verify() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![FlatParameter::public(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::new(0),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let keypair = <Bellman as NonUniversalBackend<Bn128Field, G16>>::setup(program.clone());
|
|
@ -1,18 +1,20 @@
|
|||
pub mod groth16;
|
||||
|
||||
use crate::ir::{CanonicalLinComb, ProgIterator, Statement, Witness};
|
||||
use bellman::groth16::Proof;
|
||||
use bellman::groth16::{
|
||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
Parameters,
|
||||
};
|
||||
use bellman::pairing::ff::ScalarEngine;
|
||||
use bellman::{Circuit, ConstraintSystem, LinearCombination, SynthesisError, Variable};
|
||||
use bellman::{
|
||||
Circuit, ConstraintSystem, LinearCombination, SynthesisError, Variable as BellmanVariable,
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
use zokrates_ast::common::Variable;
|
||||
use zokrates_ast::ir::{CanonicalLinComb, ProgIterator, Statement, Witness};
|
||||
use zokrates_field::BellmanFieldExtensions;
|
||||
use zokrates_field::Field;
|
||||
|
||||
use crate::flat_absy::FlatVariable;
|
||||
use rand_0_4::ChaChaRng;
|
||||
|
||||
pub use self::parse::*;
|
||||
|
@ -44,7 +46,7 @@ impl<T: Field, I: IntoIterator<Item = Statement<T>>> Computation<T, I> {
|
|||
fn bellman_combination<T: BellmanFieldExtensions, CS: ConstraintSystem<T::BellmanEngine>>(
|
||||
l: CanonicalLinComb<T>,
|
||||
cs: &mut CS,
|
||||
symbols: &mut BTreeMap<FlatVariable, Variable>,
|
||||
symbols: &mut BTreeMap<Variable, BellmanVariable>,
|
||||
witness: &mut Witness<T>,
|
||||
) -> LinearCombination<T::BellmanEngine> {
|
||||
l.0.into_iter()
|
||||
|
@ -81,20 +83,21 @@ fn bellman_combination<T: BellmanFieldExtensions, CS: ConstraintSystem<T::Bellma
|
|||
.fold(LinearCombination::zero(), |acc, e| acc + e)
|
||||
}
|
||||
|
||||
impl<T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<T>>> ProgIterator<T, I> {
|
||||
pub fn synthesize<CS: ConstraintSystem<T::BellmanEngine>>(
|
||||
impl<T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<T>>>
|
||||
Circuit<T::BellmanEngine> for Computation<T, I>
|
||||
{
|
||||
fn synthesize<CS: ConstraintSystem<T::BellmanEngine>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
witness: Option<Witness<T>>,
|
||||
) -> Result<(), SynthesisError> {
|
||||
// mapping from IR variables
|
||||
let mut symbols = BTreeMap::new();
|
||||
|
||||
let mut witness = witness.unwrap_or_else(Witness::empty);
|
||||
let mut witness = self.witness.unwrap_or_else(Witness::empty);
|
||||
|
||||
assert!(symbols.insert(FlatVariable::one(), CS::one()).is_none());
|
||||
assert!(symbols.insert(Variable::one(), CS::one()).is_none());
|
||||
|
||||
symbols.extend(self.arguments.iter().enumerate().map(|(index, p)| {
|
||||
symbols.extend(self.program.arguments.iter().enumerate().map(|(index, p)| {
|
||||
let wire = match p.private {
|
||||
true => cs.alloc(
|
||||
|| format!("PRIVATE_INPUT_{}", index),
|
||||
|
@ -121,7 +124,7 @@ impl<T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<T>>> Pr
|
|||
(p.id, wire)
|
||||
}));
|
||||
|
||||
for statement in self.statements {
|
||||
for statement in self.program.statements {
|
||||
if let Statement::Constraint(quad, lin, _) = statement {
|
||||
let a = &bellman_combination(
|
||||
quad.left.into_canonical(),
|
||||
|
@ -192,21 +195,10 @@ impl<T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<T>>> Co
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: BellmanFieldExtensions + Field, I: IntoIterator<Item = Statement<T>>>
|
||||
Circuit<T::BellmanEngine> for Computation<T, I>
|
||||
{
|
||||
fn synthesize<CS: ConstraintSystem<T::BellmanEngine>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
self.program.synthesize(cs, self.witness)
|
||||
}
|
||||
}
|
||||
|
||||
mod parse {
|
||||
use super::*;
|
||||
use crate::proof_system::{G1Affine, G2Affine};
|
||||
use pairing_ce::CurveAffine;
|
||||
use pairing::CurveAffine;
|
||||
use zokrates_proof_systems::{G1Affine, G2Affine, G2AffineFq2};
|
||||
|
||||
fn to_hex(bytes: &[u8]) -> String {
|
||||
let mut hex = hex::encode(bytes);
|
||||
|
@ -239,21 +231,21 @@ mod parse {
|
|||
let y1 = to_hex(iter.next().unwrap());
|
||||
let y0 = to_hex(iter.next().unwrap());
|
||||
|
||||
G2Affine((x0, x1), (y0, y1))
|
||||
G2Affine::Fq2(G2AffineFq2((x0, x1), (y0, y1)))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ir::Interpreter;
|
||||
use crate::ir::LinComb;
|
||||
use zokrates_ast::ir::LinComb;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
mod prove {
|
||||
use super::*;
|
||||
use crate::flat_absy::FlatParameter;
|
||||
use crate::ir::Prog;
|
||||
use zokrates_ast::flat::Parameter;
|
||||
use zokrates_ast::ir::Prog;
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
|
@ -271,12 +263,9 @@ mod tests {
|
|||
#[test]
|
||||
fn identity() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::private(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::new(0),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let interpreter = Interpreter::default();
|
||||
|
@ -294,12 +283,9 @@ mod tests {
|
|||
#[test]
|
||||
fn public_identity() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![FlatParameter::public(FlatVariable::new(0))],
|
||||
arguments: vec![Parameter::public(Variable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::new(0),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::new(0), Variable::public(0))],
|
||||
};
|
||||
|
||||
let interpreter = Interpreter::default();
|
||||
|
@ -319,10 +305,7 @@ mod tests {
|
|||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
FlatVariable::one(),
|
||||
FlatVariable::public(0),
|
||||
)],
|
||||
statements: vec![Statement::constraint(Variable::one(), Variable::public(0))],
|
||||
};
|
||||
|
||||
let interpreter = Interpreter::default();
|
||||
|
@ -340,18 +323,18 @@ mod tests {
|
|||
// private variables can be unordered
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![
|
||||
FlatParameter::private(FlatVariable::new(42)),
|
||||
FlatParameter::public(FlatVariable::new(51)),
|
||||
Parameter::private(Variable::new(42)),
|
||||
Parameter::public(Variable::new(51)),
|
||||
],
|
||||
return_count: 2,
|
||||
statements: vec![
|
||||
Statement::constraint(
|
||||
LinComb::from(FlatVariable::new(42)) + LinComb::from(FlatVariable::new(51)),
|
||||
FlatVariable::public(0),
|
||||
LinComb::from(Variable::new(42)) + LinComb::from(Variable::new(51)),
|
||||
Variable::public(0),
|
||||
),
|
||||
Statement::constraint(
|
||||
LinComb::from(FlatVariable::one()) + LinComb::from(FlatVariable::new(42)),
|
||||
FlatVariable::public(1),
|
||||
LinComb::from(Variable::one()) + LinComb::from(Variable::new(42)),
|
||||
Variable::public(1),
|
||||
),
|
||||
],
|
||||
};
|
||||
|
@ -370,11 +353,11 @@ mod tests {
|
|||
#[test]
|
||||
fn one() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![FlatParameter::public(FlatVariable::new(42))],
|
||||
arguments: vec![Parameter::public(Variable::new(42))],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
LinComb::from(FlatVariable::new(42)) + LinComb::one(),
|
||||
FlatVariable::public(0),
|
||||
LinComb::from(Variable::new(42)) + LinComb::one(),
|
||||
Variable::public(0),
|
||||
)],
|
||||
};
|
||||
|
||||
|
@ -394,13 +377,13 @@ mod tests {
|
|||
fn with_directives() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![
|
||||
FlatParameter::private(FlatVariable::new(42)),
|
||||
FlatParameter::public(FlatVariable::new(51)),
|
||||
Parameter::private(Variable::new(42)),
|
||||
Parameter::public(Variable::new(51)),
|
||||
],
|
||||
return_count: 1,
|
||||
statements: vec![Statement::constraint(
|
||||
LinComb::from(FlatVariable::new(42)) + LinComb::from(FlatVariable::new(51)),
|
||||
FlatVariable::public(0),
|
||||
LinComb::from(Variable::new(42)) + LinComb::from(Variable::new(51)),
|
||||
Variable::public(0),
|
||||
)],
|
||||
};
|
||||
|
|
@ -48,7 +48,6 @@ ZoKrates supports multiple backends. The options are the following:
|
|||
| Backend | CLI flag | Proving schemes | Curves |
|
||||
| ---- | -------- |-------------------|------------------------------------------|
|
||||
| Bellman | `--backend bellman` | G16 | ALTBN_128, BLS12_381 |
|
||||
| Libsnark | `--backend libsnark` | GM17, PGHR13 | ALTBN_128 |
|
||||
| Ark | `--backend ark` | G16, GM17, MARLIN | ALTBN_128, BLS12_381, BLS12_377, BW6_761 |
|
||||
|
||||
Default: `bellman`
|
||||
|
@ -59,12 +58,6 @@ When not using the default, the CLI flag has to be provided for the following co
|
|||
- `generate-proof`
|
||||
- `verify`
|
||||
|
||||
To include libsnark in the build, compile ZoKrates from [source](https://github.com/ZoKrates/ZoKrates/) with the `libsnark` feature:
|
||||
```bash
|
||||
cargo +nightly -Z package-features build --release --package zokrates_cli --features="libsnark"
|
||||
```
|
||||
Note, that this is only tested for Linux. If you are on another OS, consider using our Docker container, which includes a libsnark installation.
|
||||
|
||||
## G16 malleability
|
||||
|
||||
When using G16, developers should pay attention to the fact that an attacker, seeing a valid proof, can very easily generate a different but still valid proof. Therefore, depending on the use case, making sure on chain that the same proof cannot be submitted twice may *not* be enough to guarantee that attackers cannot replay proofs. Mechanisms to solve this issue include:
|
||||
|
|
|
@ -7,9 +7,8 @@ edition = "2018"
|
|||
|
||||
[features]
|
||||
default = ["bellman", "ark"]
|
||||
libsnark = ["zokrates_core/libsnark", "zokrates_common/libsnark"]
|
||||
bellman = ["zokrates_core/bellman", "zokrates_common/bellman"]
|
||||
ark = ["zokrates_core/ark", "zokrates_common/ark"]
|
||||
bellman = ["zokrates_bellman", "zokrates_core/bellman", "zokrates_common/bellman"]
|
||||
ark = ["zokrates_ark", "zokrates_core/ark", "zokrates_common/ark"]
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
|
@ -21,9 +20,11 @@ regex = "0.2"
|
|||
zokrates_field = { version = "0.5", path = "../zokrates_field", default-features = false }
|
||||
zokrates_abi = { version = "0.1", path = "../zokrates_abi" }
|
||||
zokrates_core = { version = "0.6", 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 }
|
||||
typed-arena = "1.4.1"
|
||||
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
|
||||
zokrates_common = { version = "0.1", path = "../zokrates_common" }
|
||||
zokrates_common = { version = "0.1", path = "../zokrates_common", default-features = false }
|
||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
dirs = "3.0.1"
|
||||
|
@ -35,6 +36,11 @@ hex = "0.3.1"
|
|||
blake2 = "0.8.1"
|
||||
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 }
|
||||
|
||||
[dev-dependencies]
|
||||
glob = "0.2.11"
|
||||
assert_cli = "0.5"
|
||||
|
|
|
@ -49,14 +49,14 @@ fn cli() -> Result<(), String> {
|
|||
universal_setup::subcommand(),
|
||||
#[cfg(feature = "bellman")]
|
||||
mpc::subcommand(),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
setup::subcommand(),
|
||||
export_verifier::subcommand(),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
generate_proof::subcommand(),
|
||||
generate_smtlib2::subcommand(),
|
||||
print_proof::subcommand(),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
verify::subcommand()])
|
||||
.get_matches();
|
||||
|
||||
|
@ -69,14 +69,14 @@ fn cli() -> Result<(), String> {
|
|||
("universal-setup", Some(sub_matches)) => universal_setup::exec(sub_matches),
|
||||
#[cfg(feature = "bellman")]
|
||||
("mpc", Some(sub_matches)) => mpc::exec(sub_matches),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
("setup", Some(sub_matches)) => setup::exec(sub_matches),
|
||||
("export-verifier", Some(sub_matches)) => export_verifier::exec(sub_matches),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
("generate-proof", Some(sub_matches)) => generate_proof::exec(sub_matches),
|
||||
("generate-smtlib2", Some(sub_matches)) => generate_smtlib2::exec(sub_matches),
|
||||
("print-proof", Some(sub_matches)) => print_proof::exec(sub_matches),
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
("verify", Some(sub_matches)) => verify::exec(sub_matches),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -122,7 +122,6 @@ mod tests {
|
|||
use std::string::String;
|
||||
use typed_arena::Arena;
|
||||
use zokrates_core::compile::{compile, CompilationArtifacts, CompileConfig};
|
||||
use zokrates_core::ir;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_fs_resolver::FileSystemResolver;
|
||||
|
||||
|
@ -217,7 +216,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
let interpreter = zokrates_interpreter::Interpreter::default();
|
||||
|
||||
let _ = interpreter
|
||||
.execute(artifacts.prog(), &[Bn128Field::from(0)])
|
||||
|
@ -257,7 +256,7 @@ mod tests {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
let interpreter = zokrates_interpreter::Interpreter::default();
|
||||
|
||||
let res = interpreter.execute(artifacts.prog(), &[Bn128Field::from(0)]);
|
||||
|
||||
|
|
|
@ -21,20 +21,8 @@ lazy_static! {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
pub const BACKENDS: &[&str] = if cfg!(feature = "libsnark") {
|
||||
if cfg!(feature = "ark") {
|
||||
if cfg!(feature = "bellman") {
|
||||
&[BELLMAN, LIBSNARK, ARK]
|
||||
} else {
|
||||
&[LIBSNARK, ARK]
|
||||
}
|
||||
} else if cfg!(feature = "bellman") {
|
||||
&[BELLMAN, LIBSNARK]
|
||||
} else {
|
||||
&[LIBSNARK]
|
||||
}
|
||||
} else if cfg!(feature = "ark") {
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
pub const BACKENDS: &[&str] = if cfg!(feature = "ark") {
|
||||
if cfg!(feature = "bellman") {
|
||||
&[BELLMAN, ARK]
|
||||
} else {
|
||||
|
@ -48,10 +36,6 @@ pub const BACKENDS: &[&str] = if cfg!(feature = "libsnark") {
|
|||
|
||||
pub const CURVES: &[&str] = &[BN128, BLS12_381, BLS12_377, BW6_761];
|
||||
|
||||
pub const SCHEMES: &[&str] = if cfg!(feature = "libsnark") {
|
||||
&[G16, GM17, PGHR13, MARLIN]
|
||||
} else {
|
||||
&[G16, GM17, MARLIN]
|
||||
};
|
||||
pub const SCHEMES: &[&str] = &[G16, GM17, MARLIN];
|
||||
|
||||
pub const UNIVERSAL_SCHEMES: &[&str] = &[MARLIN];
|
||||
|
|
|
@ -5,10 +5,11 @@ use std::fs::File;
|
|||
use std::io::{stdin, BufReader, BufWriter, Read};
|
||||
use std::path::Path;
|
||||
use zokrates_abi::Encode;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
use zokrates_core::typed_absy::abi::Abi;
|
||||
use zokrates_core::typed_absy::types::{ConcreteSignature, ConcreteType, GTupleType};
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
use zokrates_ast::typed::{
|
||||
abi::Abi,
|
||||
types::{ConcreteSignature, ConcreteType, GTupleType},
|
||||
};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
|
@ -158,7 +159,7 @@ fn cli_compute<T: Field, I: Iterator<Item = ir::Statement<T>>>(
|
|||
}
|
||||
.map_err(|e| format!("Could not parse argument: {}", e))?;
|
||||
|
||||
let interpreter = ir::Interpreter::default();
|
||||
let interpreter = zokrates_interpreter::Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(ir_prog, &arguments.encode())
|
||||
|
|
|
@ -5,8 +5,8 @@ use std::fs::File;
|
|||
use std::io::{BufReader, BufWriter, Write};
|
||||
use std::path::Path;
|
||||
use zokrates_common::helpers::{CurveParameter, SchemeParameter};
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("export-verifier")
|
||||
|
@ -65,10 +65,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
(CurveParameter::Bn128, SchemeParameter::GM17) => {
|
||||
cli_export_verifier::<Bn128Field, GM17>(sub_matches, vk)
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
(CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
cli_export_verifier::<Bn128Field, PGHR13>(sub_matches, vk)
|
||||
}
|
||||
(CurveParameter::Bn128, SchemeParameter::MARLIN) => {
|
||||
cli_export_verifier::<Bn128Field, Marlin>(sub_matches, vk)
|
||||
}
|
||||
|
|
|
@ -4,19 +4,16 @@ use std::convert::TryFrom;
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Read, Write};
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_ark::Ark;
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_core::proof_system::ark::Ark;
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
#[cfg(feature = "libsnark")]
|
||||
use zokrates_core::proof_system::libsnark::Libsnark;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::Field;
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("generate-proof")
|
||||
|
@ -134,24 +131,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
}
|
||||
ProgEnum::Bw6_761Program(p) => cli_generate_proof::<_, _, Marlin, Ark>(p, sub_matches),
|
||||
},
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => {
|
||||
match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
cli_generate_proof::<_, _, GM17, Libsnark>(p, sub_matches)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
cli_generate_proof::<_, _, PGHR13, Libsnark>(p, sub_matches)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Write};
|
||||
use std::path::Path;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::smtlib2::SMTLib2Display;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
use zokrates_ast::ir::{self, smtlib2::SMTLib2Display, ProgEnum};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
|
|
|
@ -3,8 +3,7 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
|
|
|
@ -2,16 +2,16 @@ pub mod check;
|
|||
pub mod compile;
|
||||
pub mod compute_witness;
|
||||
pub mod export_verifier;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
pub mod generate_proof;
|
||||
pub mod generate_smtlib2;
|
||||
pub mod inspect;
|
||||
#[cfg(feature = "bellman")]
|
||||
pub mod mpc;
|
||||
pub mod print_proof;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
pub mod setup;
|
||||
#[cfg(feature = "ark")]
|
||||
pub mod universal_setup;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
pub mod verify;
|
||||
|
|
|
@ -3,10 +3,10 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::path::Path;
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants::{BLS12_381, BN128};
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
use zokrates_core::proof_system::{MpcBackend, MpcScheme, G16};
|
||||
use zokrates_field::{BellmanFieldExtensions, Bls12_381Field, Bn128Field, Field};
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("beacon")
|
||||
|
|
|
@ -3,10 +3,10 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::path::Path;
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants::{BLS12_381, BN128};
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
use zokrates_core::proof_system::{MpcBackend, MpcScheme, G16};
|
||||
use zokrates_field::{BellmanFieldExtensions, Bls12_381Field, Bn128Field, Field};
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("contribute")
|
||||
|
|
|
@ -3,10 +3,10 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Write};
|
||||
use std::path::Path;
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants::{BLS12_381, BN128};
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
use zokrates_core::proof_system::{MpcBackend, MpcScheme, TaggedVerificationKey, G16};
|
||||
use zokrates_field::{BellmanFieldExtensions, Bls12_381Field, Bn128Field, Field};
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, TaggedVerificationKey, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("export")
|
||||
|
|
|
@ -3,11 +3,10 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, BufWriter};
|
||||
use std::path::Path;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
use zokrates_core::proof_system::{MpcBackend, MpcScheme, G16};
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_field::{BellmanFieldExtensions, Field};
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("init")
|
||||
|
|
|
@ -3,11 +3,10 @@ use clap::{App, Arg, ArgMatches, SubCommand};
|
|||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
use zokrates_core::proof_system::{MpcBackend, MpcScheme, G16};
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_field::{BellmanFieldExtensions, Field};
|
||||
use zokrates_proof_systems::{MpcBackend, MpcScheme, G16};
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("verify")
|
||||
|
|
|
@ -5,10 +5,10 @@ use std::fs::File;
|
|||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
use zokrates_common::helpers::{CurveParameter, SchemeParameter};
|
||||
use zokrates_core::proof_system::{
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_proof_systems::{
|
||||
Marlin, Proof, SolidityCompatibleField, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("print-proof")
|
||||
|
|
|
@ -4,19 +4,16 @@ use std::convert::TryFrom;
|
|||
use std::fs::File;
|
||||
use std::io::{BufReader, Write};
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_ark::Ark;
|
||||
use zokrates_ast::ir::{self, ProgEnum};
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
use zokrates_core::ir;
|
||||
use zokrates_core::ir::ProgEnum;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_core::proof_system::ark::Ark;
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
#[cfg(feature = "libsnark")]
|
||||
use zokrates_core::proof_system::libsnark::Libsnark;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::Field;
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("setup")
|
||||
|
@ -165,24 +162,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => {
|
||||
match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
cli_setup_non_universal::<_, _, GM17, Libsnark>(p, sub_matches)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
cli_setup_non_universal::<_, _, PGHR13, Libsnark>(p, sub_matches)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ use std::convert::TryFrom;
|
|||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_ark::Ark;
|
||||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_core::proof_system::ark::Ark;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field};
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("universal-setup")
|
||||
|
|
|
@ -4,17 +4,15 @@ use std::convert::TryFrom;
|
|||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::Path;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_ark::Ark;
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_common::constants;
|
||||
use zokrates_common::helpers::*;
|
||||
#[cfg(feature = "ark")]
|
||||
use zokrates_core::proof_system::ark::Ark;
|
||||
#[cfg(feature = "bellman")]
|
||||
use zokrates_core::proof_system::bellman::Bellman;
|
||||
#[cfg(feature = "libsnark")]
|
||||
use zokrates_core::proof_system::libsnark::Libsnark;
|
||||
#[cfg(any(feature = "bellman", feature = "ark", feature = "libsnark"))]
|
||||
use zokrates_core::proof_system::*;
|
||||
use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Bw6_761Field, Field};
|
||||
#[cfg(any(feature = "bellman", feature = "ark"))]
|
||||
use zokrates_proof_systems::*;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("verify")
|
||||
|
@ -170,14 +168,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
Parameters(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => {
|
||||
cli_verify::<Bw6_761Field, Marlin, Ark>(vk, proof)
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => {
|
||||
cli_verify::<Bn128Field, GM17, Libsnark>(vk, proof)
|
||||
}
|
||||
#[cfg(feature = "libsnark")]
|
||||
Parameters(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
cli_verify::<Bn128Field, PGHR13, Libsnark>(vk, proof)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,12 @@ mod integration {
|
|||
use std::path::Path;
|
||||
use tempdir::TempDir;
|
||||
use zokrates_abi::{parse_strict, Encode};
|
||||
use zokrates_core::proof_system::{
|
||||
use zokrates_ast::typed::abi::Abi;
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_proof_systems::{
|
||||
to_token::ToToken, Marlin, Proof, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
SOLIDITY_G2_ADDITION_LIB,
|
||||
};
|
||||
use zokrates_core::typed_absy::abi::Abi;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
macro_rules! map(
|
||||
{
|
||||
|
@ -233,14 +233,6 @@ mod integration {
|
|||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
let backends = map! {
|
||||
"bellman" => vec!["g16"],
|
||||
"libsnark" => vec!["pghr13"],
|
||||
"ark" => vec!["g16", "gm17", "marlin"]
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "libsnark"))]
|
||||
let backends = map! {
|
||||
"bellman" => vec!["g16"],
|
||||
"ark" => vec!["g16", "gm17", "marlin"]
|
||||
|
|
|
@ -10,7 +10,6 @@ edition = "2018"
|
|||
default = ["bellman", "ark"]
|
||||
bellman = []
|
||||
ark = []
|
||||
libsnark = []
|
||||
|
||||
|
||||
[dependencies]
|
|
@ -1,6 +1,5 @@
|
|||
pub const BELLMAN: &str = "bellman";
|
||||
pub const ARK: &str = "ark";
|
||||
pub const LIBSNARK: &str = "libsnark";
|
||||
|
||||
pub const BN128: &str = "bn128";
|
||||
pub const BLS12_381: &str = "bls12_381";
|
||||
|
|
|
@ -28,8 +28,6 @@ pub enum BackendParameter {
|
|||
Bellman,
|
||||
#[cfg(feature = "ark")]
|
||||
Ark,
|
||||
#[cfg(feature = "libsnark")]
|
||||
Libsnark,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for BackendParameter {
|
||||
|
@ -92,8 +90,6 @@ impl TryFrom<&str> for BackendParameter {
|
|||
BELLMAN => Ok(BackendParameter::Bellman),
|
||||
#[cfg(feature = "ark")]
|
||||
ARK => Ok(BackendParameter::Ark),
|
||||
#[cfg(feature = "libsnark")]
|
||||
LIBSNARK => Ok(BackendParameter::Libsnark),
|
||||
_ => Err(format!("Unknown backend {}", s)),
|
||||
}
|
||||
}
|
||||
|
@ -157,10 +153,6 @@ impl TryFrom<(&str, &str, &str)> for Parameters {
|
|||
(BackendParameter::Ark, CurveParameter::Bls12_377, SchemeParameter::MARLIN) => Ok(()),
|
||||
#[cfg(feature = "ark")]
|
||||
(BackendParameter::Ark, CurveParameter::Bw6_761, SchemeParameter::MARLIN) => Ok(()),
|
||||
#[cfg(feature = "libsnark")]
|
||||
(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::GM17) => Ok(()),
|
||||
#[cfg(feature = "libsnark")]
|
||||
(BackendParameter::Libsnark, CurveParameter::Bn128, SchemeParameter::PGHR13) => Ok(()),
|
||||
_ => Err(format!(
|
||||
"Unsupported combination of parameters (backend: {}, curve: {}, proving scheme: {})",
|
||||
s.0, s.1, s.2
|
||||
|
|
|
@ -5,15 +5,11 @@ edition = "2018"
|
|||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||
repository = "https://github.com/Zokrates/ZoKrates"
|
||||
readme = "README.md"
|
||||
build = "build.rs"
|
||||
|
||||
[features]
|
||||
default = ["bellman", "ark"]
|
||||
libsnark = ["cc", "cmake"]
|
||||
bellman = ["bellman_ce", "pairing_ce", "ff_ce", "zokrates_field/bellman"]
|
||||
wasm = ["bellman_ce/nolog", "bellman_ce/wasm"]
|
||||
multicore = ["bellman_ce/multicore", "phase2/multicore"]
|
||||
ark = ["ark-ff", "ark-ec", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-groth16", "ark-crypto-primitives", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "sha3", "digest"]
|
||||
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]
|
||||
log = "0.4"
|
||||
|
@ -26,48 +22,14 @@ reduce = "0.1.1"
|
|||
# serialization and deserialization
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
serde_cbor = "0.11.2"
|
||||
hex = "0.4.2"
|
||||
regex = "0.2"
|
||||
zokrates_field = { version = "0.5.0", path = "../zokrates_field", default-features = false }
|
||||
zokrates_pest_ast = { version = "0.2.0", path = "../zokrates_pest_ast" }
|
||||
zokrates_common = { path = "../zokrates_common" }
|
||||
zokrates_embed = { version = "0.1.0", path = "../zokrates_embed" }
|
||||
getrandom = { version = "0.2", features = ["js", "wasm-bindgen"] }
|
||||
rand_0_4 = { version = "0.4", package = "rand" }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
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_ast = { version = "0.1", path = "../zokrates_ast", default-features = false }
|
||||
csv = "1"
|
||||
phase2 = { git = "https://github.com/Zokrates/phase2", default-features = false }
|
||||
|
||||
# bellman
|
||||
bellman_ce = { version = "^0.3", default-features = false, optional = true }
|
||||
pairing_ce = { version = "^0.21", optional = true }
|
||||
ff_ce = { version = "^0.9", optional = true }
|
||||
|
||||
# ark
|
||||
ark-ff = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-ec = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-bn254 = { version = "^0.3.0", features = ["curve"], default-features = false, optional = true }
|
||||
ark-bls12-377 = { version = "^0.3.0", features = ["curve"], default-features = false, optional = true }
|
||||
ark-bw6-761 = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-gm17 = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-groth16 = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-serialize = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-relations = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-marlin = { git = "https://github.com/arkworks-rs/marlin", rev = "63cfd82", default-features = false, optional = true }
|
||||
ark-poly = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-poly-commit = { version = "^0.3.0", default-features = false, optional = true }
|
||||
ark-crypto-primitives = { version = "^0.3.0", default-features = false, optional = true }
|
||||
sha3 = { version = "0.9", optional = true }
|
||||
digest = { version = "0.9", optional = true }
|
||||
ethabi = "17.0.0"
|
||||
primitive-types = { version = "0.11", features = ["rlp"] }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "^0.3.0"
|
||||
pretty_assertions = "0.6.1"
|
||||
zokrates_fs_resolver = { version = "0.5", path = "../zokrates_fs_resolver"}
|
||||
|
||||
[build-dependencies]
|
||||
cc = { version = "1.0", features = ["parallel"], optional = true }
|
||||
cmake = { version = "=0.1.45", optional = true }
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
#[cfg(feature = "libsnark")]
|
||||
extern crate cc;
|
||||
#[cfg(feature = "libsnark")]
|
||||
extern crate cmake;
|
||||
|
||||
fn main() {
|
||||
#[cfg(feature = "libsnark")]
|
||||
{
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
// fetch libsnark source
|
||||
const LIBSNARK_URL: &'static str = "https://github.com/scipr-lab/libsnark.git";
|
||||
const LIBSNARK_COMMIT: &'static str = "f7c87b88744ecfd008126d415494d9b34c4c1b20";
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let libsnark_source_path = &out_path.join("libsnark");
|
||||
|
||||
if !libsnark_source_path.exists() {
|
||||
// Clone the repository
|
||||
let _ = Command::new("git")
|
||||
.current_dir(out_path)
|
||||
.args(&["clone", "--no-checkout", LIBSNARK_URL])
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
// Checkout the specific commit
|
||||
let _ = Command::new("git")
|
||||
.current_dir(libsnark_source_path)
|
||||
.args(&["checkout", "-f", LIBSNARK_COMMIT])
|
||||
.status()
|
||||
.unwrap();
|
||||
|
||||
// Unencrypted `git://` protocol is no longer supported on GitHub
|
||||
// so we replace all submodule urls to use `https://`
|
||||
let gitmodules_path = libsnark_source_path.join(".gitmodules");
|
||||
let gitmodules = std::fs::read_to_string(&gitmodules_path)
|
||||
.unwrap()
|
||||
.replace("git://", "https://");
|
||||
|
||||
std::fs::write(&gitmodules_path, gitmodules).unwrap();
|
||||
|
||||
// Update all submodules recursively
|
||||
let _ = Command::new("git")
|
||||
.current_dir(libsnark_source_path)
|
||||
.args(&["submodule", "update", "--init", "--recursive"])
|
||||
.status()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// build libsnark
|
||||
let libsnark = cmake::Config::new(libsnark_source_path)
|
||||
.define("WITH_SUPERCOP", "OFF")
|
||||
.define("WITH_PROCPS", "OFF")
|
||||
.define("WITH_SUPERCOP", "OFF")
|
||||
.define("CURVE", "ALT_BN128")
|
||||
.define("USE_PT_COMPRESSION", "OFF")
|
||||
.define("MONTGOMERY_OUTPUT", "ON")
|
||||
.define("BINARY_OUTPUT", "ON")
|
||||
.define("DMULTICORE", "ON")
|
||||
.build();
|
||||
|
||||
// build backends
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.debug(cfg!(debug_assertions))
|
||||
.flag("-std=c++11")
|
||||
.include(libsnark_source_path)
|
||||
.include(libsnark_source_path.join("depends/libff"))
|
||||
.include(libsnark_source_path.join("depends/libfqfft"))
|
||||
.define("CURVE_ALT_BN128", None)
|
||||
.file("lib/ffi.cpp")
|
||||
.file("lib/gm17.cpp")
|
||||
.file("lib/pghr13.cpp")
|
||||
.compile("libsnark_wrapper.a");
|
||||
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
libsnark.join("lib").display()
|
||||
);
|
||||
|
||||
println!("cargo:rustc-link-lib=gmp");
|
||||
println!("cargo:rustc-link-lib=gmpxx");
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
println!("cargo:rustc-link-lib=static=snarkd");
|
||||
println!("cargo:rustc-link-lib=static=ffd");
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
println!("cargo:rustc-link-lib=static=snark");
|
||||
println!("cargo:rustc-link-lib=static=ff");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#include "ffi.hpp"
|
||||
|
||||
void c_free(uint8_t* ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct buffer_t {
|
||||
uint8_t* data;
|
||||
int32_t length;
|
||||
};
|
||||
|
||||
struct setup_result_t {
|
||||
buffer_t vk;
|
||||
buffer_t pk;
|
||||
setup_result_t(buffer_t& vk_buf, buffer_t& pk_buf)
|
||||
: vk(vk_buf)
|
||||
, pk(pk_buf)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct proof_result_t {
|
||||
buffer_t proof;
|
||||
proof_result_t(buffer_t& proof_buf)
|
||||
: proof(proof_buf)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void c_free(uint8_t* ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
|
@ -1,216 +0,0 @@
|
|||
/**
|
||||
* @file gm17.cpp
|
||||
* @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
* @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
* @date 2017
|
||||
*/
|
||||
|
||||
#include "gm17.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// contains definition of alt_bn128 ec public parameters
|
||||
#include "libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp"
|
||||
|
||||
// contains required interfaces and types (keypair, proof, generator, prover, verifier)
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_se_ppzksnark/r1cs_se_ppzksnark.hpp>
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
#include "util.tcc"
|
||||
|
||||
namespace gm17 {
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_verification_key(r1cs_se_ppzksnark_verification_key<ppT>* vk)
|
||||
{
|
||||
const size_t QUERY_COUNT = vk->query.size();
|
||||
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 2) + (G2_SIZE * 3) + (QUERY_COUNT * G1_SIZE);
|
||||
|
||||
// [ ----------------- LENGTH ------------------ ]
|
||||
// [ h, G_alpha, H_beta, G_gamma, H_gamma, query ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g2_affine<Q, G2>(vk->H, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->G_alpha, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->H_beta, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->G_gamma, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->H_gamma, ptr);
|
||||
|
||||
for (size_t i = 0; i < QUERY_COUNT; ++i)
|
||||
serialize_g1_affine<Q, G1>(vk->query[i], ptr);
|
||||
|
||||
assert(ptr == buffer.data + buffer.length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_proof(r1cs_se_ppzksnark_proof<ppT>* proof)
|
||||
{
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 2) + G2_SIZE;
|
||||
|
||||
// [ ---------- LENGTH ---------- ]
|
||||
// [ G1_SIZE, G2_SIZE, G1_SIZE ]
|
||||
// [ a, b, c ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g1_affine<Q, G1>(proof->A, ptr);
|
||||
serialize_g2_affine<Q, G2>(proof->B, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->C, ptr);
|
||||
|
||||
assert(ptr == buffer.data + buffer.length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
setup_result_t setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32_t a_len, int32_t b_len, int32_t c_len, int32_t constraints, int32_t variables, int32_t inputs)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
auto cs = create_constraint_system<r1cs_se_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
assert(cs.num_variables() >= (unsigned)inputs);
|
||||
assert(cs.num_inputs() == (unsigned)inputs);
|
||||
assert(cs.num_constraints() == (unsigned)constraints);
|
||||
|
||||
r1cs_se_ppzksnark_keypair<ppT> keypair = r1cs_se_ppzksnark_generator<ppT>(cs);
|
||||
|
||||
buffer_t vk_buf = serialize_verification_key<Q, ppT, G1, G2>(&keypair.vk);
|
||||
buffer_t pk_buf = create_buffer(keypair.pk);
|
||||
|
||||
setup_result_t result(vk_buf, pk_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
proof_result_t generate_proof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
r1cs_se_ppzksnark_proving_key<ppT> proving_key;
|
||||
from_buffer<r1cs_se_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
|
||||
r1cs_variable_assignment<libff::Fr<ppT>> full_variable_assignment;
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
for (int i = 0; i < private_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input(
|
||||
full_variable_assignment.begin(),
|
||||
full_variable_assignment.begin() + public_inputs_length - 1);
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> auxiliary_input(
|
||||
full_variable_assignment.begin() + public_inputs_length - 1,
|
||||
full_variable_assignment.end());
|
||||
|
||||
r1cs_se_ppzksnark_proof<ppT> proof = r1cs_se_ppzksnark_prover<ppT>(proving_key, primary_input, auxiliary_input);
|
||||
buffer_t proof_buf = serialize_proof<Q, ppT, G1, G2>(&proof);
|
||||
proof_result_t result(proof_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
uint8_t* ptr = vk_buf->data;
|
||||
const G2 H = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 G_alpha = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 H_beta = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 G_gamma = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 H_gamma = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
|
||||
libff::G1_vector<ppT> query_G1_vector;
|
||||
|
||||
const size_t query_count = ((vk_buf->data + vk_buf->length) - ptr) / (Q * sizeof(mp_limb_t) * 2);
|
||||
for (size_t i = 0; i < query_count; i++) {
|
||||
auto query = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
query_G1_vector.push_back(query);
|
||||
}
|
||||
|
||||
const r1cs_se_ppzksnark_verification_key<ppT> vk(H, G_alpha, H_beta, G_gamma, H_gamma, std::move(query_G1_vector));
|
||||
|
||||
ptr = proof_buf->data;
|
||||
G1 a = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
G2 b = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
G1 c = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
r1cs_se_ppzksnark_proof<ppT> proof(
|
||||
std::move(a),
|
||||
std::move(b),
|
||||
std::move(c));
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input;
|
||||
for (int i = 0; i < public_inputs_length; i++) {
|
||||
primary_input.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
return r1cs_se_ppzksnark_verifier_strong_IC<ppT>(vk, primary_input, proof);
|
||||
}
|
||||
}
|
||||
|
||||
setup_result_t gm17_bn128_setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32_t a_len, int32_t b_len, int32_t c_len, int32_t constraints, int32_t variables, int32_t inputs)
|
||||
{
|
||||
return gm17::setup<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
}
|
||||
|
||||
proof_result_t gm17_bn128_generate_proof(buffer_t* pk_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length,
|
||||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length)
|
||||
{
|
||||
return gm17::generate_proof<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(pk_buf,
|
||||
public_inputs,
|
||||
public_inputs_length,
|
||||
private_inputs,
|
||||
private_inputs_length);
|
||||
}
|
||||
|
||||
bool gm17_bn128_verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
return gm17::verify<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @file gm17.hpp
|
||||
* @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
* @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
* @date 2017
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffi.hpp"
|
||||
|
||||
setup_result_t gm17_bn128_setup(
|
||||
const uint8_t* a,
|
||||
const uint8_t* b,
|
||||
const uint8_t* c,
|
||||
int32_t a_len,
|
||||
int32_t b_len,
|
||||
int32_t c_len,
|
||||
int32_t constraints,
|
||||
int32_t variables,
|
||||
int32_t inputs);
|
||||
|
||||
proof_result_t gm17_bn128_generate_proof(
|
||||
buffer_t* pk_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length,
|
||||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length);
|
||||
|
||||
bool gm17_bn128_verify(
|
||||
buffer_t* vk_buf,
|
||||
buffer_t* proof_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
|
@ -1,240 +0,0 @@
|
|||
/**
|
||||
* @file pghr13.cpp
|
||||
* @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
* @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
* @date 2017
|
||||
*/
|
||||
|
||||
#include "pghr13.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// contains definition of alt_bn128 ec public parameters
|
||||
#include "libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp"
|
||||
// contains required interfaces and types (keypair, proof, generator, prover, verifier)
|
||||
#include <libsnark/common/data_structures/accumulation_vector.hpp>
|
||||
#include <libsnark/knowledge_commitment/knowledge_commitment.hpp>
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
#include "util.tcc"
|
||||
|
||||
namespace pghr13 {
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_verification_key(r1cs_ppzksnark_verification_key<ppT>* vk)
|
||||
{
|
||||
const size_t QUERY_COUNT = vk->encoded_IC_query.rest.indices.size();
|
||||
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 3) + (G2_SIZE * 5) + (QUERY_COUNT * G1_SIZE);
|
||||
|
||||
// [ -------------------- LENGTH --------------------- ]
|
||||
// [ a, b, c, gamma, gamma_beta_1, gamma_beta_2, z, ic ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g2_affine<Q, G2>(vk->alphaA_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->alphaB_g1, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->alphaC_g2, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->gamma_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->gamma_beta_g1, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->gamma_beta_g2, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->rC_Z_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->encoded_IC_query.first, ptr);
|
||||
|
||||
for (size_t i = 0; i < QUERY_COUNT; ++i)
|
||||
serialize_g1_affine<Q, G1>(vk->encoded_IC_query.rest.values[i], ptr);
|
||||
|
||||
assert(ptr == buffer.data + buffer.length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_proof(r1cs_ppzksnark_proof<ppT>* proof)
|
||||
{
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 7) + G2_SIZE;
|
||||
|
||||
// [ ------------- LENGTH -------------- ]
|
||||
// [ a, a_p, b, b_p, c, c_p, h, k ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g1_affine<Q, G1>(proof->g_A.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_A.h, ptr);
|
||||
serialize_g2_affine<Q, G2>(proof->g_B.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_B.h, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_C.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_C.h, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_H, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_K, ptr);
|
||||
|
||||
assert(ptr == buffer.data + buffer.length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
setup_result_t setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32_t a_len, int32_t b_len, int32_t c_len, int32_t constraints, int32_t variables, int32_t inputs)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
auto cs = create_constraint_system<r1cs_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
assert(cs.num_variables() >= (unsigned)inputs);
|
||||
assert(cs.num_inputs() == (unsigned)inputs);
|
||||
assert(cs.num_constraints() == (unsigned)constraints);
|
||||
|
||||
r1cs_ppzksnark_keypair<ppT> keypair = r1cs_ppzksnark_generator<ppT>(cs);
|
||||
|
||||
buffer_t vk_buf = serialize_verification_key<Q, ppT, G1, G2>(&keypair.vk);
|
||||
buffer_t pk_buf = create_buffer(keypair.pk);
|
||||
|
||||
setup_result_t result(vk_buf, pk_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
proof_result_t generate_proof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
r1cs_ppzksnark_proving_key<ppT> proving_key;
|
||||
from_buffer<r1cs_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
|
||||
// assign variables based on witness values, excludes ~one
|
||||
r1cs_variable_assignment<libff::Fr<ppT>> full_variable_assignment;
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
for (int i = 0; i < private_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input(
|
||||
full_variable_assignment.begin(),
|
||||
full_variable_assignment.begin() + public_inputs_length - 1);
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> auxiliary_input(
|
||||
full_variable_assignment.begin() + public_inputs_length - 1,
|
||||
full_variable_assignment.end());
|
||||
|
||||
r1cs_ppzksnark_proof<ppT> proof = r1cs_ppzksnark_prover<ppT>(proving_key, primary_input, auxiliary_input);
|
||||
buffer_t proof_buf = serialize_proof<Q, ppT, G1, G2>(&proof);
|
||||
proof_result_t result(proof_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
||||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
uint8_t* ptr = vk_buf->data;
|
||||
const G2 alphaA_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 alphaB_g1 = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 alphaC_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G2 gamma_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 gamma_beta_g1 = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 gamma_beta_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G2 rC_Z_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
G1 ic_first = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
std::vector<G1> ic_rest;
|
||||
const size_t ic_rest_count = ((vk_buf->data + vk_buf->length) - ptr) / (Q * sizeof(mp_limb_t) * 2);
|
||||
for (size_t i = 0; i < ic_rest_count; i++) {
|
||||
auto ic_query = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
ic_rest.push_back(ic_query);
|
||||
}
|
||||
|
||||
accumulation_vector<G1> eIC(std::move(ic_first), std::move(ic_rest));
|
||||
const r1cs_ppzksnark_verification_key<ppT> vk(alphaA_g2, alphaB_g1, alphaC_g2, gamma_g2, gamma_beta_g1, gamma_beta_g2, rC_Z_g2, eIC);
|
||||
|
||||
ptr = proof_buf->data;
|
||||
const G1 g_A_g = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_A_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 g_B_g = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 g_B_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_C_g = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_C_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
knowledge_commitment<G1, G1> g_A(g_A_g, g_A_h);
|
||||
knowledge_commitment<G2, G1> g_B(g_B_g, g_B_h);
|
||||
knowledge_commitment<G1, G1> g_C(g_C_g, g_C_h);
|
||||
|
||||
G1 g_H = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
G1 g_K = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
const r1cs_ppzksnark_proof<ppT> proof(
|
||||
std::move(g_A),
|
||||
std::move(g_B),
|
||||
std::move(g_C),
|
||||
std::move(g_H),
|
||||
std::move(g_K));
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input;
|
||||
for (int i = 0; i < public_inputs_length; i++) {
|
||||
primary_input.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
return r1cs_ppzksnark_verifier_strong_IC<ppT>(vk, primary_input, proof);
|
||||
}
|
||||
}
|
||||
|
||||
setup_result_t pghr13_bn128_setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32_t a_len, int32_t b_len, int32_t c_len, int32_t constraints, int32_t variables, int32_t inputs)
|
||||
{
|
||||
return pghr13::setup<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
}
|
||||
|
||||
proof_result_t pghr13_bn128_generate_proof(buffer_t* pk_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length,
|
||||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length)
|
||||
{
|
||||
return pghr13::generate_proof<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(pk_buf,
|
||||
public_inputs,
|
||||
public_inputs_length,
|
||||
private_inputs,
|
||||
private_inputs_length);
|
||||
}
|
||||
|
||||
bool pghr13_bn128_verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
return pghr13::verify<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @file pghr13.hpp
|
||||
* @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de
|
||||
* @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
* @date 2017
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffi.hpp"
|
||||
|
||||
setup_result_t pghr13_bn128_setup(
|
||||
const uint8_t* a,
|
||||
const uint8_t* b,
|
||||
const uint8_t* c,
|
||||
int32_t a_len,
|
||||
int32_t b_len,
|
||||
int32_t c_len,
|
||||
int32_t constraints,
|
||||
int32_t variables,
|
||||
int32_t inputs);
|
||||
|
||||
proof_result_t pghr13_bn128_generate_proof(
|
||||
buffer_t* pk_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length,
|
||||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length);
|
||||
|
||||
bool pghr13_bn128_verify(
|
||||
buffer_t* vk_buf,
|
||||
buffer_t* proof_buf,
|
||||
const uint8_t* public_inputs,
|
||||
int32_t public_inputs_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
|
@ -1,187 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "ffi.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// conversion byte[N] -> libsnark bigint
|
||||
template <mp_size_t N>
|
||||
libff::bigint<N> to_libff_bigint(const uint8_t* input)
|
||||
{
|
||||
libff::bigint<N> x;
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
x.data[N - 1 - i] |= uint64_t(input[i * 8 + j]) << (8 * (7 - j));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// conversion libsnark bigint -> byte[N]
|
||||
template <mp_size_t N>
|
||||
void from_libff_bigint(libff::bigint<N> x, uint8_t* out)
|
||||
{
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
out[i * 8 + j] = uint8_t(uint64_t(x.data[N - 1 - i]) >> (8 * (7 - j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename G1>
|
||||
void serialize_g1_affine(G1 point, uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
G1 aff = point;
|
||||
aff.to_affine_coordinates();
|
||||
|
||||
auto x = aff.X.as_bigint();
|
||||
auto y = aff.Y.as_bigint();
|
||||
|
||||
from_libff_bigint<Q>(x, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename G2>
|
||||
void serialize_g2_affine(G2 point, uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
G2 aff = point;
|
||||
aff.to_affine_coordinates();
|
||||
|
||||
auto x0 = aff.X.c0.as_bigint();
|
||||
auto x1 = aff.X.c1.as_bigint();
|
||||
auto y0 = aff.Y.c0.as_bigint();
|
||||
auto y1 = aff.Y.c1.as_bigint();
|
||||
|
||||
from_libff_bigint<Q>(x0, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(x1, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y0, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y1, buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename Fq, typename G1>
|
||||
G1 deserialize_g1_affine(uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
auto x = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
auto y = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
|
||||
return G1(Fq(x), Fq(y), Fq::one());
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename Fq2, typename G2>
|
||||
G2 deserialize_g2_affine(uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
auto x0 = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
auto x1 = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
auto y0 = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
auto y1 = to_libff_bigint<Q>(buffer);
|
||||
buffer += ELEMENT_SIZE;
|
||||
|
||||
auto x = Fq2(x0, x1);
|
||||
auto y = Fq2(y0, y1);
|
||||
return G2(x, y, Fq2::one());
|
||||
}
|
||||
|
||||
template <template <typename ppT> class ConstraintSystem, mp_size_t R, typename ppT>
|
||||
ConstraintSystem<ppT> create_constraint_system(const uint8_t* a,
|
||||
const uint8_t* b,
|
||||
const uint8_t* c,
|
||||
int32_t a_len,
|
||||
int32_t b_len,
|
||||
int32_t c_len,
|
||||
int32_t constraints,
|
||||
int32_t variables,
|
||||
int32_t inputs)
|
||||
{
|
||||
ConstraintSystem<ppT> cs;
|
||||
cs.primary_input_size = inputs;
|
||||
cs.auxiliary_input_size = variables - inputs - 1; // ~one not included
|
||||
|
||||
struct vvmap_t {
|
||||
int constraint_id;
|
||||
int variable_id;
|
||||
uint8_t variable_value[R * sizeof(mp_limb_t)];
|
||||
};
|
||||
|
||||
const vvmap_t* a_vvmap = (vvmap_t*)a;
|
||||
const vvmap_t* b_vvmap = (vvmap_t*)b;
|
||||
const vvmap_t* c_vvmap = (vvmap_t*)c;
|
||||
|
||||
int a_id = 0;
|
||||
int b_id = 0;
|
||||
int c_id = 0;
|
||||
|
||||
for (int row = 0; row < constraints; row++) {
|
||||
linear_combination<libff::Fr<ppT>> lin_comb_a, lin_comb_b, lin_comb_c;
|
||||
while (a_id < a_len && a_vvmap[a_id].constraint_id == row) {
|
||||
libff::bigint<R> value = to_libff_bigint<R>(a_vvmap[a_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_a.add_term(a_vvmap[a_id].variable_id, value);
|
||||
}
|
||||
a_id++;
|
||||
}
|
||||
while (b_id < b_len && b_vvmap[b_id].constraint_id == row) {
|
||||
libff::bigint<R> value = to_libff_bigint<R>(b_vvmap[b_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_b.add_term(b_vvmap[b_id].variable_id, value);
|
||||
}
|
||||
b_id++;
|
||||
}
|
||||
while (c_id < c_len && c_vvmap[c_id].constraint_id == row) {
|
||||
libff::bigint<R> value = to_libff_bigint<R>(c_vvmap[c_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_c.add_term(c_vvmap[c_id].variable_id, value);
|
||||
}
|
||||
c_id++;
|
||||
}
|
||||
cs.add_constraint(r1cs_constraint<libff::Fr<ppT>>(lin_comb_a, lin_comb_b, lin_comb_c));
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void from_buffer(buffer_t* buffer, T& t)
|
||||
{
|
||||
std::string tmp((char*)buffer->data, buffer->length);
|
||||
std::stringstream ss(tmp);
|
||||
ss >> t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline buffer_t create_buffer(T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
|
||||
std::string tmp = ss.str();
|
||||
size_t length = tmp.length();
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(length);
|
||||
buffer.length = length;
|
||||
|
||||
tmp.copy(reinterpret_cast<char*>(buffer.data), buffer.length);
|
||||
return buffer;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue