1
0
Fork 0
mirror of synced 2025-09-23 04:08:33 +00:00

Merge pull request #1151 from Zokrates/split-to-crates

Split project into crates
This commit is contained in:
Thibaut Schaeffer 2022-07-04 17:20:23 +02:00 committed by GitHub
commit 80f4aa4939
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
167 changed files with 3536 additions and 13572 deletions

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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 = []

View file

@ -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 \

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
Split codebase into smaller crates

View file

@ -0,0 +1 @@
Drop support for libsnark

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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"] }

View file

@ -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
View 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
View 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);
}
}

View file

@ -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());

View file

@ -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()
}

View file

@ -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
View 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 }

View file

@ -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();
}
}
}

View 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)
}
}

View 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;

View file

@ -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,
}

View file

@ -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");
}
}

View 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
}

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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());

View file

@ -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
}

View file

@ -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);
}
}

View file

@ -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")

View file

@ -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();

View file

@ -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)
}

View file

@ -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) {}

View file

@ -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
View 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;

View file

@ -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,

View file

@ -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 {

View file

@ -1,4 +1,4 @@
use crate::typed_absy::CanonicalConstantIdentifier;
use crate::typed::CanonicalConstantIdentifier;
use std::convert::TryInto;
use std::fmt;

View file

@ -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]

View file

@ -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(),

View file

@ -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 {

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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,

File diff suppressed because it is too large Load diff

View file

@ -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;

View file

@ -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> {}

View file

@ -1,4 +1,4 @@
use crate::absy::{Node, VariableNode};
use super::{Node, VariableNode};
use std::fmt;
#[derive(Clone, PartialEq)]

View file

@ -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> {

View file

@ -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> {

View file

@ -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 {

View file

@ -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> {

View file

@ -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> {

View file

@ -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)

View 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"] }

View file

@ -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());

View file

@ -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),
)],
};

View file

@ -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:

View file

@ -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"

View file

@ -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)]);

View file

@ -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];

View file

@ -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())

View file

@ -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)
}

View file

@ -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!(),
}
}

View file

@ -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> {

View file

@ -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> {

View file

@ -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;

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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")

View file

@ -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!(),
}
}

View file

@ -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")

View file

@ -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!(),
}
}

View file

@ -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"]

View file

@ -10,7 +10,6 @@ edition = "2018"
default = ["bellman", "ark"]
bellman = []
ark = []
libsnark = []
[dependencies]

View file

@ -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";

View file

@ -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

View file

@ -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 }

View file

@ -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");
}
}
}

View file

@ -1,6 +0,0 @@
#include "ffi.hpp"
void c_free(uint8_t* ptr)
{
free(ptr);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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