mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-09-11 05:45:30 +03:00
Merge pull request #37 from AleoHQ/refactor/group-type
Refactor/group type
This commit is contained in:
commit
f546752cbc
97
Cargo.lock
generated
97
Cargo.lock
generated
@ -99,13 +99,14 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "blake2"
|
||||
version = "0.7.1"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73b77e29dbd0115e43938be2d5128ecf81c0353e00acaa65339a1242586951d9"
|
||||
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
|
||||
dependencies = [
|
||||
"byte-tools 0.2.0",
|
||||
"byte-tools",
|
||||
"crypto-mac",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -115,9 +116,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -126,15 +127,9 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools 0.3.1",
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
@ -208,12 +203,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.7.3"
|
||||
@ -263,32 +252,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.5.2"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958"
|
||||
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
|
||||
dependencies = [
|
||||
"constant_time_eq",
|
||||
"generic-array 0.9.0",
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "1.0.4"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c6d883546668a3e2011b6a716a7330b82eabb0151b138217f632c8243e17135"
|
||||
checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||
dependencies = [
|
||||
"generic-array 0.9.0",
|
||||
"proc-macro2 1.0.9",
|
||||
"quote 1.0.3",
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -297,7 +277,7 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -363,15 +343,6 @@ version = "0.1.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
@ -496,20 +467,6 @@ dependencies = [
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-benchmark"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"from-pest",
|
||||
"leo-compiler",
|
||||
"rand",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
"snarkos-gadgets",
|
||||
"snarkos-models",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leo-compiler"
|
||||
version = "0.1.0"
|
||||
@ -922,7 +879,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -934,7 +891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest 0.8.1",
|
||||
"digest",
|
||||
"fake-simd",
|
||||
"opaque-debug",
|
||||
]
|
||||
@ -966,8 +923,9 @@ version = "0.8.0"
|
||||
dependencies = [
|
||||
"blake2",
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rayon",
|
||||
"sha2",
|
||||
"smallvec",
|
||||
@ -993,10 +951,10 @@ name = "snarkos-errors"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"failure",
|
||||
"hex",
|
||||
"jsonrpc-core",
|
||||
"rocksdb",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1004,7 +962,7 @@ name = "snarkos-gadgets"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"digest 0.7.6",
|
||||
"digest",
|
||||
"snarkos-algorithms",
|
||||
"snarkos-curves",
|
||||
"snarkos-errors",
|
||||
@ -1017,7 +975,6 @@ name = "snarkos-models"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"failure",
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"smallvec",
|
||||
@ -1066,6 +1023,12 @@ dependencies = [
|
||||
"syn 1.0.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
|
@ -13,7 +13,7 @@ name = "leo"
|
||||
path = "leo/main.rs"
|
||||
|
||||
[workspace]
|
||||
members = [ "benchmark", "compiler" ]
|
||||
members = [ "compiler" ]
|
||||
|
||||
[dependencies]
|
||||
leo-compiler = { path = "compiler", version = "0.1.0" }
|
||||
|
@ -1,17 +0,0 @@
|
||||
[package]
|
||||
name = "leo-benchmark"
|
||||
version = "0.1.0"
|
||||
authors = ["The Aleo Team <hello@aleo.org>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
leo-compiler = { path = "../compiler", version = "0.1.0" }
|
||||
|
||||
snarkos-algorithms = { path = "../../snarkOS/algorithms", version = "0.8.0" }
|
||||
snarkos-curves = { path = "../../snarkOS/curves", version = "0.8.0" }
|
||||
snarkos-errors = { path = "../../snarkOS/errors", version = "0.8.0" }
|
||||
snarkos-gadgets = { path = "../../snarkOS/gadgets", version = "0.8.0" }
|
||||
snarkos-models = { path = "../../snarkOS/models", version = "0.8.0" }
|
||||
|
||||
from-pest = { version = "0.3.1" }
|
||||
rand = { version = "0.7" }
|
@ -1,10 +0,0 @@
|
||||
function test(mut a: u32) {
|
||||
a = 0;
|
||||
}
|
||||
|
||||
function main() -> u32 {
|
||||
let a = 1;
|
||||
test(a);
|
||||
|
||||
return a // <- returns 1
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
struct Point {
|
||||
u32 x
|
||||
u32 y
|
||||
}
|
||||
|
||||
function test() -> (u32) {
|
||||
return 5
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
use leo_compiler::{self, ast, errors::CompilerError, InputValue, Program};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use rand::thread_rng;
|
||||
use snarkos_algorithms::snark::{
|
||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||
};
|
||||
use snarkos_curves::bls12_377::{Bls12_377, Fr};
|
||||
use snarkos_curves::edwards_bls12::EdwardsProjective;
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::curves::Group;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
|
||||
};
|
||||
use std::{
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Benchmark<F: Field + PrimeField, G: Group> {
|
||||
program: Program<F, G>,
|
||||
parameters: Vec<Option<InputValue<F, G>>>,
|
||||
_group: PhantomData<G>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Benchmark<F, G> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
program: Program::new(),
|
||||
parameters: vec![],
|
||||
_group: PhantomData,
|
||||
_engine: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn evaluate_program(&mut self) -> Result<(), CompilerError> {
|
||||
// Read in file as string
|
||||
let unparsed_file = fs::read_to_string("simple.leo").expect("cannot read file");
|
||||
|
||||
// Parse the file using leo.pest
|
||||
let mut file = ast::parse(&unparsed_file).expect("unsuccessful parse");
|
||||
|
||||
// Build the abstract syntax tree
|
||||
let syntax_tree = ast::File::from_pest(&mut file).expect("infallible");
|
||||
|
||||
// Build a leo program from the syntax tree
|
||||
self.program = Program::<F, G>::from(syntax_tree, "simple".into());
|
||||
self.parameters = vec![None; self.program.num_parameters];
|
||||
|
||||
println!(" compiled: {:#?}\n", self.program);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> ConstraintSynthesizer<F> for Benchmark<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _res = leo_compiler::generate_constraints(cs, self.program, self.parameters).unwrap();
|
||||
println!(" Result: {}", _res);
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut setup = Duration::new(0, 0);
|
||||
let mut proving = Duration::new(0, 0);
|
||||
let mut verifying = Duration::new(0, 0);
|
||||
|
||||
let rng = &mut thread_rng();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// Load and compile program
|
||||
let mut program = Benchmark::<Fr, EdwardsProjective>::new();
|
||||
program.evaluate_program().unwrap();
|
||||
|
||||
// Generate proof parameters
|
||||
let params = { generate_random_parameters::<Bls12_377, _, _>(program.clone(), rng).unwrap() };
|
||||
|
||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶ms.vk);
|
||||
|
||||
setup += start.elapsed();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// Set main function arguments in compiled program
|
||||
// let argument = Some(InputValue::Field(Fr::one()));
|
||||
|
||||
// let bool_true = InputValue::Boolean(true);
|
||||
// let array = InputValue::Array(vec![bool_true.clone(), bool_true.clone(), bool_true.clone()]);
|
||||
// let argument = Some(array);
|
||||
//
|
||||
// program.parameters = vec![argument];
|
||||
|
||||
// Generate proof
|
||||
let proof = create_random_proof(program, ¶ms, rng).unwrap();
|
||||
|
||||
proving += start.elapsed();
|
||||
|
||||
let start = Instant::now();
|
||||
|
||||
// let public_input = Fr::one();
|
||||
|
||||
// Verify proof
|
||||
let is_success = verify_proof(&prepared_verifying_key, &proof, &[]).unwrap();
|
||||
|
||||
verifying += start.elapsed();
|
||||
|
||||
println!(" ");
|
||||
println!(" Setup time : {:?} milliseconds", setup.as_millis());
|
||||
println!(" Prover time : {:?} milliseconds", proving.as_millis());
|
||||
println!(
|
||||
" Verifier time : {:?} milliseconds",
|
||||
verifying.as_millis()
|
||||
);
|
||||
println!(" Verifier output : {}", is_success);
|
||||
println!(" ");
|
||||
|
||||
// let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
//
|
||||
// println!("\n satisfied: {:?}", cs.is_satisfied());
|
||||
//
|
||||
// println!(
|
||||
// "\n number of constraints for input: {}",
|
||||
// cs.num_constraints()
|
||||
// );
|
||||
//
|
||||
}
|
@ -291,10 +291,41 @@ impl<'ast> fmt::Display for Field<'ast> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::group_tuple))]
|
||||
pub struct GroupTuple<'ast> {
|
||||
pub x: Number<'ast>,
|
||||
pub y: Number<'ast>,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for GroupTuple<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::group_single_or_tuple))]
|
||||
pub enum GroupValue<'ast> {
|
||||
Single(Number<'ast>),
|
||||
Tuple(GroupTuple<'ast>),
|
||||
}
|
||||
|
||||
impl<'ast> fmt::Display for GroupValue<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GroupValue::Single(number) => write!(f, "{}", number),
|
||||
GroupValue::Tuple(tuple) => write!(f, "{}", tuple),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, FromPest, PartialEq)]
|
||||
#[pest_ast(rule(Rule::value_group))]
|
||||
pub struct Group<'ast> {
|
||||
pub number: Number<'ast>,
|
||||
pub value: GroupValue<'ast>,
|
||||
pub _type: GroupType,
|
||||
#[pest_ast(outer())]
|
||||
pub span: Span<'ast>,
|
||||
@ -302,7 +333,7 @@ pub struct Group<'ast> {
|
||||
|
||||
impl<'ast> fmt::Display for Group<'ast> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.number)
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,12 @@ use crate::{
|
||||
ast,
|
||||
constraints::{generate_constraints, ConstrainedValue},
|
||||
errors::CompilerError,
|
||||
InputValue, Program,
|
||||
GroupType, InputValue, Program,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSynthesizer, ConstraintSystem},
|
||||
};
|
||||
|
||||
@ -18,16 +18,16 @@ use sha2::{Digest, Sha256};
|
||||
use std::{fs, marker::PhantomData, path::PathBuf};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Compiler<F: Field + PrimeField, G: Group> {
|
||||
pub struct Compiler<F: Field + PrimeField, G: GroupType<F>> {
|
||||
package_name: String,
|
||||
main_file_path: PathBuf,
|
||||
program: Program<F, G>,
|
||||
program_inputs: Vec<Option<InputValue<F, G>>>,
|
||||
program: Program<F>,
|
||||
program_inputs: Vec<Option<InputValue<F>>>,
|
||||
output: Option<ConstrainedValue<F, G>>,
|
||||
_engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
|
||||
pub fn init(package_name: String, main_file_path: PathBuf) -> Result<Self, CompilerError> {
|
||||
let mut program = Self {
|
||||
package_name,
|
||||
@ -44,7 +44,7 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue<F, G>>>) {
|
||||
pub fn set_inputs(&mut self, program_inputs: Vec<Option<InputValue<F>>>) {
|
||||
self.program_inputs = program_inputs;
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
// Build program from abstract syntax tree
|
||||
let package_name = self.package_name.clone();
|
||||
|
||||
self.program = Program::<F, G>::from(syntax_tree, package_name);
|
||||
self.program = Program::<F>::from(syntax_tree, package_name);
|
||||
self.program_inputs = vec![None; self.program.num_parameters];
|
||||
|
||||
log::debug!("Program parsing complete\n{:#?}", self.program);
|
||||
@ -107,12 +107,13 @@ impl<F: Field + PrimeField, G: Group> Compiler<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstraintSynthesizer<F> for Compiler<F, G> {
|
||||
fn generate_constraints<CS: ConstraintSystem<F>>(
|
||||
self,
|
||||
cs: &mut CS,
|
||||
) -> Result<(), SynthesisError> {
|
||||
let _result = generate_constraints(cs, self.program, self.program_inputs).unwrap();
|
||||
let _result =
|
||||
generate_constraints::<_, G, _>(cs, self.program, self.program_inputs).unwrap();
|
||||
|
||||
// Write results to file or something
|
||||
|
||||
|
@ -4,24 +4,25 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::BooleanError,
|
||||
types::InputValue,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, boolean::Boolean, eq::EqGadget},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn bool_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, BooleanError> {
|
||||
// Check that the input value is the correct type
|
||||
let bool_value = match input_value {
|
||||
|
@ -8,25 +8,25 @@ use crate::{
|
||||
CircuitFieldDefinition, CircuitMember, Expression, Identifier, RangeOrExpression,
|
||||
SpreadOrExpression,
|
||||
},
|
||||
Integer, IntegerType, Type,
|
||||
GroupType, Integer, IntegerType, Type,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{boolean::Boolean, select::CondSelectGadget},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
/// Enforce a variable expression by getting the resolved value
|
||||
pub(crate) fn evaluate_identifier(
|
||||
&mut self,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
unresolved_identifier: Identifier<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
unresolved_identifier: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Evaluate the identifier name in the current function scope
|
||||
let variable_name = new_scope(function_scope, unresolved_identifier.to_string());
|
||||
@ -63,8 +63,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
Ok(self.enforce_field_add(cs, fe_1, fe_2)?)
|
||||
}
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Ok(Self::evaluate_group_add(ge_1, ge_2))
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Group(ge_1.add(cs, &ge_2)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
@ -94,8 +94,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
Ok(self.enforce_field_sub(cs, fe_1, fe_2)?)
|
||||
}
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Ok(Self::evaluate_group_sub(ge_1, ge_2))
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Group(ge_1.sub(cs, &ge_2)?))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
@ -125,9 +125,6 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
Ok(self.enforce_field_mul(cs, fe_1, fe_2)?)
|
||||
}
|
||||
// (ConstrainedValue::GroupElement(group), ConstrainedValue::FieldElement(scalar)) => {
|
||||
// Ok(Self::evaluate_group_mul(group, scalar))
|
||||
// }
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
self.enforce_mul_expression(cs, val_1, val_2)
|
||||
@ -221,8 +218,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
// (ResolvedValue::FieldElement(fe_1), ResolvedValue::FieldElement(fe_2)) => {
|
||||
// Self::field_eq(fe_1, fe_2)
|
||||
// }
|
||||
(ConstrainedValue::GroupElement(ge_1), ConstrainedValue::GroupElement(ge_2)) => {
|
||||
Ok(Self::evaluate_group_eq(ge_1, ge_2))
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
Ok(ConstrainedValue::Boolean(Boolean::Constant(ge_1.eq(&ge_2))))
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2)?;
|
||||
@ -341,10 +338,10 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
first: Expression<F, G>,
|
||||
second: Expression<F, G>,
|
||||
third: Expression<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
first: Expression<F>,
|
||||
second: Expression<F>,
|
||||
third: Expression<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let resolved_first = match self.enforce_expression(
|
||||
cs,
|
||||
@ -377,9 +374,10 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
Integer::conditionally_select(cs, &resolved_first, &integer_2, &integer_3)?;
|
||||
Ok(ConstrainedValue::Integer(result))
|
||||
}
|
||||
// (ConstrainedValue::GroupElement(group_2), ConstrainedValue::GroupElement(group_3)) => {
|
||||
// let result = Group
|
||||
// }
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
let result = G::conditionally_select(cs, &resolved_first, &ge_1, &ge_2)?;
|
||||
Ok(ConstrainedValue::Group(result))
|
||||
}
|
||||
(_, _) => {
|
||||
unimplemented!("conditional select gadget not implemented between given types")
|
||||
}
|
||||
@ -392,8 +390,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
array: Vec<Box<SpreadOrExpression<F, G>>>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
array: Vec<Box<SpreadOrExpression<F>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Check explicit array type dimension if given
|
||||
let mut expected_types = expected_types.clone();
|
||||
@ -456,7 +454,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
index: Expression<F, G>,
|
||||
index: Expression<F>,
|
||||
) -> Result<usize, ExpressionError> {
|
||||
let expected_types = vec![Type::IntegerType(IntegerType::U32)];
|
||||
match self.enforce_branch(
|
||||
@ -476,9 +474,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
array: Box<Expression<F, G>>,
|
||||
index: RangeOrExpression<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
array: Box<Expression<F>>,
|
||||
index: RangeOrExpression<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let array = match self.enforce_branch(
|
||||
cs,
|
||||
@ -517,8 +515,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
identifier: Identifier<F, G>,
|
||||
members: Vec<CircuitFieldDefinition<F, G>>,
|
||||
identifier: Identifier<F>,
|
||||
members: Vec<CircuitFieldDefinition<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut program_identifier = new_scope(file_scope.clone(), identifier.to_string());
|
||||
|
||||
@ -591,9 +589,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
circuit_identifier: Box<Expression<F, G>>,
|
||||
circuit_member: Identifier<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
circuit_identifier: Box<Expression<F>>,
|
||||
circuit_member: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let (circuit_name, members) = match self.enforce_branch(
|
||||
cs,
|
||||
@ -652,9 +650,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
circuit_identifier: Box<Expression<F, G>>,
|
||||
circuit_member: Identifier<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
circuit_identifier: Box<Expression<F>>,
|
||||
circuit_member: Identifier<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
// Get defined circuit
|
||||
let circuit = match self.enforce_expression(
|
||||
@ -706,9 +704,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
function: Box<Expression<F, G>>,
|
||||
arguments: Vec<Expression<F, G>>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
function: Box<Expression<F>>,
|
||||
arguments: Vec<Expression<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let function_value = self.enforce_expression(
|
||||
cs,
|
||||
@ -745,7 +743,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
}
|
||||
|
||||
pub(crate) fn enforce_number_implicit(
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
value: String,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
if expected_types.len() == 1 {
|
||||
@ -763,8 +761,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
expression: Expression<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
let mut branch =
|
||||
self.enforce_expression(cs, file_scope, function_scope, expected_types, expression)?;
|
||||
@ -780,9 +778,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
left: Expression<F, G>,
|
||||
right: Expression<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
left: Expression<F>,
|
||||
right: Expression<F>,
|
||||
) -> Result<(ConstrainedValue<F, G>, ConstrainedValue<F, G>), ExpressionError> {
|
||||
let resolved_left = self.enforce_branch(
|
||||
cs,
|
||||
@ -807,8 +805,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expected_types: &Vec<Type<F, G>>,
|
||||
expression: Expression<F, G>,
|
||||
expected_types: &Vec<Type<F>>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, ExpressionError> {
|
||||
match expression {
|
||||
// Variables
|
||||
@ -822,7 +820,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
// Values
|
||||
Expression::Integer(integer) => Ok(Self::get_integer_constant(integer)),
|
||||
Expression::FieldElement(fe) => Ok(Self::get_field_element_constant(fe)),
|
||||
Expression::GroupElement(gr) => Ok(ConstrainedValue::GroupElement(gr)),
|
||||
Expression::Group(group_affine) => {
|
||||
Ok(ConstrainedValue::Group(G::constant(group_affine)?))
|
||||
}
|
||||
Expression::Boolean(bool) => Ok(Self::get_boolean_constant(bool)),
|
||||
Expression::Implicit(value) => Self::enforce_number_implicit(expected_types, value),
|
||||
|
||||
|
@ -4,21 +4,22 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::FieldElementError,
|
||||
types::{FieldElement, InputValue, Integer},
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::{ConstraintSystem, LinearCombination, Variable as R1CSVariable},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn field_element_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FieldElementError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let field_option = match input_value {
|
||||
|
@ -4,15 +4,17 @@
|
||||
use crate::{
|
||||
constraints::{new_scope, ConstrainedProgram, ConstrainedValue},
|
||||
errors::{FunctionError, ImportError},
|
||||
group_from_input,
|
||||
types::{Expression, Function, Identifier, InputValue, Program, Type},
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn check_arguments_length(expected: usize, actual: usize) -> Result<(), FunctionError> {
|
||||
// Make sure we are given the correct number of arguments
|
||||
if expected != actual {
|
||||
@ -28,8 +30,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
scope: String,
|
||||
caller_scope: String,
|
||||
function_name: String,
|
||||
expected_types: Vec<Type<F, G>>,
|
||||
input: Expression<F, G>,
|
||||
expected_types: Vec<Type<F>>,
|
||||
input: Expression<F>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
// Evaluate the function input value as pass by value from the caller or
|
||||
// evaluate as an expression in the current function scope
|
||||
@ -55,8 +57,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
caller_scope: String,
|
||||
function: Function<F, G>,
|
||||
inputs: Vec<Expression<F, G>>,
|
||||
function: Function<F>,
|
||||
inputs: Vec<Expression<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
@ -116,9 +118,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
array_type: Type<F, G>,
|
||||
array_type: Type<F>,
|
||||
array_dimensions: Vec<usize>,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let expected_length = array_dimensions[0];
|
||||
let mut array_value = vec![];
|
||||
@ -168,10 +170,10 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
fn allocate_main_function_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
_type: Type<F, G>,
|
||||
_type: Type<F>,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
match _type {
|
||||
Type::IntegerType(integer_type) => {
|
||||
@ -180,9 +182,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
Type::FieldElement => {
|
||||
Ok(self.field_element_from_input(cs, name, private, input_value)?)
|
||||
}
|
||||
Type::GroupElement => {
|
||||
Ok(self.group_element_from_input(cs, name, private, input_value)?)
|
||||
}
|
||||
Type::Group => Ok(group_from_input(cs, name, private, input_value)?),
|
||||
Type::Boolean => Ok(self.bool_from_input(cs, name, private, input_value)?),
|
||||
Type::Array(_type, dimensions) => {
|
||||
self.allocate_array(cs, name, private, *_type, dimensions, input_value)
|
||||
@ -195,8 +195,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
function: Function<F, G>,
|
||||
inputs: Vec<Option<InputValue<F, G>>>,
|
||||
function: Function<F>,
|
||||
inputs: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, FunctionError> {
|
||||
let function_name = new_scope(scope.clone(), function.get_name());
|
||||
|
||||
@ -231,7 +231,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
pub(crate) fn resolve_definitions(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
program: Program<F, G>,
|
||||
program: Program<F>,
|
||||
) -> Result<(), ImportError> {
|
||||
let program_name = program.name.clone();
|
||||
|
||||
|
39
compiler/src/constraints/group.rs
Normal file
39
compiler/src/constraints/group.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use crate::{errors::GroupError, ConstrainedValue, GroupType, InputValue};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
pub(crate) fn group_from_input<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
name: String,
|
||||
private: bool,
|
||||
input_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, GroupError> {
|
||||
// Check that the parameter value is the correct type
|
||||
let group_option = match input_value {
|
||||
Some(input) => {
|
||||
if let InputValue::Group(group_string) = input {
|
||||
Some(group_string)
|
||||
} else {
|
||||
return Err(GroupError::Invalid(input.to_string()));
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Check visibility of parameter
|
||||
let group_value = if private {
|
||||
G::alloc(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
} else {
|
||||
G::alloc_input(cs.ns(|| name), || {
|
||||
group_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})?
|
||||
};
|
||||
|
||||
Ok(ConstrainedValue::Group(group_value))
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
use crate::errors::GroupElementError;
|
||||
use crate::{ConstrainedProgram, ConstrainedValue, InputValue};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn group_element_from_input(
|
||||
&mut self,
|
||||
_cs: &mut CS,
|
||||
_name: String,
|
||||
_private: bool,
|
||||
input_value: Option<InputValue<F, G>>,
|
||||
) -> Result<ConstrainedValue<F, G>, GroupElementError> {
|
||||
// Check that the parameter value is the correct type
|
||||
// let group_option = match input_value {
|
||||
// Some(input) => {
|
||||
// if let InputValue::Group(group) = input {
|
||||
// Some(group)
|
||||
// } else {
|
||||
// return Err(GroupElementError::InvalidGroup(input.to_string()));
|
||||
// }
|
||||
// }
|
||||
// None => None,
|
||||
// };
|
||||
//
|
||||
// // Check visibility of parameter
|
||||
// let group_value = if private {
|
||||
// cs.alloc(
|
||||
// || name,
|
||||
// || group_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
// )?
|
||||
// } else {
|
||||
// cs.alloc_input(
|
||||
// || name,
|
||||
// || group_option.ok_or(SynthesisError::AssignmentMissing),
|
||||
// )?
|
||||
// };
|
||||
//
|
||||
// Ok(ConstrainedValue::GroupElement())
|
||||
|
||||
// TODO: use group gadget to allocate groups
|
||||
if let Some(InputValue::Group(group)) = input_value {
|
||||
return Ok(ConstrainedValue::GroupElement(group));
|
||||
}
|
||||
|
||||
Ok(ConstrainedValue::GroupElement(G::default()))
|
||||
}
|
||||
|
||||
pub fn evaluate_group_eq(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Boolean(Boolean::constant(group_element_1.eq(&group_element_2)))
|
||||
}
|
||||
|
||||
pub fn evaluate_group_add(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::GroupElement(group_element_1.add(&group_element_2))
|
||||
}
|
||||
|
||||
pub fn evaluate_group_sub(group_element_1: G, group_element_2: G) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::GroupElement(group_element_1.sub(&group_element_2))
|
||||
}
|
||||
//
|
||||
// pub fn evaluate_group_mul(group_element: G, scalar_field: G::ScalarField) -> ConstrainedValue<F, G> {
|
||||
// ConstrainedValue::GroupElement(group_element.mul(&scalar_field))
|
||||
// }
|
||||
}
|
@ -4,23 +4,22 @@ use crate::{
|
||||
errors::constraints::ImportError,
|
||||
new_scope,
|
||||
types::Program,
|
||||
Import,
|
||||
GroupType, Import,
|
||||
};
|
||||
|
||||
use from_pest::FromPest;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
use std::env::current_dir;
|
||||
use std::fs;
|
||||
use std::{env::current_dir, fs};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn enforce_import(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
scope: String,
|
||||
import: Import<F, G>,
|
||||
import: Import<F>,
|
||||
) -> Result<(), ImportError> {
|
||||
let path = current_dir().map_err(|error| ImportError::DirectoryError(error))?;
|
||||
|
||||
|
@ -4,12 +4,12 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::{InputValue, Integer},
|
||||
IntegerType,
|
||||
GroupType, IntegerType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{
|
||||
@ -73,7 +73,7 @@ impl<F: Field + PrimeField> CondSelectGadget<F> for Integer {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn get_integer_constant(integer: Integer) -> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::Integer(integer)
|
||||
}
|
||||
@ -105,7 +105,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
integer_type: IntegerType,
|
||||
name: String,
|
||||
private: bool,
|
||||
integer_value: Option<InputValue<F, G>>,
|
||||
integer_value: Option<InputValue<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, IntegerError> {
|
||||
// Check that the input value is the correct type
|
||||
let integer_option = match integer_value {
|
||||
|
@ -4,18 +4,19 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::Integer,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint128::UInt128},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u128_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -4,18 +4,19 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::Integer,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint16::UInt16},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u16_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -4,18 +4,19 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::Integer,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint32::UInt32},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u32_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -4,18 +4,19 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::Integer,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint64::UInt64},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u64_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -4,18 +4,19 @@ use crate::{
|
||||
constraints::{ConstrainedProgram, ConstrainedValue},
|
||||
errors::IntegerError,
|
||||
types::Integer,
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{alloc::AllocGadget, eq::EqGadget, uint8::UInt8},
|
||||
},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub(crate) fn u8_from_input(
|
||||
&mut self,
|
||||
cs: &mut CS,
|
||||
|
@ -18,8 +18,8 @@ pub use integer::*;
|
||||
pub mod field_element;
|
||||
pub use field_element::*;
|
||||
|
||||
pub mod group_element;
|
||||
pub use group_element::*;
|
||||
pub(crate) mod group;
|
||||
pub(crate) use group::*;
|
||||
|
||||
pub mod program;
|
||||
pub use program::*;
|
||||
@ -33,17 +33,18 @@ pub use statement::*;
|
||||
use crate::{
|
||||
errors::CompilerError,
|
||||
types::{InputValue, Program},
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
|
||||
pub fn generate_constraints<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>>(
|
||||
pub fn generate_constraints<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>>(
|
||||
cs: &mut CS,
|
||||
program: Program<F, G>,
|
||||
parameters: Vec<Option<InputValue<F, G>>>,
|
||||
program: Program<F>,
|
||||
parameters: Vec<Option<InputValue<F>>>,
|
||||
) -> Result<ConstrainedValue<F, G>, CompilerError> {
|
||||
let mut resolved_program = ConstrainedProgram::new();
|
||||
let program_name = program.get_name();
|
||||
|
@ -1,14 +1,14 @@
|
||||
//! An in memory store to keep track of defined names when constraining a Leo program.
|
||||
|
||||
use crate::constraints::ConstrainedValue;
|
||||
use crate::{constraints::ConstrainedValue, GroupType};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::r1cs::ConstraintSystem,
|
||||
};
|
||||
use std::{collections::HashMap, marker::PhantomData};
|
||||
|
||||
pub struct ConstrainedProgram<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> {
|
||||
pub struct ConstrainedProgram<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> {
|
||||
pub identifiers: HashMap<String, ConstrainedValue<F, G>>,
|
||||
pub _cs: PhantomData<CS>,
|
||||
}
|
||||
@ -17,7 +17,7 @@ pub fn new_scope(outer: String, inner: String) -> String {
|
||||
format!("{}_{}", outer, inner)
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
identifiers: HashMap::new(),
|
||||
|
@ -8,16 +8,16 @@ use crate::{
|
||||
Assignee, ConditionalNestedOrEnd, ConditionalStatement, Expression, Identifier, Integer,
|
||||
RangeOrExpression, Statement, Type,
|
||||
},
|
||||
Variable,
|
||||
GroupType, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{r1cs::ConstraintSystem, utilities::boolean::Boolean, utilities::uint32::UInt32},
|
||||
};
|
||||
|
||||
impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F, G>) -> String {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<F>> ConstrainedProgram<F, G, CS> {
|
||||
fn resolve_assignee(&mut self, scope: String, assignee: Assignee<F>) -> String {
|
||||
match assignee {
|
||||
Assignee::Identifier(name) => new_scope(scope, name.to_string()),
|
||||
Assignee::Array(array, _index) => self.resolve_assignee(scope, *array),
|
||||
@ -47,7 +47,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
name: String,
|
||||
range_or_expression: RangeOrExpression<F, G>,
|
||||
range_or_expression: RangeOrExpression<F>,
|
||||
new_value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Resolve index so we know if we are assigning to a single value or a range of values
|
||||
@ -91,7 +91,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
fn mutute_circuit_field(
|
||||
&mut self,
|
||||
circuit_name: String,
|
||||
object_name: Identifier<F, G>,
|
||||
object_name: Identifier<F>,
|
||||
new_value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
match self.get_mutable_assignee(circuit_name)? {
|
||||
@ -129,8 +129,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
assignee: Assignee<F, G>,
|
||||
expression: Expression<F, G>,
|
||||
assignee: Assignee<F>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Get the name of the variable we are assigning to
|
||||
let variable_name = self.resolve_assignee(function_scope.clone(), assignee.clone());
|
||||
@ -170,7 +170,7 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
fn store_definition(
|
||||
&mut self,
|
||||
function_scope: String,
|
||||
variable: Variable<F, G>,
|
||||
variable: Variable<F>,
|
||||
mut value: ConstrainedValue<F, G>,
|
||||
) -> Result<(), StatementError> {
|
||||
// Store with given mutability
|
||||
@ -190,8 +190,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
variable: Variable<F, G>,
|
||||
expression: Expression<F, G>,
|
||||
variable: Variable<F>,
|
||||
expression: Expression<F>,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
if let Some(ref _type) = variable._type {
|
||||
@ -213,8 +213,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
variables: Vec<Variable<F, G>>,
|
||||
function: Expression<F, G>,
|
||||
variables: Vec<Variable<F>>,
|
||||
function: Expression<F>,
|
||||
) -> Result<(), StatementError> {
|
||||
let mut expected_types = vec![];
|
||||
for variable in variables.iter() {
|
||||
@ -256,8 +256,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
expressions: Vec<Expression<F, G>>,
|
||||
return_types: Vec<Type<F, G>>,
|
||||
expressions: Vec<Expression<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<ConstrainedValue<F, G>, StatementError> {
|
||||
// Make sure we return the correct number of values
|
||||
if return_types.len() != expressions.len() {
|
||||
@ -289,8 +289,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statements: Vec<Statement<F, G>>,
|
||||
return_types: Vec<Type<F, G>>,
|
||||
statements: Vec<Statement<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
// Evaluate statements and possibly return early
|
||||
@ -315,8 +315,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statement: ConditionalStatement<F, G>,
|
||||
return_types: Vec<Type<F, G>>,
|
||||
statement: ConditionalStatement<F>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let expected_types = vec![Type::Boolean];
|
||||
let condition = match self.enforce_expression(
|
||||
@ -367,11 +367,11 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
index: Identifier<F, G>,
|
||||
index: Identifier<F>,
|
||||
start: Integer,
|
||||
stop: Integer,
|
||||
statements: Vec<Statement<F, G>>,
|
||||
return_types: Vec<Type<F, G>>,
|
||||
statements: Vec<Statement<F>>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
|
||||
@ -416,6 +416,9 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
(ConstrainedValue::FieldElement(fe_1), ConstrainedValue::FieldElement(fe_2)) => {
|
||||
self.enforce_field_eq(cs, fe_1, fe_2)
|
||||
}
|
||||
(ConstrainedValue::Group(ge_1), ConstrainedValue::Group(ge_2)) => {
|
||||
ge_1.enforce_equal(cs, &ge_2)?
|
||||
}
|
||||
(ConstrainedValue::Array(arr_1), ConstrainedValue::Array(arr_2)) => {
|
||||
for (left, right) in arr_1.into_iter().zip(arr_2.into_iter()) {
|
||||
self.enforce_assert_eq_statement(cs, left, right)?;
|
||||
@ -440,8 +443,8 @@ impl<F: Field + PrimeField, G: Group, CS: ConstraintSystem<F>> ConstrainedProgra
|
||||
cs: &mut CS,
|
||||
file_scope: String,
|
||||
function_scope: String,
|
||||
statement: Statement<F, G>,
|
||||
return_types: Vec<Type<F, G>>,
|
||||
statement: Statement<F>,
|
||||
return_types: Vec<Type<F>>,
|
||||
) -> Result<Option<ConstrainedValue<F, G>>, StatementError> {
|
||||
let mut res = None;
|
||||
match statement {
|
||||
|
@ -3,10 +3,11 @@
|
||||
use crate::{
|
||||
errors::ValueError,
|
||||
types::{Circuit, FieldElement, Function, Identifier, Integer, IntegerType, Type},
|
||||
GroupType,
|
||||
};
|
||||
|
||||
use snarkos_models::{
|
||||
curves::{Field, Group, PrimeField},
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::utilities::{
|
||||
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
|
||||
uint8::UInt8,
|
||||
@ -15,24 +16,24 @@ use snarkos_models::{
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: Group>(
|
||||
pub Identifier<F, G>,
|
||||
pub struct ConstrainedCircuitMember<F: Field + PrimeField, G: GroupType<F>>(
|
||||
pub Identifier<F>,
|
||||
pub ConstrainedValue<F, G>,
|
||||
);
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum ConstrainedValue<F: Field + PrimeField, G: Group> {
|
||||
pub enum ConstrainedValue<F: Field + PrimeField, G: GroupType<F>> {
|
||||
Integer(Integer),
|
||||
FieldElement(FieldElement<F>),
|
||||
GroupElement(G),
|
||||
Group(G),
|
||||
Boolean(Boolean),
|
||||
|
||||
Array(Vec<ConstrainedValue<F, G>>),
|
||||
|
||||
CircuitDefinition(Circuit<F, G>),
|
||||
CircuitExpression(Identifier<F, G>, Vec<ConstrainedCircuitMember<F, G>>),
|
||||
CircuitDefinition(Circuit<F>),
|
||||
CircuitExpression(Identifier<F>, Vec<ConstrainedCircuitMember<F, G>>),
|
||||
|
||||
Function(Option<Identifier<F, G>>, Function<F, G>), // (optional circuit identifier, function definition)
|
||||
Function(Option<Identifier<F>>, Function<F>), // (optional circuit identifier, function definition)
|
||||
Return(Vec<ConstrainedValue<F, G>>),
|
||||
|
||||
Mutable(Box<ConstrainedValue<F, G>>),
|
||||
@ -40,7 +41,7 @@ pub enum ConstrainedValue<F: Field + PrimeField, G: Group> {
|
||||
Unresolved(String),
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedValue<F, G> {
|
||||
pub(crate) fn from_other(
|
||||
value: String,
|
||||
other: &ConstrainedValue<F, G>,
|
||||
@ -50,7 +51,7 @@ impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
ConstrainedValue::from_type(value, &other_type)
|
||||
}
|
||||
|
||||
pub(crate) fn from_type(value: String, _type: &Type<F, G>) -> Result<Self, ValueError> {
|
||||
pub(crate) fn from_type(value: String, _type: &Type<F>) -> Result<Self, ValueError> {
|
||||
match _type {
|
||||
Type::IntegerType(integer_type) => Ok(ConstrainedValue::Integer(match integer_type {
|
||||
IntegerType::U8 => Integer::U8(UInt8::constant(value.parse::<u8>()?)),
|
||||
@ -62,13 +63,7 @@ impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
Type::FieldElement => Ok(ConstrainedValue::FieldElement(FieldElement::Constant(
|
||||
F::from_str(&value).unwrap_or_default(),
|
||||
))),
|
||||
Type::GroupElement => Ok(ConstrainedValue::GroupElement({
|
||||
use std::str::FromStr;
|
||||
|
||||
let scalar = G::ScalarField::from_str(&value).unwrap_or_default();
|
||||
let point = G::default().mul(&scalar);
|
||||
point
|
||||
})),
|
||||
Type::Group => Ok(ConstrainedValue::Group(G::constant(value)?)),
|
||||
Type::Boolean => Ok(ConstrainedValue::Boolean(Boolean::Constant(
|
||||
value.parse::<bool>()?,
|
||||
))),
|
||||
@ -77,17 +72,17 @@ impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_type(&self) -> Type<F, G> {
|
||||
pub(crate) fn to_type(&self) -> Type<F> {
|
||||
match self {
|
||||
ConstrainedValue::Integer(integer) => Type::IntegerType(integer.get_type()),
|
||||
ConstrainedValue::FieldElement(_field) => Type::FieldElement,
|
||||
ConstrainedValue::GroupElement(_group) => Type::GroupElement,
|
||||
ConstrainedValue::Group(_group) => Type::Group,
|
||||
ConstrainedValue::Boolean(_bool) => Type::Boolean,
|
||||
_ => unimplemented!("to type only implemented for primitives"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_type(&mut self, types: &Vec<Type<F, G>>) -> Result<(), ValueError> {
|
||||
pub(crate) fn resolve_type(&mut self, types: &Vec<Type<F>>) -> Result<(), ValueError> {
|
||||
if let ConstrainedValue::Unresolved(ref string) = self {
|
||||
if !types.is_empty() {
|
||||
*self = ConstrainedValue::from_type(string.clone(), &types[0])?
|
||||
@ -104,12 +99,12 @@ impl<F: Field + PrimeField, G: Group> ConstrainedValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for ConstrainedValue<F, G> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> fmt::Display for ConstrainedValue<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConstrainedValue::Integer(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::FieldElement(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::GroupElement(ref value) => write!(f, "{}", value),
|
||||
ConstrainedValue::Group(ref value) => write!(f, "{:?}", value),
|
||||
ConstrainedValue::Boolean(ref value) => write!(f, "{}", value.get_value().unwrap()),
|
||||
ConstrainedValue::Array(ref array) => {
|
||||
write!(f, "[")?;
|
||||
@ -154,7 +149,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for ConstrainedValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Debug for ConstrainedValue<F, G> {
|
||||
impl<F: Field + PrimeField, G: GroupType<F>> fmt::Debug for ConstrainedValue<F, G> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::{FunctionError, ImportError, IntegerError};
|
||||
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CompilerError {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::errors::ValueError;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::errors::{BooleanError, FieldElementError, FunctionError, IntegerError, ValueError};
|
||||
use crate::errors::{
|
||||
BooleanError, FieldElementError, FunctionError, GroupError, IntegerError, ValueError,
|
||||
};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use std::num::ParseIntError;
|
||||
@ -28,6 +30,9 @@ pub enum ExpressionError {
|
||||
#[error("{}", _0)]
|
||||
FieldElementError(FieldElementError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(BooleanError),
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::errors::{
|
||||
BooleanError, ExpressionError, FieldElementError, GroupElementError, IntegerError,
|
||||
StatementError, ValueError,
|
||||
BooleanError, ExpressionError, FieldElementError, GroupError, IntegerError, StatementError,
|
||||
ValueError,
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
@ -30,7 +30,7 @@ pub enum FunctionError {
|
||||
FieldElementError(FieldElementError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupElementError(GroupElementError),
|
||||
GroupError(GroupError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BooleanError(BooleanError),
|
||||
@ -60,9 +60,9 @@ impl From<FieldElementError> for FunctionError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GroupElementError> for FunctionError {
|
||||
fn from(error: GroupElementError) -> Self {
|
||||
FunctionError::GroupElementError(error)
|
||||
impl From<GroupError> for FunctionError {
|
||||
fn from(error: GroupError) -> Self {
|
||||
FunctionError::GroupError(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
16
compiler/src/errors/constraints/group.rs
Normal file
16
compiler/src/errors/constraints/group.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GroupError {
|
||||
#[error("Expected affine point, got {}", _0)]
|
||||
Invalid(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for GroupError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
GroupError::SynthesisError(error)
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum GroupElementError {
|
||||
#[error("Expected group element parameter, got {}", _0)]
|
||||
InvalidGroup(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(SynthesisError),
|
||||
}
|
||||
|
||||
impl From<SynthesisError> for GroupElementError {
|
||||
fn from(error: SynthesisError) -> Self {
|
||||
GroupElementError::SynthesisError(error)
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::{io, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ImportError {
|
||||
|
@ -18,8 +18,8 @@ pub use integer::*;
|
||||
pub mod field_element;
|
||||
pub use field_element::*;
|
||||
|
||||
pub mod group_element;
|
||||
pub use group_element::*;
|
||||
pub mod group;
|
||||
pub use group::*;
|
||||
|
||||
pub mod value;
|
||||
pub use value::*;
|
||||
|
@ -1,5 +1,7 @@
|
||||
use crate::errors::{BooleanError, ExpressionError, FieldElementError, IntegerError, ValueError};
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StatementError {
|
||||
#[error("Attempted to assign to unknown variable {}", _0)]
|
||||
@ -62,6 +64,9 @@ pub enum StatementError {
|
||||
|
||||
#[error("Expected assignment of return values for expression {}", _0)]
|
||||
Unassigned(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
SynthesisError(#[from] SynthesisError),
|
||||
}
|
||||
|
||||
impl From<ExpressionError> for StatementError {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::errors::IntegerError;
|
||||
use crate::errors::{GroupError, IntegerError};
|
||||
|
||||
use std::num::ParseIntError;
|
||||
use std::str::ParseBoolError;
|
||||
use std::{num::ParseIntError, str::ParseBoolError};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ValueError {
|
||||
@ -27,6 +26,9 @@ pub enum ValueError {
|
||||
/// Unexpected type
|
||||
#[error("{}", _0)]
|
||||
TypeError(String),
|
||||
|
||||
#[error("{}", _0)]
|
||||
GroupError(#[from] GroupError),
|
||||
}
|
||||
|
||||
impl From<ParseIntError> for ValueError {
|
||||
|
306
compiler/src/group/edwards_bls12.rs
Normal file
306
compiler/src/group/edwards_bls12.rs
Normal file
@ -0,0 +1,306 @@
|
||||
use crate::{errors::GroupError, GroupType};
|
||||
|
||||
use snarkos_curves::{
|
||||
edwards_bls12::{EdwardsAffine, EdwardsParameters, Fq},
|
||||
templates::twisted_edwards_extended::GroupAffine,
|
||||
};
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::{
|
||||
curves::AffineCurve,
|
||||
gadgets::{
|
||||
curves::{FpGadget, GroupGadget},
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{
|
||||
alloc::AllocGadget,
|
||||
boolean::Boolean,
|
||||
eq::{ConditionalEqGadget, EqGadget},
|
||||
select::CondSelectGadget,
|
||||
uint8::UInt8,
|
||||
ToBitsGadget, ToBytesGadget,
|
||||
},
|
||||
},
|
||||
};
|
||||
use std::{borrow::Borrow, ops::Sub, str::FromStr};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum EdwardsGroupType {
|
||||
Constant(EdwardsAffine),
|
||||
Allocated(EdwardsBlsGadget),
|
||||
}
|
||||
|
||||
impl GroupType<Fq> for EdwardsGroupType {
|
||||
fn constant(string: String) -> Result<Self, GroupError> {
|
||||
let value = Self::edwards_affine_from_str(string)?;
|
||||
|
||||
Ok(EdwardsGroupType::Constant(value))
|
||||
}
|
||||
|
||||
fn add<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError> {
|
||||
match (self, other) {
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
Ok(EdwardsGroupType::Constant(self_value.add(other_value)))
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
let result = <EdwardsBlsGadget as GroupGadget<
|
||||
GroupAffine<EdwardsParameters>,
|
||||
Fq,
|
||||
>>::add(self_value, cs, other_value)?;
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => Ok(EdwardsGroupType::Allocated(
|
||||
allocated_value.add_constant(cs, constant_value)?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn sub<CS: ConstraintSystem<Fq>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError> {
|
||||
match (self, other) {
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
Ok(EdwardsGroupType::Constant(self_value.sub(other_value)))
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
let result = <EdwardsBlsGadget as GroupGadget<
|
||||
GroupAffine<EdwardsParameters>,
|
||||
Fq,
|
||||
>>::sub(self_value, cs, other_value)?;
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => Ok(EdwardsGroupType::Allocated(
|
||||
allocated_value.sub_constant(cs, constant_value)?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EdwardsGroupType {
|
||||
pub fn edwards_affine_from_str(string: String) -> Result<EdwardsAffine, GroupError> {
|
||||
// 0 or (0, 1)
|
||||
match Fq::from_str(&string).ok() {
|
||||
Some(x) => EdwardsAffine::get_point_from_x(x, false).ok_or(GroupError::Invalid(string)),
|
||||
None => EdwardsAffine::from_str(&string).map_err(|_| GroupError::Invalid(string)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_x_helper<Fn: FnOnce() -> Result<T, SynthesisError>, T: Borrow<String>>(
|
||||
value_gen: Fn,
|
||||
) -> Result<EdwardsAffine, SynthesisError> {
|
||||
let affine_string = match value_gen() {
|
||||
Ok(value) => {
|
||||
let string_value = value.borrow().clone();
|
||||
Ok(string_value)
|
||||
}
|
||||
_ => Err(SynthesisError::AssignmentMissing),
|
||||
}?;
|
||||
|
||||
Self::edwards_affine_from_str(affine_string).map_err(|_| SynthesisError::AssignmentMissing)
|
||||
}
|
||||
|
||||
pub fn allocated<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<EdwardsBlsGadget, SynthesisError> {
|
||||
match self {
|
||||
EdwardsGroupType::Constant(constant) => {
|
||||
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
|
||||
&mut cs.ns(|| format!("{:?}", constant)),
|
||||
|| Ok(constant),
|
||||
)
|
||||
}
|
||||
EdwardsGroupType::Allocated(allocated) => Ok(allocated.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AllocGadget<String, Fq> for EdwardsGroupType {
|
||||
fn alloc<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value = <EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
|
||||
fn alloc_input<
|
||||
Fn: FnOnce() -> Result<T, SynthesisError>,
|
||||
T: Borrow<String>,
|
||||
CS: ConstraintSystem<Fq>,
|
||||
>(
|
||||
cs: CS,
|
||||
value_gen: Fn,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
let value =
|
||||
<EdwardsBlsGadget as AllocGadget<GroupAffine<EdwardsParameters>, Fq>>::alloc_input(
|
||||
cs,
|
||||
|| Self::alloc_x_helper(value_gen),
|
||||
)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for EdwardsGroupType {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
self_value == other_value
|
||||
}
|
||||
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
self_value.eq(other_value)
|
||||
}
|
||||
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => <EdwardsBlsGadget as GroupGadget<GroupAffine<EdwardsParameters>, Fq>>::get_value(
|
||||
allocated_value,
|
||||
)
|
||||
.map(|allocated_value| allocated_value == *constant_value)
|
||||
.unwrap_or(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for EdwardsGroupType {}
|
||||
|
||||
impl EqGadget<Fq> for EdwardsGroupType {}
|
||||
|
||||
impl ConditionalEqGadget<Fq> for EdwardsGroupType {
|
||||
#[inline]
|
||||
fn conditional_enforce_equal<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
other: &Self,
|
||||
condition: &Boolean,
|
||||
) -> Result<(), SynthesisError> {
|
||||
match (self, other) {
|
||||
// c - c
|
||||
(EdwardsGroupType::Constant(self_value), EdwardsGroupType::Constant(other_value)) => {
|
||||
if self_value == other_value {
|
||||
return Ok(());
|
||||
}
|
||||
Err(SynthesisError::AssignmentMissing)
|
||||
}
|
||||
// a - a
|
||||
(EdwardsGroupType::Allocated(self_value), EdwardsGroupType::Allocated(other_value)) => {
|
||||
return <EdwardsBlsGadget>::conditional_enforce_equal(
|
||||
self_value,
|
||||
cs,
|
||||
other_value,
|
||||
condition,
|
||||
)
|
||||
}
|
||||
// c - a = a - c
|
||||
(
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
)
|
||||
| (
|
||||
EdwardsGroupType::Allocated(allocated_value),
|
||||
EdwardsGroupType::Constant(constant_value),
|
||||
) => {
|
||||
let x = FpGadget::from(&mut cs, &constant_value.x);
|
||||
let y = FpGadget::from(&mut cs, &constant_value.y);
|
||||
let constant_gadget = EdwardsBlsGadget::new(x, y);
|
||||
|
||||
constant_gadget.conditional_enforce_equal(cs, allocated_value, condition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cost() -> usize {
|
||||
2 * <EdwardsBlsGadget as ConditionalEqGadget<Fq>>::cost() //upper bound
|
||||
}
|
||||
}
|
||||
|
||||
impl CondSelectGadget<Fq> for EdwardsGroupType {
|
||||
fn conditionally_select<CS: ConstraintSystem<Fq>>(
|
||||
mut cs: CS,
|
||||
cond: &Boolean,
|
||||
first: &Self,
|
||||
second: &Self,
|
||||
) -> Result<Self, SynthesisError> {
|
||||
if let Boolean::Constant(cond) = *cond {
|
||||
if cond {
|
||||
Ok(first.clone())
|
||||
} else {
|
||||
Ok(second.clone())
|
||||
}
|
||||
} else {
|
||||
let first_gadget = first.allocated(&mut cs)?;
|
||||
let second_gadget = second.allocated(&mut cs)?;
|
||||
let result =
|
||||
EdwardsBlsGadget::conditionally_select(cs, cond, &first_gadget, &second_gadget)?;
|
||||
|
||||
Ok(EdwardsGroupType::Allocated(result))
|
||||
}
|
||||
}
|
||||
|
||||
fn cost() -> usize {
|
||||
2 * <EdwardsBlsGadget as CondSelectGadget<Fq>>::cost()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBitsGadget<Fq> for EdwardsGroupType {
|
||||
fn to_bits<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bits(cs)
|
||||
}
|
||||
|
||||
fn to_bits_strict<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<Boolean>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bits_strict(cs)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBytesGadget<Fq> for EdwardsGroupType {
|
||||
fn to_bytes<CS: ConstraintSystem<Fq>>(&self, mut cs: CS) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bytes(cs)
|
||||
}
|
||||
|
||||
fn to_bytes_strict<CS: ConstraintSystem<Fq>>(
|
||||
&self,
|
||||
mut cs: CS,
|
||||
) -> Result<Vec<UInt8>, SynthesisError> {
|
||||
let self_gadget = self.allocated(&mut cs)?;
|
||||
self_gadget.to_bytes_strict(cs)
|
||||
}
|
||||
}
|
35
compiler/src/group/mod.rs
Normal file
35
compiler/src/group/mod.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::errors::GroupError;
|
||||
|
||||
use snarkos_models::{
|
||||
curves::Field,
|
||||
gadgets::{
|
||||
r1cs::ConstraintSystem,
|
||||
utilities::{
|
||||
alloc::AllocGadget,
|
||||
eq::{ConditionalEqGadget, EqGadget},
|
||||
select::CondSelectGadget,
|
||||
ToBitsGadget, ToBytesGadget,
|
||||
},
|
||||
},
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub mod edwards_bls12;
|
||||
|
||||
pub trait GroupType<F: Field>:
|
||||
Sized
|
||||
+ Clone
|
||||
+ Debug
|
||||
+ EqGadget<F>
|
||||
+ ConditionalEqGadget<F>
|
||||
+ AllocGadget<String, F>
|
||||
+ CondSelectGadget<F>
|
||||
+ ToBitsGadget<F>
|
||||
+ ToBytesGadget<F>
|
||||
{
|
||||
fn constant(string: String) -> Result<Self, GroupError>;
|
||||
|
||||
fn add<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError>;
|
||||
|
||||
fn sub<CS: ConstraintSystem<F>>(&self, cs: CS, other: &Self) -> Result<Self, GroupError>;
|
||||
}
|
@ -2,23 +2,23 @@
|
||||
|
||||
use crate::Identifier;
|
||||
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ImportSymbol<F: Field + PrimeField, G: Group> {
|
||||
pub symbol: Identifier<F, G>,
|
||||
pub alias: Option<Identifier<F, G>>,
|
||||
pub struct ImportSymbol<F: Field + PrimeField> {
|
||||
pub symbol: Identifier<F>,
|
||||
pub alias: Option<Identifier<F>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Import<F: Field + PrimeField, G: Group> {
|
||||
pub struct Import<F: Field + PrimeField> {
|
||||
pub path_string: String,
|
||||
pub symbols: Vec<ImportSymbol<F, G>>,
|
||||
pub symbols: Vec<ImportSymbol<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Import<F, G> {
|
||||
pub fn new(source: String, symbols: Vec<ImportSymbol<F, G>>) -> Import<F, G> {
|
||||
impl<F: Field + PrimeField> Import<F> {
|
||||
pub fn new(source: String, symbols: Vec<ImportSymbol<F>>) -> Import<F> {
|
||||
Import {
|
||||
path_string: source,
|
||||
symbols,
|
||||
@ -51,7 +51,7 @@ impl<F: Field + PrimeField, G: Group> Import<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for ImportSymbol<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for ImportSymbol<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.alias.is_some() {
|
||||
write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||
@ -61,13 +61,13 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for ImportSymbol<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Import<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for Import<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> fmt::Debug for Import<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Debug for Import<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
|
@ -92,7 +92,10 @@ value_number = @{ "0" | ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* }
|
||||
value_implicit = { value_number }
|
||||
value_integer = { value_number ~ type_integer }
|
||||
value_field = { value_number ~ type_field }
|
||||
value_group = { value_number ~ type_group }
|
||||
|
||||
group_tuple = {"(" ~ value_number ~ "," ~ value_number ~ ")"}
|
||||
group_single_or_tuple = {value_number | group_tuple}
|
||||
value_group = { group_single_or_tuple ~ type_group }
|
||||
value_boolean = { "true" | "false" }
|
||||
value = { value_field | value_group | value_boolean | value_integer | value_implicit }
|
||||
expression_primitive = { value | identifier }
|
||||
|
@ -22,6 +22,9 @@ pub use self::constraints::*;
|
||||
|
||||
pub mod errors;
|
||||
|
||||
pub mod group;
|
||||
pub use self::group::*;
|
||||
|
||||
pub mod imports;
|
||||
pub use self::imports::*;
|
||||
|
||||
|
@ -3,30 +3,29 @@
|
||||
|
||||
use crate::Import;
|
||||
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use snarkos_models::gadgets::{
|
||||
r1cs::Variable as R1CSVariable,
|
||||
utilities::{
|
||||
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
|
||||
uint8::UInt8,
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::{
|
||||
r1cs::Variable as R1CSVariable,
|
||||
utilities::{
|
||||
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
|
||||
uint8::UInt8,
|
||||
},
|
||||
},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::marker::PhantomData;
|
||||
use std::{collections::HashMap, marker::PhantomData};
|
||||
|
||||
/// An identifier in the constrained program.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Identifier<F: Field + PrimeField, G: Group> {
|
||||
pub struct Identifier<F: Field + PrimeField> {
|
||||
pub name: String,
|
||||
pub(crate) _group: PhantomData<G>,
|
||||
pub(crate) _engine: PhantomData<F>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Identifier<F, G> {
|
||||
impl<F: Field + PrimeField> Identifier<F> {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
_group: PhantomData::<G>,
|
||||
_engine: PhantomData::<F>,
|
||||
}
|
||||
}
|
||||
@ -38,10 +37,10 @@ impl<F: Field + PrimeField, G: Group> Identifier<F, G> {
|
||||
|
||||
/// A variable that is assigned to a value in the constrained program
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Variable<F: Field + PrimeField, G: Group> {
|
||||
pub identifier: Identifier<F, G>,
|
||||
pub struct Variable<F: Field + PrimeField> {
|
||||
pub identifier: Identifier<F>,
|
||||
pub mutable: bool,
|
||||
pub _type: Option<Type<F, G>>,
|
||||
pub _type: Option<Type<F>>,
|
||||
}
|
||||
|
||||
/// An integer type enum wrapping the integer value. Used only in expressions.
|
||||
@ -63,74 +62,70 @@ pub enum FieldElement<F: Field + PrimeField> {
|
||||
|
||||
/// Range or expression enum
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum RangeOrExpression<F: Field + PrimeField, G: Group> {
|
||||
pub enum RangeOrExpression<F: Field + PrimeField> {
|
||||
Range(Option<Integer>, Option<Integer>),
|
||||
Expression(Expression<F, G>),
|
||||
Expression(Expression<F>),
|
||||
}
|
||||
|
||||
/// Spread or expression
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum SpreadOrExpression<F: Field + PrimeField, G: Group> {
|
||||
Spread(Expression<F, G>),
|
||||
Expression(Expression<F, G>),
|
||||
pub enum SpreadOrExpression<F: Field + PrimeField> {
|
||||
Spread(Expression<F>),
|
||||
Expression(Expression<F>),
|
||||
}
|
||||
|
||||
/// Expression that evaluates to a value
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Expression<F: Field + PrimeField, G: Group> {
|
||||
pub enum Expression<F: Field + PrimeField> {
|
||||
// Identifier
|
||||
Identifier(Identifier<F, G>),
|
||||
Identifier(Identifier<F>),
|
||||
|
||||
// Values
|
||||
Integer(Integer),
|
||||
FieldElement(FieldElement<F>),
|
||||
GroupElement(G),
|
||||
Group(String),
|
||||
Boolean(Boolean),
|
||||
Implicit(String),
|
||||
|
||||
// Number operations
|
||||
Add(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Sub(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Mul(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Div(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Pow(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Add(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Sub(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Mul(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Div(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Pow(Box<Expression<F>>, Box<Expression<F>>),
|
||||
|
||||
// Boolean operations
|
||||
Not(Box<Expression<F, G>>),
|
||||
Or(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
And(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Eq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Geq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Gt(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Leq(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Lt(Box<Expression<F, G>>, Box<Expression<F, G>>),
|
||||
Not(Box<Expression<F>>),
|
||||
Or(Box<Expression<F>>, Box<Expression<F>>),
|
||||
And(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Eq(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Geq(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Gt(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Leq(Box<Expression<F>>, Box<Expression<F>>),
|
||||
Lt(Box<Expression<F>>, Box<Expression<F>>),
|
||||
|
||||
// Conditionals
|
||||
IfElse(
|
||||
Box<Expression<F, G>>,
|
||||
Box<Expression<F, G>>,
|
||||
Box<Expression<F, G>>,
|
||||
),
|
||||
IfElse(Box<Expression<F>>, Box<Expression<F>>, Box<Expression<F>>),
|
||||
|
||||
// Arrays
|
||||
Array(Vec<Box<SpreadOrExpression<F, G>>>),
|
||||
ArrayAccess(Box<Expression<F, G>>, Box<RangeOrExpression<F, G>>), // (array name, range)
|
||||
Array(Vec<Box<SpreadOrExpression<F>>>),
|
||||
ArrayAccess(Box<Expression<F>>, Box<RangeOrExpression<F>>), // (array name, range)
|
||||
|
||||
// Circuits
|
||||
Circuit(Identifier<F, G>, Vec<CircuitFieldDefinition<F, G>>),
|
||||
CircuitMemberAccess(Box<Expression<F, G>>, Identifier<F, G>), // (declared circuit name, circuit member name)
|
||||
CircuitStaticFunctionAccess(Box<Expression<F, G>>, Identifier<F, G>), // (defined circuit name, circuit static member name)
|
||||
Circuit(Identifier<F>, Vec<CircuitFieldDefinition<F>>),
|
||||
CircuitMemberAccess(Box<Expression<F>>, Identifier<F>), // (declared circuit name, circuit member name)
|
||||
CircuitStaticFunctionAccess(Box<Expression<F>>, Identifier<F>), // (defined circuit name, circuit static member name)
|
||||
|
||||
// Functions
|
||||
FunctionCall(Box<Expression<F, G>>, Vec<Expression<F, G>>),
|
||||
FunctionCall(Box<Expression<F>>, Vec<Expression<F>>),
|
||||
}
|
||||
|
||||
/// Definition assignee: v, arr[0..2], Point p.x
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Assignee<F: Field + PrimeField, G: Group> {
|
||||
Identifier(Identifier<F, G>),
|
||||
Array(Box<Assignee<F, G>>, RangeOrExpression<F, G>),
|
||||
CircuitField(Box<Assignee<F, G>>, Identifier<F, G>), // (circuit name, circuit field name)
|
||||
pub enum Assignee<F: Field + PrimeField> {
|
||||
Identifier(Identifier<F>),
|
||||
Array(Box<Assignee<F>>, RangeOrExpression<F>),
|
||||
CircuitField(Box<Assignee<F>>, Identifier<F>), // (circuit name, circuit field name)
|
||||
}
|
||||
|
||||
/// Explicit integer type
|
||||
@ -145,17 +140,17 @@ pub enum IntegerType {
|
||||
|
||||
/// Explicit type used for defining a variable or expression type
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Type<F: Field + PrimeField, G: Group> {
|
||||
pub enum Type<F: Field + PrimeField> {
|
||||
IntegerType(IntegerType),
|
||||
FieldElement,
|
||||
GroupElement,
|
||||
Group,
|
||||
Boolean,
|
||||
Array(Box<Type<F, G>>, Vec<usize>),
|
||||
Circuit(Identifier<F, G>),
|
||||
Array(Box<Type<F>>, Vec<usize>),
|
||||
Circuit(Identifier<F>),
|
||||
SelfType,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Type<F, G> {
|
||||
impl<F: Field + PrimeField> Type<F> {
|
||||
pub fn outer_dimension(&self, dimensions: &Vec<usize>) -> Self {
|
||||
let _type = self.clone();
|
||||
|
||||
@ -184,79 +179,79 @@ impl<F: Field + PrimeField, G: Group> Type<F, G> {
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum ConditionalNestedOrEnd<F: Field + PrimeField, G: Group> {
|
||||
Nested(Box<ConditionalStatement<F, G>>),
|
||||
End(Vec<Statement<F, G>>),
|
||||
pub enum ConditionalNestedOrEnd<F: Field + PrimeField> {
|
||||
Nested(Box<ConditionalStatement<F>>),
|
||||
End(Vec<Statement<F>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct ConditionalStatement<F: Field + PrimeField, G: Group> {
|
||||
pub condition: Expression<F, G>,
|
||||
pub statements: Vec<Statement<F, G>>,
|
||||
pub next: Option<ConditionalNestedOrEnd<F, G>>,
|
||||
pub struct ConditionalStatement<F: Field + PrimeField> {
|
||||
pub condition: Expression<F>,
|
||||
pub statements: Vec<Statement<F>>,
|
||||
pub next: Option<ConditionalNestedOrEnd<F>>,
|
||||
}
|
||||
|
||||
/// Program statement that defines some action (or expression) to be carried out.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Statement<F: Field + PrimeField, G: Group> {
|
||||
Return(Vec<Expression<F, G>>),
|
||||
Definition(Variable<F, G>, Expression<F, G>),
|
||||
Assign(Assignee<F, G>, Expression<F, G>),
|
||||
MultipleAssign(Vec<Variable<F, G>>, Expression<F, G>),
|
||||
Conditional(ConditionalStatement<F, G>),
|
||||
For(Identifier<F, G>, Integer, Integer, Vec<Statement<F, G>>),
|
||||
AssertEq(Expression<F, G>, Expression<F, G>),
|
||||
Expression(Expression<F, G>),
|
||||
pub enum Statement<F: Field + PrimeField> {
|
||||
Return(Vec<Expression<F>>),
|
||||
Definition(Variable<F>, Expression<F>),
|
||||
Assign(Assignee<F>, Expression<F>),
|
||||
MultipleAssign(Vec<Variable<F>>, Expression<F>),
|
||||
Conditional(ConditionalStatement<F>),
|
||||
For(Identifier<F>, Integer, Integer, Vec<Statement<F>>),
|
||||
AssertEq(Expression<F>, Expression<F>),
|
||||
Expression(Expression<F>),
|
||||
}
|
||||
|
||||
/// Circuits
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct CircuitFieldDefinition<F: Field + PrimeField, G: Group> {
|
||||
pub identifier: Identifier<F, G>,
|
||||
pub expression: Expression<F, G>,
|
||||
pub struct CircuitFieldDefinition<F: Field + PrimeField> {
|
||||
pub identifier: Identifier<F>,
|
||||
pub expression: Expression<F>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum CircuitMember<F: Field + PrimeField, G: Group> {
|
||||
CircuitField(Identifier<F, G>, Type<F, G>),
|
||||
CircuitFunction(bool, Function<F, G>),
|
||||
pub enum CircuitMember<F: Field + PrimeField> {
|
||||
CircuitField(Identifier<F>, Type<F>),
|
||||
CircuitFunction(bool, Function<F>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Circuit<F: Field + PrimeField, G: Group> {
|
||||
pub identifier: Identifier<F, G>,
|
||||
pub members: Vec<CircuitMember<F, G>>,
|
||||
pub struct Circuit<F: Field + PrimeField> {
|
||||
pub identifier: Identifier<F>,
|
||||
pub members: Vec<CircuitMember<F>>,
|
||||
}
|
||||
|
||||
/// Function parameters
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct InputModel<F: Field + PrimeField, G: Group> {
|
||||
pub identifier: Identifier<F, G>,
|
||||
pub struct InputModel<F: Field + PrimeField> {
|
||||
pub identifier: Identifier<F>,
|
||||
pub mutable: bool,
|
||||
pub private: bool,
|
||||
pub _type: Type<F, G>,
|
||||
pub _type: Type<F>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum InputValue<F: Field + PrimeField, G: Group> {
|
||||
pub enum InputValue<F: Field + PrimeField> {
|
||||
Integer(usize),
|
||||
Field(F),
|
||||
Group(G),
|
||||
Group(String),
|
||||
Boolean(bool),
|
||||
Array(Vec<InputValue<F, G>>),
|
||||
Array(Vec<InputValue<F>>),
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Function<F: Field + PrimeField, G: Group> {
|
||||
pub function_name: Identifier<F, G>,
|
||||
pub inputs: Vec<InputModel<F, G>>,
|
||||
pub returns: Vec<Type<F, G>>,
|
||||
pub statements: Vec<Statement<F, G>>,
|
||||
pub struct Function<F: Field + PrimeField> {
|
||||
pub function_name: Identifier<F>,
|
||||
pub inputs: Vec<InputModel<F>>,
|
||||
pub returns: Vec<Type<F>>,
|
||||
pub statements: Vec<Statement<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
impl<F: Field + PrimeField> Function<F> {
|
||||
pub fn get_name(&self) -> String {
|
||||
self.function_name.name.clone()
|
||||
}
|
||||
@ -264,15 +259,15 @@ impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
|
||||
/// A simple program with statement expressions, program arguments and program returns.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Program<F: Field + PrimeField, G: Group> {
|
||||
pub name: Identifier<F, G>,
|
||||
pub struct Program<F: Field + PrimeField> {
|
||||
pub name: Identifier<F>,
|
||||
pub num_parameters: usize,
|
||||
pub imports: Vec<Import<F, G>>,
|
||||
pub circuits: HashMap<Identifier<F, G>, Circuit<F, G>>,
|
||||
pub functions: HashMap<Identifier<F, G>, Function<F, G>>,
|
||||
pub imports: Vec<Import<F>>,
|
||||
pub circuits: HashMap<Identifier<F>, Circuit<F>>,
|
||||
pub functions: HashMap<Identifier<F>, Function<F>>,
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> Program<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> Program<F> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
name: Identifier::new("".into()),
|
||||
|
@ -6,21 +6,21 @@ use crate::{
|
||||
RangeOrExpression, SpreadOrExpression, Statement, Type, Variable,
|
||||
};
|
||||
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use snarkos_models::curves::{Field, PrimeField};
|
||||
use std::fmt;
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Identifier<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Identifier<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Debug for Identifier<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Identifier<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Variable<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Variable<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.mutable {
|
||||
write!(f, "mut ")?;
|
||||
@ -69,7 +69,7 @@ impl<F: Field + PrimeField> fmt::Debug for FieldElement<F> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for RangeOrExpression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for RangeOrExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
RangeOrExpression::Range(ref from, ref to) => write!(
|
||||
@ -87,7 +87,7 @@ impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for RangeOrExpression<F
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for SpreadOrExpression<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for SpreadOrExpression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
SpreadOrExpression::Spread(ref spread) => write!(f, "...{}", spread),
|
||||
@ -96,7 +96,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for SpreadOrExpression<F, G>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> fmt::Display for Expression<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
// Variables
|
||||
@ -105,7 +105,7 @@ impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Expression<F, G> {
|
||||
// Values
|
||||
Expression::Integer(ref integer) => write!(f, "{}", integer),
|
||||
Expression::FieldElement(ref field) => write!(f, "{}", field),
|
||||
Expression::GroupElement(ref group) => write!(f, "{}", group),
|
||||
Expression::Group(ref group) => write!(f, "{}", group),
|
||||
Expression::Boolean(ref bool) => write!(f, "{}", bool.get_value().unwrap()),
|
||||
Expression::Implicit(ref value) => write!(f, "{}", value),
|
||||
|
||||
@ -177,7 +177,7 @@ impl<'ast, F: Field + PrimeField, G: Group> fmt::Display for Expression<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Assignee<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Assignee<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Assignee::Identifier(ref variable) => write!(f, "{}", variable),
|
||||
@ -189,7 +189,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for Assignee<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for ConditionalNestedOrEnd<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for ConditionalNestedOrEnd<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
ConditionalNestedOrEnd::Nested(ref nested) => write!(f, "else {}", nested),
|
||||
@ -204,7 +204,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for ConditionalNestedOrEnd<F,
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for ConditionalStatement<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for ConditionalStatement<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "if ({}) {{\n", self.condition)?;
|
||||
for statement in self.statements.iter() {
|
||||
@ -217,7 +217,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for ConditionalStatement<F, G
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Statement<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Statement<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Statement::Return(ref statements) => {
|
||||
@ -274,12 +274,12 @@ impl fmt::Display for IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Type<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Type<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Type::IntegerType(ref integer_type) => write!(f, "{}", integer_type),
|
||||
Type::FieldElement => write!(f, "field"),
|
||||
Type::GroupElement => write!(f, "group"),
|
||||
Type::Group => write!(f, "group"),
|
||||
Type::Boolean => write!(f, "bool"),
|
||||
Type::Circuit(ref variable) => write!(f, "{}", variable),
|
||||
Type::SelfType => write!(f, "Self"),
|
||||
@ -294,7 +294,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for Type<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for CircuitMember<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for CircuitMember<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
CircuitMember::CircuitField(ref identifier, ref _type) => {
|
||||
@ -310,7 +310,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for CircuitMember<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Circuit<F, G> {
|
||||
impl<F: Field + PrimeField> Circuit<F> {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "circuit {} {{ \n", self.identifier)?;
|
||||
for field in self.members.iter() {
|
||||
@ -320,19 +320,19 @@ impl<F: Field + PrimeField, G: Group> Circuit<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
// impl<F: Field + PrimeField, G: Group> fmt::Display for Circuit<F, G> {// uncomment when we no longer print out Program
|
||||
// impl<F: Field + PrimeField> fmt::Display for Circuit<F> {// uncomment when we no longer print out Program
|
||||
// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// self.format(f)
|
||||
// }
|
||||
// }
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Debug for Circuit<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Circuit<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for InputModel<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for InputModel<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// mut var: private bool
|
||||
if self.mutable {
|
||||
@ -348,7 +348,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for InputModel<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for InputValue<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for InputValue<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
InputValue::Integer(ref integer) => write!(f, "{}", integer),
|
||||
@ -369,7 +369,7 @@ impl<F: Field + PrimeField, G: Group> fmt::Display for InputValue<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
impl<F: Field + PrimeField> Function<F> {
|
||||
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "function {}", self.function_name)?;
|
||||
let parameters = self
|
||||
@ -400,13 +400,13 @@ impl<F: Field + PrimeField, G: Group> Function<F, G> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Display for Function<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Display for Function<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> fmt::Debug for Function<F, G> {
|
||||
impl<F: Field + PrimeField> fmt::Debug for Function<F> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.format(f)
|
||||
}
|
||||
|
@ -2,26 +2,24 @@
|
||||
|
||||
use crate::{ast, types, Import, ImportSymbol};
|
||||
|
||||
use snarkos_models::curves::{Field, Group, PrimeField};
|
||||
use snarkos_models::gadgets::utilities::{
|
||||
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
|
||||
uint8::UInt8,
|
||||
use snarkos_models::{
|
||||
curves::{Field, PrimeField},
|
||||
gadgets::utilities::{
|
||||
boolean::Boolean, uint128::UInt128, uint16::UInt16, uint32::UInt32, uint64::UInt64,
|
||||
uint8::UInt8,
|
||||
},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// pest ast -> types::Identifier
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Identifier<'ast>>
|
||||
for types::Identifier<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Identifier<'ast>> for types::Identifier<F> {
|
||||
fn from(identifier: ast::Identifier<'ast>) -> Self {
|
||||
types::Identifier::new(identifier.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Identifier<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Identifier<'ast>> for types::Expression<F> {
|
||||
fn from(identifier: ast::Identifier<'ast>) -> Self {
|
||||
types::Expression::Identifier(types::Identifier::from(identifier))
|
||||
}
|
||||
@ -29,7 +27,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Identifier<'ast>>
|
||||
|
||||
/// pest ast -> types::Variable
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Variable<'ast>> for types::Variable<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Variable<'ast>> for types::Variable<F> {
|
||||
fn from(variable: ast::Variable<'ast>) -> Self {
|
||||
types::Variable {
|
||||
identifier: types::Identifier::from(variable.identifier),
|
||||
@ -72,32 +70,21 @@ impl<'ast> types::Integer {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Integer<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Integer<'ast>> for types::Expression<F> {
|
||||
fn from(field: ast::Integer<'ast>) -> Self {
|
||||
types::Expression::Integer(types::Integer::from(field.number, field._type))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::RangeOrExpression<'ast>>
|
||||
for types::RangeOrExpression<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::RangeOrExpression<'ast>>
|
||||
for types::RangeOrExpression<F>
|
||||
{
|
||||
fn from(range_or_expression: ast::RangeOrExpression<'ast>) -> Self {
|
||||
match range_or_expression {
|
||||
ast::RangeOrExpression::Range(range) => {
|
||||
let from = range
|
||||
.from
|
||||
.map(|from| match types::Expression::<F, G>::from(from.0) {
|
||||
types::Expression::Integer(number) => number,
|
||||
types::Expression::Implicit(string) => {
|
||||
types::Integer::from_implicit(string)
|
||||
}
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
||||
}
|
||||
});
|
||||
let to = range
|
||||
.to
|
||||
.map(|to| match types::Expression::<F, G>::from(to.0) {
|
||||
.map(|from| match types::Expression::<F>::from(from.0) {
|
||||
types::Expression::Integer(number) => number,
|
||||
types::Expression::Implicit(string) => {
|
||||
types::Integer::from_implicit(string)
|
||||
@ -106,6 +93,13 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::RangeOrExpression<'ast>>
|
||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
||||
}
|
||||
});
|
||||
let to = range.to.map(|to| match types::Expression::<F>::from(to.0) {
|
||||
types::Expression::Integer(number) => number,
|
||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
||||
expression => {
|
||||
unimplemented!("Range bounds should be integers, found {}", expression)
|
||||
}
|
||||
});
|
||||
|
||||
types::RangeOrExpression::Range(from, to)
|
||||
}
|
||||
@ -118,7 +112,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::RangeOrExpression<'ast>>
|
||||
|
||||
/// pest ast -> types::Field
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Field<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Field<'ast>> for types::Expression<F> {
|
||||
fn from(field: ast::Field<'ast>) -> Self {
|
||||
types::Expression::FieldElement(types::FieldElement::Constant(
|
||||
F::from_str(&field.number.value).unwrap_or_default(),
|
||||
@ -128,20 +122,15 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Field<'ast>> for types::Ex
|
||||
|
||||
/// pest ast -> types::Group
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Group<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Group<'ast>> for types::Expression<F> {
|
||||
fn from(group: ast::Group<'ast>) -> Self {
|
||||
use std::str::FromStr;
|
||||
|
||||
let scalar = G::ScalarField::from_str(&group.number.value).unwrap_or_default();
|
||||
let point = G::default().mul(&scalar);
|
||||
|
||||
types::Expression::GroupElement(point)
|
||||
types::Expression::Group(group.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// pest ast -> types::Boolean
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Boolean<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Boolean<'ast>> for types::Expression<F> {
|
||||
fn from(boolean: ast::Boolean<'ast>) -> Self {
|
||||
types::Expression::Boolean(Boolean::Constant(
|
||||
boolean
|
||||
@ -154,9 +143,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Boolean<'ast>> for types::
|
||||
|
||||
/// pest ast -> types::NumberImplicit
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::NumberImplicit<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::NumberImplicit<'ast>> for types::Expression<F> {
|
||||
fn from(number: ast::NumberImplicit<'ast>) -> Self {
|
||||
types::Expression::Implicit(number.number.value)
|
||||
}
|
||||
@ -164,7 +151,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::NumberImplicit<'ast>>
|
||||
|
||||
/// pest ast -> types::Expression
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Value<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Value<'ast>> for types::Expression<F> {
|
||||
fn from(value: ast::Value<'ast>) -> Self {
|
||||
match value {
|
||||
ast::Value::Integer(num) => types::Expression::from(num),
|
||||
@ -176,16 +163,14 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Value<'ast>> for types::Ex
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::NotExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::NotExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::NotExpression<'ast>) -> Self {
|
||||
types::Expression::Not(Box::new(types::Expression::from(*expression.expression)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::SpreadOrExpression<'ast>>
|
||||
for types::SpreadOrExpression<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::SpreadOrExpression<'ast>>
|
||||
for types::SpreadOrExpression<F>
|
||||
{
|
||||
fn from(s_or_e: ast::SpreadOrExpression<'ast>) -> Self {
|
||||
match s_or_e {
|
||||
@ -199,9 +184,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::SpreadOrExpression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::BinaryExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::BinaryExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::BinaryExpression<'ast>) -> Self {
|
||||
match expression.operation {
|
||||
// Boolean operations
|
||||
@ -261,9 +244,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::BinaryExpression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::TernaryExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::TernaryExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::TernaryExpression<'ast>) -> Self {
|
||||
types::Expression::IfElse(
|
||||
Box::new(types::Expression::from(*expression.first)),
|
||||
@ -273,9 +254,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::TernaryExpression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ArrayInlineExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayInlineExpression<'ast>> for types::Expression<F> {
|
||||
fn from(array: ast::ArrayInlineExpression<'ast>) -> Self {
|
||||
types::Expression::Array(
|
||||
array
|
||||
@ -286,19 +265,19 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ArrayInlineExpression<'ast
|
||||
)
|
||||
}
|
||||
}
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ArrayInitializerExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayInitializerExpression<'ast>>
|
||||
for types::Expression<F>
|
||||
{
|
||||
fn from(array: ast::ArrayInitializerExpression<'ast>) -> Self {
|
||||
let count = types::Expression::<F, G>::get_count(array.count);
|
||||
let count = types::Expression::<F>::get_count(array.count);
|
||||
let expression = Box::new(types::SpreadOrExpression::from(*array.expression));
|
||||
|
||||
types::Expression::Array(vec![expression; count])
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitField<'ast>>
|
||||
for types::CircuitFieldDefinition<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitField<'ast>>
|
||||
for types::CircuitFieldDefinition<F>
|
||||
{
|
||||
fn from(member: ast::CircuitField<'ast>) -> Self {
|
||||
types::CircuitFieldDefinition {
|
||||
@ -308,8 +287,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitField<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitInlineExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitInlineExpression<'ast>>
|
||||
for types::Expression<F>
|
||||
{
|
||||
fn from(expression: ast::CircuitInlineExpression<'ast>) -> Self {
|
||||
let variable = types::Identifier::from(expression.identifier);
|
||||
@ -317,15 +296,13 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitInlineExpression<'a
|
||||
.members
|
||||
.into_iter()
|
||||
.map(|member| types::CircuitFieldDefinition::from(member))
|
||||
.collect::<Vec<types::CircuitFieldDefinition<F, G>>>();
|
||||
.collect::<Vec<types::CircuitFieldDefinition<F>>>();
|
||||
|
||||
types::Expression::Circuit(variable, members)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::PostfixExpression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::PostfixExpression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::PostfixExpression<'ast>) -> Self {
|
||||
let variable =
|
||||
types::Expression::Identifier(types::Identifier::from(expression.identifier));
|
||||
@ -369,9 +346,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::PostfixExpression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Expression<'ast>>
|
||||
for types::Expression<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Expression<'ast>> for types::Expression<F> {
|
||||
fn from(expression: ast::Expression<'ast>) -> Self {
|
||||
match expression {
|
||||
ast::Expression::Value(value) => types::Expression::from(value),
|
||||
@ -387,7 +362,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Expression<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> types::Expression<F> {
|
||||
fn get_count(count: ast::Value<'ast>) -> usize {
|
||||
match count {
|
||||
ast::Value::Integer(integer) => integer
|
||||
@ -406,7 +381,7 @@ impl<'ast, F: Field + PrimeField, G: Group> types::Expression<F, G> {
|
||||
}
|
||||
|
||||
// ast::Assignee -> types::Expression for operator assign statements
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types::Expression<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Expression<F> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Expression::Identifier(types::Identifier::from(assignee.identifier));
|
||||
|
||||
@ -431,13 +406,13 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types:
|
||||
|
||||
/// pest ast -> types::Assignee
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Identifier<'ast>> for types::Assignee<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Identifier<'ast>> for types::Assignee<F> {
|
||||
fn from(variable: ast::Identifier<'ast>) -> Self {
|
||||
types::Assignee::Identifier(types::Identifier::from(variable))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types::Assignee<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Assignee<'ast>> for types::Assignee<F> {
|
||||
fn from(assignee: ast::Assignee<'ast>) -> Self {
|
||||
let variable = types::Assignee::from(assignee.identifier);
|
||||
|
||||
@ -460,9 +435,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Assignee<'ast>> for types:
|
||||
|
||||
/// pest ast -> types::Statement
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ReturnStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ReturnStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ReturnStatement<'ast>) -> Self {
|
||||
types::Statement::Return(
|
||||
statement
|
||||
@ -474,9 +447,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ReturnStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::DefinitionStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::DefinitionStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::DefinitionStatement<'ast>) -> Self {
|
||||
types::Statement::Definition(
|
||||
types::Variable::from(statement.variable),
|
||||
@ -485,9 +456,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::DefinitionStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::AssignStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssignStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssignStatement<'ast>) -> Self {
|
||||
match statement.assign {
|
||||
ast::OperationAssign::Assign(ref _assign) => types::Statement::Assign(
|
||||
@ -543,8 +512,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::AssignStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::MultipleAssignmentStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::MultipleAssignmentStatement<'ast>>
|
||||
for types::Statement<F>
|
||||
{
|
||||
fn from(statement: ast::MultipleAssignmentStatement<'ast>) -> Self {
|
||||
let variables = statement
|
||||
@ -567,8 +536,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::MultipleAssignmentStatemen
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ConditionalNestedOrEnd<'ast>>
|
||||
for types::ConditionalNestedOrEnd<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ConditionalNestedOrEnd<'ast>>
|
||||
for types::ConditionalNestedOrEnd<F>
|
||||
{
|
||||
fn from(statement: ast::ConditionalNestedOrEnd<'ast>) -> Self {
|
||||
match statement {
|
||||
@ -585,8 +554,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ConditionalNestedOrEnd<'as
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ConditionalStatement<'ast>>
|
||||
for types::ConditionalStatement<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ConditionalStatement<'ast>>
|
||||
for types::ConditionalStatement<F>
|
||||
{
|
||||
fn from(statement: ast::ConditionalStatement<'ast>) -> Self {
|
||||
types::ConditionalStatement {
|
||||
@ -604,16 +573,14 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ConditionalStatement<'ast>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ForStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ForStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ForStatement<'ast>) -> Self {
|
||||
let from = match types::Expression::<F, G>::from(statement.start) {
|
||||
let from = match types::Expression::<F>::from(statement.start) {
|
||||
types::Expression::Integer(number) => number,
|
||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
};
|
||||
let to = match types::Expression::<F, G>::from(statement.stop) {
|
||||
let to = match types::Expression::<F>::from(statement.stop) {
|
||||
types::Expression::Integer(number) => number,
|
||||
types::Expression::Implicit(string) => types::Integer::from_implicit(string),
|
||||
expression => unimplemented!("Range bounds should be integers, found {}", expression),
|
||||
@ -632,9 +599,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ForStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::AssertStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::AssertStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::AssertStatement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::AssertStatement::AssertEq(assert_eq) => types::Statement::AssertEq(
|
||||
@ -645,15 +610,13 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::AssertStatement<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ExpressionStatement<'ast>>
|
||||
for types::Statement<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ExpressionStatement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::ExpressionStatement<'ast>) -> Self {
|
||||
types::Statement::Expression(types::Expression::from(statement.expression))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Statement<'ast>> for types::Statement<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Statement<'ast>> for types::Statement<F> {
|
||||
fn from(statement: ast::Statement<'ast>) -> Self {
|
||||
match statement {
|
||||
ast::Statement::Return(statement) => types::Statement::from(statement),
|
||||
@ -684,39 +647,39 @@ impl From<ast::IntegerType> for types::IntegerType {
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField, G: Group> From<ast::BasicType> for types::Type<F, G> {
|
||||
impl<F: Field + PrimeField> From<ast::BasicType> for types::Type<F> {
|
||||
fn from(basic_type: ast::BasicType) -> Self {
|
||||
match basic_type {
|
||||
ast::BasicType::Integer(_type) => {
|
||||
types::Type::IntegerType(types::IntegerType::from(_type))
|
||||
}
|
||||
ast::BasicType::Field(_type) => types::Type::FieldElement,
|
||||
ast::BasicType::Group(_type) => types::Type::GroupElement,
|
||||
ast::BasicType::Group(_type) => types::Type::Group,
|
||||
ast::BasicType::Boolean(_type) => types::Type::Boolean,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ArrayType<'ast>> for types::Type<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ArrayType<'ast>> for types::Type<F> {
|
||||
fn from(array_type: ast::ArrayType<'ast>) -> Self {
|
||||
let element_type = Box::new(types::Type::from(array_type._type));
|
||||
let dimensions = array_type
|
||||
.dimensions
|
||||
.into_iter()
|
||||
.map(|row| types::Expression::<F, G>::get_count(row))
|
||||
.map(|row| types::Expression::<F>::get_count(row))
|
||||
.collect();
|
||||
|
||||
types::Type::Array(element_type, dimensions)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitType<'ast>> for types::Type<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitType<'ast>> for types::Type<F> {
|
||||
fn from(circuit_type: ast::CircuitType<'ast>) -> Self {
|
||||
types::Type::Circuit(types::Identifier::from(circuit_type.identifier))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Type<'ast>> for types::Type<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Type<'ast>> for types::Type<F> {
|
||||
fn from(_type: ast::Type<'ast>) -> Self {
|
||||
match _type {
|
||||
ast::Type::Basic(_type) => types::Type::from(_type),
|
||||
@ -729,8 +692,8 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Type<'ast>> for types::Typ
|
||||
|
||||
/// pest ast -> types::Circuit
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitFieldDefinition<'ast>>
|
||||
for types::CircuitMember<F, G>
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitFieldDefinition<'ast>>
|
||||
for types::CircuitMember<F>
|
||||
{
|
||||
fn from(circuit_value: ast::CircuitFieldDefinition<'ast>) -> Self {
|
||||
types::CircuitMember::CircuitField(
|
||||
@ -740,9 +703,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitFieldDefinition<'as
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitFunction<'ast>>
|
||||
for types::CircuitMember<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitFunction<'ast>> for types::CircuitMember<F> {
|
||||
fn from(circuit_function: ast::CircuitFunction<'ast>) -> Self {
|
||||
types::CircuitMember::CircuitFunction(
|
||||
circuit_function._static.is_some(),
|
||||
@ -751,9 +712,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitFunction<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitMember<'ast>>
|
||||
for types::CircuitMember<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::CircuitMember<'ast>> for types::CircuitMember<F> {
|
||||
fn from(object: ast::CircuitMember<'ast>) -> Self {
|
||||
match object {
|
||||
ast::CircuitMember::CircuitFieldDefinition(circuit_value) => {
|
||||
@ -766,7 +725,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::CircuitMember<'ast>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Circuit<'ast>> for types::Circuit<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Circuit<'ast>> for types::Circuit<F> {
|
||||
fn from(circuit: ast::Circuit<'ast>) -> Self {
|
||||
let variable = types::Identifier::from(circuit.identifier);
|
||||
let members = circuit
|
||||
@ -784,9 +743,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Circuit<'ast>> for types::
|
||||
|
||||
/// pest ast -> function types::Parameters
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::InputModel<'ast>>
|
||||
for types::InputModel<F, G>
|
||||
{
|
||||
impl<'ast, F: Field + PrimeField> From<ast::InputModel<'ast>> for types::InputModel<F> {
|
||||
fn from(parameter: ast::InputModel<'ast>) -> Self {
|
||||
types::InputModel {
|
||||
identifier: types::Identifier::from(parameter.identifier),
|
||||
@ -802,7 +759,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::InputModel<'ast>>
|
||||
|
||||
/// pest ast -> types::Function
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Function<'ast>> for types::Function<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Function<'ast>> for types::Function<F> {
|
||||
fn from(function_definition: ast::Function<'ast>) -> Self {
|
||||
let function_name = types::Identifier::from(function_definition.function_name);
|
||||
let parameters = function_definition
|
||||
@ -832,7 +789,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Function<'ast>> for types:
|
||||
|
||||
/// pest ast -> Import
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::ImportSymbol<'ast>> for ImportSymbol<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::ImportSymbol<'ast>> for ImportSymbol<F> {
|
||||
fn from(symbol: ast::ImportSymbol<'ast>) -> Self {
|
||||
ImportSymbol {
|
||||
symbol: types::Identifier::from(symbol.value),
|
||||
@ -841,7 +798,7 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::ImportSymbol<'ast>> for Im
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> From<ast::Import<'ast>> for Import<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> From<ast::Import<'ast>> for Import<F> {
|
||||
fn from(import: ast::Import<'ast>) -> Self {
|
||||
Import {
|
||||
path_string: import.source.value,
|
||||
@ -856,14 +813,14 @@ impl<'ast, F: Field + PrimeField, G: Group> From<ast::Import<'ast>> for Import<F
|
||||
|
||||
/// pest ast -> types::Program
|
||||
|
||||
impl<'ast, F: Field + PrimeField, G: Group> types::Program<F, G> {
|
||||
impl<'ast, F: Field + PrimeField> types::Program<F> {
|
||||
pub fn from(file: ast::File<'ast>, name: String) -> Self {
|
||||
// Compiled ast -> aleo program representation
|
||||
let imports = file
|
||||
.imports
|
||||
.into_iter()
|
||||
.map(|import| Import::from(import))
|
||||
.collect::<Vec<Import<F, G>>>();
|
||||
.collect::<Vec<Import<F>>>();
|
||||
|
||||
let mut circuits = HashMap::new();
|
||||
let mut functions = HashMap::new();
|
||||
|
@ -1,53 +1,49 @@
|
||||
use crate::{compile_program, get_error, get_output};
|
||||
|
||||
use leo_compiler::errors::IntegerError;
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, FunctionError},
|
||||
errors::{CompilerError, FunctionError, IntegerError},
|
||||
ConstrainedValue, InputValue, Integer,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_models::gadgets::utilities::uint32::UInt32;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/array/";
|
||||
|
||||
// [1, 1, 1]
|
||||
fn output_ones(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_ones(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Array(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(
|
||||
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32))); 3]
|
||||
)]),
|
||||
output
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
// [[0, 0, 0],
|
||||
// [0, 0, 0]]
|
||||
fn output_multi(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_multi(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Array(vec![
|
||||
ConstrainedValue::Array(vec![
|
||||
ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(0u32)
|
||||
));
|
||||
3
|
||||
]);
|
||||
2
|
||||
])]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Array(vec![
|
||||
ConstrainedValue::Array(
|
||||
vec![ConstrainedValue::Integer(Integer::U32(UInt32::constant(0u32))); 3]
|
||||
);
|
||||
2
|
||||
])])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn fail_array(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_array(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::InvalidArray(_string)) => {}
|
||||
error => panic!("Expected invalid array error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::SynthesisError(_string),
|
||||
|
@ -1,37 +1,32 @@
|
||||
use crate::{compile_program, get_error, get_output};
|
||||
|
||||
use leo_compiler::errors::{BooleanError, ExpressionError};
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, FunctionError, StatementError},
|
||||
errors::{BooleanError, CompilerError, ExpressionError, FunctionError, StatementError},
|
||||
ConstrainedValue, InputValue,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/boolean/";
|
||||
|
||||
fn output_true(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub fn output_true(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
|
||||
Boolean::Constant(true)
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(true))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn output_false(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub fn output_false(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Boolean(
|
||||
Boolean::Constant(false)
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Boolean(Boolean::Constant(false))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn fail_evaluate(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_evaluate(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::BooleanError(
|
||||
@ -42,7 +37,7 @@ fn fail_evaluate(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_enforce(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_enforce(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::BooleanError(
|
||||
@ -53,7 +48,7 @@ fn fail_enforce(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_boolean(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_boolean(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(
|
||||
BooleanError::InvalidBoolean(_string),
|
||||
@ -62,7 +57,7 @@ fn fail_boolean(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::BooleanError(
|
||||
BooleanError::SynthesisError(_string),
|
||||
|
@ -1,40 +1,34 @@
|
||||
use crate::{
|
||||
compile_program,
|
||||
get_error,
|
||||
get_output,
|
||||
integer::u32::output_one,
|
||||
// group_element::output_zero
|
||||
compile_program, get_error, get_output, integer::u32::output_one, EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
||||
ConstrainedCircuitMember, ConstrainedValue, Expression, Function, Identifier, Integer,
|
||||
Statement, Type,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_models::gadgets::utilities::uint32::UInt32;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/circuit/";
|
||||
|
||||
// Circ { x: 1u32 }
|
||||
fn output_circuit(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_circuit(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![
|
||||
ConstrainedValue::CircuitExpression(
|
||||
Identifier::new("Circ".into()),
|
||||
vec![ConstrainedCircuitMember(
|
||||
Identifier::new("x".into()),
|
||||
ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32)))
|
||||
)]
|
||||
)
|
||||
]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::CircuitExpression(
|
||||
Identifier::new("Circ".into()),
|
||||
vec![ConstrainedCircuitMember(
|
||||
Identifier::new("x".into()),
|
||||
ConstrainedValue::Integer(Integer::U32(UInt32::constant(1u32)))
|
||||
)]
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn fail_expected_member(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_expected_member(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::ExpectedCircuitMember(_string)),
|
||||
@ -43,7 +37,7 @@ fn fail_expected_member(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_undefined_member(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_undefined_member(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedMemberAccess(_, _)),
|
||||
@ -153,27 +147,26 @@ fn test_self() {
|
||||
// }
|
||||
// }
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![
|
||||
ConstrainedValue::CircuitExpression(
|
||||
Identifier::new("Circ".into()),
|
||||
vec![ConstrainedCircuitMember(
|
||||
Identifier::new("new".into()),
|
||||
ConstrainedValue::Static(Box::new(ConstrainedValue::Function(
|
||||
Some(Identifier::new("Circ".into())),
|
||||
Function {
|
||||
function_name: Identifier::new("new".into()),
|
||||
inputs: vec![],
|
||||
returns: vec![Type::SelfType],
|
||||
statements: vec![Statement::Return(vec![Expression::Circuit(
|
||||
Identifier::new("Self".into()),
|
||||
vec![]
|
||||
)])]
|
||||
}
|
||||
)))
|
||||
)]
|
||||
)
|
||||
]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::CircuitExpression(
|
||||
Identifier::new("Circ".into()),
|
||||
vec![ConstrainedCircuitMember(
|
||||
Identifier::new("new".into()),
|
||||
ConstrainedValue::Static(Box::new(ConstrainedValue::Function(
|
||||
Some(Identifier::new("Circ".into())),
|
||||
Function {
|
||||
function_name: Identifier::new("new".into()),
|
||||
inputs: vec![],
|
||||
returns: vec![Type::SelfType],
|
||||
statements: vec![Statement::Return(vec![Expression::Circuit(
|
||||
Identifier::new("Self".into()),
|
||||
vec![]
|
||||
)])]
|
||||
}
|
||||
)))
|
||||
)]
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,37 @@
|
||||
use crate::{compile_program, get_error, get_output};
|
||||
|
||||
use leo_compiler::errors::FieldElementError;
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, FunctionError},
|
||||
errors::{CompilerError, FieldElementError, FunctionError},
|
||||
ConstrainedValue, FieldElement, InputValue,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::curves::Field;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/field_element/";
|
||||
|
||||
fn output_zero(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_zero(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::FieldElement(
|
||||
FieldElement::Constant(Fr::zero())
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::FieldElement(
|
||||
FieldElement::Constant(Fq::zero())
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn output_one(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_one(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::FieldElement(
|
||||
FieldElement::Constant(Fr::one())
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::FieldElement(
|
||||
FieldElement::Constant(Fq::one())
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn fail_field(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_field(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::FieldElementError(
|
||||
FieldElementError::InvalidField(_string),
|
||||
@ -40,7 +40,7 @@ fn fail_field(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::FieldElementError(
|
||||
FieldElementError::SynthesisError(_string),
|
||||
|
@ -1,36 +1,38 @@
|
||||
use crate::{compile_program, get_error, get_output, integer::u32::output_one};
|
||||
|
||||
use crate::{
|
||||
compile_program, get_error, get_output, integer::u32::output_one, EdwardsConstrainedValue,
|
||||
EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, ExpressionError, FunctionError, StatementError},
|
||||
ConstrainedValue,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_models::gadgets::utilities::boolean::Boolean;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/function/";
|
||||
|
||||
pub(crate) fn output_empty(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub(crate) fn output_empty(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![]).to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
// (true, false)
|
||||
pub(crate) fn output_multiple(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub(crate) fn output_multiple(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![
|
||||
EdwardsConstrainedValue::Return(vec![
|
||||
ConstrainedValue::Boolean(Boolean::Constant(true)),
|
||||
ConstrainedValue::Boolean(Boolean::Constant(false))
|
||||
]),
|
||||
output
|
||||
])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn fail_undefined_identifier(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_undefined_identifier(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::ExpressionError(ExpressionError::UndefinedIdentifier(_)),
|
||||
|
6
compiler/tests/group/add.leo
Normal file
6
compiler/tests/group/add.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 + point_2
|
||||
}
|
6
compiler/tests/group/assert_eq_false.leo
Normal file
6
compiler/tests/group/assert_eq_false.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
assert_eq!(point_1, point_2);
|
||||
}
|
6
compiler/tests/group/assert_eq_true.leo
Normal file
6
compiler/tests/group/assert_eq_true.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
|
||||
assert_eq!(point_1, point_2);
|
||||
}
|
6
compiler/tests/group/eq_false.leo
Normal file
6
compiler/tests/group/eq_false.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() -> bool {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 == point_2
|
||||
}
|
6
compiler/tests/group/eq_true.leo
Normal file
6
compiler/tests/group/eq_true.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() -> bool {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
|
||||
return point_1 == point_2
|
||||
}
|
3
compiler/tests/group/input.leo
Normal file
3
compiler/tests/group/input.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main(g: group) -> group {
|
||||
return g
|
||||
}
|
176
compiler/tests/group/mod.rs
Normal file
176
compiler/tests/group/mod.rs
Normal file
@ -0,0 +1,176 @@
|
||||
use crate::{
|
||||
boolean::{output_false, output_true},
|
||||
compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler,
|
||||
};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FunctionError, StatementError},
|
||||
group::edwards_bls12::EdwardsGroupType,
|
||||
ConstrainedValue, InputValue,
|
||||
};
|
||||
|
||||
use snarkos_curves::edwards_bls12::{EdwardsAffine, Fq};
|
||||
use snarkos_gadgets::curves::edwards_bls12::EdwardsBlsGadget;
|
||||
use snarkos_models::{
|
||||
curves::Group,
|
||||
gadgets::{curves::GroupGadget, r1cs::TestConstraintSystem, utilities::alloc::AllocGadget},
|
||||
};
|
||||
use std::str::FromStr;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group/";
|
||||
|
||||
const TEST_POINT_1: &str = "(7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)";
|
||||
const TEST_POINT_2: &str = "(1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)";
|
||||
|
||||
fn output_expected_constant(program: EdwardsTestCompiler, expected: EdwardsAffine) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(EdwardsGroupType::Constant(
|
||||
expected
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn output_expected_allocated(program: EdwardsTestCompiler, expected: EdwardsBlsGadget) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Group(
|
||||
EdwardsGroupType::Allocated(expected)
|
||||
)])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn output_zero(program: EdwardsTestCompiler) {
|
||||
output_expected_constant(program, EdwardsAffine::zero())
|
||||
}
|
||||
|
||||
fn fail_enforce(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::StatementError(
|
||||
StatementError::SynthesisError(_),
|
||||
)) => {}
|
||||
error => panic!("Expected evaluate error, got {}", error),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
output_zero(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_point() {
|
||||
let point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let program = compile_program(DIRECTORY_NAME, "point.leo").unwrap();
|
||||
output_expected_constant(program, point);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add() {
|
||||
use std::ops::Add;
|
||||
|
||||
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
|
||||
|
||||
let sum = point_1.add(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "add.leo").unwrap();
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sub() {
|
||||
use std::ops::Sub;
|
||||
|
||||
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
|
||||
|
||||
let sum = point_1.sub(&point_2);
|
||||
|
||||
let program = compile_program(DIRECTORY_NAME, "sub.leo").unwrap();
|
||||
output_expected_constant(program, sum);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "eq_true.leo").unwrap();
|
||||
output_true(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_eq_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "eq_false.leo").unwrap();
|
||||
output_false(program)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_eq_true() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assert_eq_true.leo").unwrap();
|
||||
let _res = get_output(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_eq_false() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assert_eq_false.leo").unwrap();
|
||||
fail_enforce(program);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input() {
|
||||
let mut program = compile_program(DIRECTORY_NAME, "input.leo").unwrap();
|
||||
program.set_inputs(vec![Some(InputValue::Group(TEST_POINT_1.into()))]);
|
||||
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let constant_point = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let allocated_point =
|
||||
<EdwardsBlsGadget as AllocGadget<EdwardsAffine, Fq>>::alloc(&mut cs, || Ok(constant_point))
|
||||
.unwrap();
|
||||
|
||||
output_expected_allocated(program, allocated_point);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ternary() {
|
||||
let mut program_1 = compile_program(DIRECTORY_NAME, "ternary.leo").unwrap();
|
||||
let mut program_2 = program_1.clone();
|
||||
|
||||
// true -> point_1
|
||||
program_1.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
|
||||
let point_1 = EdwardsAffine::from_str(TEST_POINT_1).unwrap();
|
||||
let output_1 = get_output(program_1);
|
||||
let actual_1: EdwardsAffine = match output_1 {
|
||||
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
||||
[ConstrainedValue::Group(EdwardsGroupType::Allocated(edwards_gadget))] => {
|
||||
<EdwardsBlsGadget as GroupGadget<EdwardsAffine, Fq>>::get_value(edwards_gadget)
|
||||
.unwrap()
|
||||
}
|
||||
_ => panic!("program output unknown return value"),
|
||||
},
|
||||
_ => panic!("program output unknown return value"),
|
||||
};
|
||||
|
||||
assert_eq!(point_1, actual_1);
|
||||
|
||||
// false -> point_2
|
||||
program_2.set_inputs(vec![Some(InputValue::Boolean(false))]);
|
||||
|
||||
let point_2 = EdwardsAffine::from_str(TEST_POINT_2).unwrap();
|
||||
let output_2 = get_output(program_2);
|
||||
let actual_2: EdwardsAffine = match output_2 {
|
||||
EdwardsConstrainedValue::Return(vec) => match vec.as_slice() {
|
||||
[ConstrainedValue::Group(EdwardsGroupType::Allocated(edwards_gadget))] => {
|
||||
<EdwardsBlsGadget as GroupGadget<EdwardsAffine, Fq>>::get_value(edwards_gadget)
|
||||
.unwrap()
|
||||
}
|
||||
_ => panic!("program output unknown return value"),
|
||||
},
|
||||
_ => panic!("program output unknown return value"),
|
||||
};
|
||||
|
||||
assert_eq!(point_2, actual_2);
|
||||
}
|
3
compiler/tests/group/point.leo
Normal file
3
compiler/tests/group/point.leo
Normal file
@ -0,0 +1,3 @@
|
||||
function main() -> group {
|
||||
return (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group
|
||||
}
|
6
compiler/tests/group/sub.leo
Normal file
6
compiler/tests/group/sub.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main() -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return point_1 - point_2
|
||||
}
|
6
compiler/tests/group/ternary.leo
Normal file
6
compiler/tests/group/ternary.leo
Normal file
@ -0,0 +1,6 @@
|
||||
function main (b: bool) -> group {
|
||||
let point_1 = (7374112779530666882856915975292384652154477718021969292781165691637980424078, 3435195339177955418892975564890903138308061187980579490487898366607011481796)group;
|
||||
let point_2 = (1005842117974384149622370061042978581211342111653966059496918451529532134799, 79389132189982034519597104273449021362784864778548730890166152019533697186)group;
|
||||
|
||||
return if b ? point_1 : point_2
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
use crate::{compile_program, get_output};
|
||||
|
||||
use leo_compiler::{compiler::Compiler, ConstrainedValue};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
use snarkos_models::curves::Group;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/group_element/";
|
||||
|
||||
pub(crate) fn output_zero(program: Compiler<Fr, EdwardsProjective>) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::GroupElement(
|
||||
EdwardsProjective::zero()
|
||||
)]),
|
||||
output
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero() {
|
||||
let program = compile_program(DIRECTORY_NAME, "zero.leo").unwrap();
|
||||
output_zero(program);
|
||||
}
|
@ -1,44 +1,48 @@
|
||||
use crate::{compile_program, get_error, get_output};
|
||||
use crate::{compile_program, get_error, get_output, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
errors::{CompilerError, FunctionError, IntegerError},
|
||||
types::Integer,
|
||||
ConstrainedValue, InputValue,
|
||||
};
|
||||
|
||||
use leo_compiler::{compiler::Compiler, types::Integer, ConstrainedValue, InputValue};
|
||||
|
||||
use leo_compiler::errors::{CompilerError, FunctionError, IntegerError};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
use snarkos_models::gadgets::utilities::uint32::UInt32;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/integer/u32/";
|
||||
|
||||
pub(crate) fn output_zero(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub(crate) fn output_zero(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
|
||||
Integer::U32(UInt32::constant(0u32))
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(0u32)
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn output_one(program: Compiler<Fr, EdwardsProjective>) {
|
||||
pub(crate) fn output_one(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
|
||||
Integer::U32(UInt32::constant(1u32))
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(1u32)
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn output_two(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn output_two(program: EdwardsTestCompiler) {
|
||||
let output = get_output(program);
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
|
||||
Integer::U32(UInt32::constant(2u32))
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(2u32)
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn fail_integer(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_integer(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::InvalidInteger(_string),
|
||||
@ -47,7 +51,7 @@ fn fail_integer(program: Compiler<Fr, EdwardsProjective>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn fail_synthesis(program: Compiler<Fr, EdwardsProjective>) {
|
||||
fn fail_synthesis(program: EdwardsTestCompiler) {
|
||||
match get_error(program) {
|
||||
CompilerError::FunctionError(FunctionError::IntegerError(
|
||||
IntegerError::SynthesisError(_string),
|
||||
|
@ -3,37 +3,40 @@ pub mod boolean;
|
||||
pub mod circuit;
|
||||
pub mod field_element;
|
||||
pub mod function;
|
||||
pub mod group_element;
|
||||
pub mod group;
|
||||
pub mod import;
|
||||
pub mod integer;
|
||||
pub mod mutability;
|
||||
pub mod statement;
|
||||
|
||||
use leo_compiler::{compiler::Compiler, errors::CompilerError, ConstrainedValue};
|
||||
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler, errors::CompilerError, group::edwards_bls12::EdwardsGroupType,
|
||||
ConstrainedValue,
|
||||
};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
use std::env::current_dir;
|
||||
|
||||
pub(crate) fn get_output(
|
||||
program: Compiler<Fr, EdwardsProjective>,
|
||||
) -> ConstrainedValue<Fr, EdwardsProjective> {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
pub type EdwardsTestCompiler = Compiler<Fq, EdwardsGroupType>;
|
||||
pub type EdwardsConstrainedValue = ConstrainedValue<Fq, EdwardsGroupType>;
|
||||
|
||||
pub(crate) fn get_output(program: EdwardsTestCompiler) -> EdwardsConstrainedValue {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
assert!(cs.is_satisfied());
|
||||
output
|
||||
}
|
||||
|
||||
pub(crate) fn get_error(program: Compiler<Fr, EdwardsProjective>) -> CompilerError {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
pub(crate) fn get_error(program: EdwardsTestCompiler) -> CompilerError {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
program.compile_constraints(&mut cs).unwrap_err()
|
||||
}
|
||||
|
||||
pub(crate) fn compile_program(
|
||||
directory_name: &str,
|
||||
file_name: &str,
|
||||
) -> Result<Compiler<Fr, EdwardsProjective>, CompilerError> {
|
||||
) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
let path = current_dir().map_err(|error| CompilerError::DirectoryError(error))?;
|
||||
|
||||
// Sanitize the package path to the test directory
|
||||
@ -50,5 +53,5 @@ pub(crate) fn compile_program(
|
||||
println!("Compiling file - {:?}", main_file_path);
|
||||
|
||||
// Compile from the main file path
|
||||
Compiler::<Fr, EdwardsProjective>::init(file_name.to_string(), main_file_path)
|
||||
EdwardsTestCompiler::init(file_name.to_string(), main_file_path)
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
use crate::compile_program;
|
||||
|
||||
use crate::{compile_program, EdwardsConstrainedValue, EdwardsTestCompiler};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
errors::{CompilerError, FunctionError, StatementError},
|
||||
types::{InputValue, Integer},
|
||||
ConstrainedValue,
|
||||
};
|
||||
use snarkos_curves::{bls12_377::Fr, edwards_bls12::EdwardsProjective};
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::{r1cs::TestConstraintSystem, utilities::uint32::UInt32};
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/mutability/";
|
||||
|
||||
fn mut_success(program: Compiler<Fr, EdwardsProjective>) {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
fn mut_success(program: EdwardsTestCompiler) {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let output = program.compile_constraints(&mut cs).unwrap();
|
||||
|
||||
assert!(cs.is_satisfied());
|
||||
assert_eq!(
|
||||
ConstrainedValue::<Fr, EdwardsProjective>::Return(vec![ConstrainedValue::Integer(
|
||||
Integer::U32(UInt32::constant(0))
|
||||
)]),
|
||||
output
|
||||
EdwardsConstrainedValue::Return(vec![ConstrainedValue::Integer(Integer::U32(
|
||||
UInt32::constant(0)
|
||||
))])
|
||||
.to_string(),
|
||||
output.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
fn mut_fail(program: Compiler<Fr, EdwardsProjective>) {
|
||||
let mut cs = TestConstraintSystem::<Fr>::new();
|
||||
fn mut_fail(program: EdwardsTestCompiler) {
|
||||
let mut cs = TestConstraintSystem::<Fq>::new();
|
||||
let err = program.compile_constraints(&mut cs).unwrap_err();
|
||||
|
||||
// It would be ideal if assert_eq!(Error1, Error2) were possible but unfortunately it is not due to
|
||||
|
@ -3,7 +3,8 @@ use crate::{
|
||||
integer::u32::{output_one, output_zero},
|
||||
};
|
||||
use leo_compiler::InputValue;
|
||||
use snarkos_curves::bls12_377::Fr;
|
||||
|
||||
use snarkos_curves::edwards_bls12::Fq;
|
||||
use snarkos_models::gadgets::r1cs::TestConstraintSystem;
|
||||
|
||||
const DIRECTORY_NAME: &str = "tests/statement/";
|
||||
@ -37,7 +38,7 @@ fn test_assertion_basic() {
|
||||
let program = compile_program(DIRECTORY_NAME, "assertion_basic.leo").unwrap();
|
||||
|
||||
let mut program_input_true = program.clone();
|
||||
let mut cs_satisfied = TestConstraintSystem::<Fr>::new();
|
||||
let mut cs_satisfied = TestConstraintSystem::<Fq>::new();
|
||||
|
||||
program_input_true.set_inputs(vec![Some(InputValue::Boolean(true))]);
|
||||
let _output = program_input_true
|
||||
@ -47,7 +48,7 @@ fn test_assertion_basic() {
|
||||
assert!(cs_satisfied.is_satisfied());
|
||||
|
||||
let mut program_input_false = program.clone();
|
||||
let mut cs_unsatisfied = TestConstraintSystem::<Fr>::new();
|
||||
let mut cs_unsatisfied = TestConstraintSystem::<Fq>::new();
|
||||
|
||||
program_input_false.set_inputs(vec![Some(InputValue::Boolean(false))]);
|
||||
let _output = program_input_false
|
||||
|
@ -2,12 +2,15 @@ use crate::directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory};
|
||||
use crate::errors::{BuildError, CLIError};
|
||||
use crate::files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
group::edwards_bls12::EdwardsGroupType
|
||||
};
|
||||
|
||||
use snarkos_algorithms::snark::KeypairAssembly;
|
||||
use snarkos_curves::{
|
||||
bls12_377::{Bls12_377, Fr},
|
||||
edwards_bls12::EdwardsProjective
|
||||
bls12_377::Bls12_377,
|
||||
edwards_bls12::Fq
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
@ -19,7 +22,7 @@ pub struct BuildCommand;
|
||||
|
||||
impl CLI for BuildCommand {
|
||||
type Options = ();
|
||||
type Output = (Compiler<Fr, EdwardsProjective>, bool);
|
||||
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
|
||||
|
||||
const NAME: NameType = "build";
|
||||
const ABOUT: AboutType = "Compile the current package as a program";
|
||||
@ -63,7 +66,8 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Compute the current program checksum
|
||||
let program = Compiler::<Fr, EdwardsProjective>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::init(package_name.clone(), main_file_path.clone())?;
|
||||
let program_checksum = program.checksum()?;
|
||||
|
||||
// Generate the program on the constraint system and verify correctness
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::SetupCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::{Manifest, ProofFile};
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use snarkos_algorithms::snark::{create_random_proof, Proof};
|
||||
use snarkos_curves::bls12_377::Bls12_377;
|
||||
@ -45,7 +45,10 @@ impl CLI for ProveCommand {
|
||||
let rng = &mut thread_rng();
|
||||
let program_proof = create_random_proof(program, ¶meters, rng).unwrap();
|
||||
|
||||
log::info!("Prover completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||
log::info!(
|
||||
"Prover completed in {:?} milliseconds",
|
||||
start.elapsed().as_millis()
|
||||
);
|
||||
|
||||
// Write the proof file to the outputs directory
|
||||
let mut proof = vec![];
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::commands::{SetupCommand, ProveCommand};
|
||||
use crate::commands::{ProveCommand, SetupCommand};
|
||||
use crate::errors::CLIError;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::{CLIError, VerificationKeyFileError};
|
||||
use crate::files::{Manifest, ProvingKeyFile, VerificationKeyFile};
|
||||
use leo_compiler::compiler::Compiler;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use leo_compiler::{
|
||||
compiler::Compiler,
|
||||
group::edwards_bls12::EdwardsGroupType
|
||||
};
|
||||
|
||||
use snarkos_algorithms::snark::{
|
||||
generate_random_parameters, prepare_verifying_key, Parameters, PreparedVerifyingKey,
|
||||
};
|
||||
use snarkos_curves::{
|
||||
bls12_377::{Bls12_377, Fr},
|
||||
edwards_bls12::EdwardsProjective
|
||||
bls12_377::Bls12_377,
|
||||
edwards_bls12::Fq
|
||||
};
|
||||
use snarkos_utilities::bytes::ToBytes;
|
||||
|
||||
@ -25,7 +28,7 @@ pub struct SetupCommand;
|
||||
impl CLI for SetupCommand {
|
||||
type Options = ();
|
||||
type Output = (
|
||||
Compiler<Fr, EdwardsProjective>,
|
||||
Compiler<Fq, EdwardsGroupType>,
|
||||
Parameters<Bls12_377>,
|
||||
PreparedVerifyingKey<Bls12_377>,
|
||||
);
|
||||
@ -66,7 +69,10 @@ impl CLI for SetupCommand {
|
||||
let prepared_verifying_key = prepare_verifying_key::<Bls12_377>(¶meters.vk);
|
||||
|
||||
// End the timer
|
||||
log::info!("Setup completed in {:?} milliseconds", start.elapsed().as_millis());
|
||||
log::info!(
|
||||
"Setup completed in {:?} milliseconds",
|
||||
start.elapsed().as_millis()
|
||||
);
|
||||
|
||||
// TODO (howardwu): Convert parameters to a 'proving key' struct for serialization.
|
||||
// Write the proving key file to the outputs directory
|
||||
@ -95,10 +101,13 @@ impl CLI for SetupCommand {
|
||||
prepared_verifying_key.write(&mut verification_key)?;
|
||||
|
||||
// Check that the constructed prepared verification key matches the stored verification key
|
||||
let compare: Vec<(u8, u8)> = verification_key.into_iter().zip(stored_vk.into_iter()).collect();
|
||||
let compare: Vec<(u8, u8)> = verification_key
|
||||
.into_iter()
|
||||
.zip(stored_vk.into_iter())
|
||||
.collect();
|
||||
for (a, b) in compare {
|
||||
if a != b {
|
||||
return Err(VerificationKeyFileError::IncorrectVerificationKey.into())
|
||||
return Err(VerificationKeyFileError::IncorrectVerificationKey.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{cli::*, cli_types::*};
|
||||
use crate::commands::BuildCommand;
|
||||
use crate::errors::CLIError;
|
||||
use crate::files::Manifest;
|
||||
use crate::{cli::*, cli_types::*};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -31,7 +31,10 @@ impl ChecksumFile {
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<String, ChecksumFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
Ok(fs::read_to_string(&path).map_err(|_| ChecksumFileError::FileReadError(path.clone()))?)
|
||||
Ok(
|
||||
fs::read_to_string(&path)
|
||||
.map_err(|_| ChecksumFileError::FileReadError(path.clone()))?,
|
||||
)
|
||||
}
|
||||
|
||||
/// Writes the given checksum to a file.
|
||||
@ -52,7 +55,10 @@ impl ChecksumFile {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, CHECKSUM_FILE_EXTENSION)));
|
||||
path.push(PathBuf::from(format!(
|
||||
"{}{}",
|
||||
self.package_name, CHECKSUM_FILE_EXTENSION
|
||||
)));
|
||||
}
|
||||
path
|
||||
}
|
||||
|
@ -31,7 +31,8 @@ impl ProofFile {
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<String, ProofFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let proof = fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
|
||||
let proof =
|
||||
fs::read_to_string(&path).map_err(|_| ProofFileError::FileReadError(path.clone()))?;
|
||||
Ok(proof)
|
||||
}
|
||||
|
||||
@ -53,7 +54,10 @@ impl ProofFile {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, PROOF_FILE_EXTENSION)));
|
||||
path.push(PathBuf::from(format!(
|
||||
"{}{}",
|
||||
self.package_name, PROOF_FILE_EXTENSION
|
||||
)));
|
||||
}
|
||||
path
|
||||
}
|
||||
|
@ -52,7 +52,10 @@ impl ProvingKeyFile {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, PROVING_KEY_FILE_EXTENSION)));
|
||||
path.push(PathBuf::from(format!(
|
||||
"{}{}",
|
||||
self.package_name, PROVING_KEY_FILE_EXTENSION
|
||||
)));
|
||||
}
|
||||
path
|
||||
}
|
||||
|
@ -35,7 +35,11 @@ impl VerificationKeyFile {
|
||||
}
|
||||
|
||||
/// Writes the given verification key to a file.
|
||||
pub fn write_to(&self, path: &PathBuf, verification_key: &[u8]) -> Result<(), VerificationKeyFileError> {
|
||||
pub fn write_to(
|
||||
&self,
|
||||
path: &PathBuf,
|
||||
verification_key: &[u8],
|
||||
) -> Result<(), VerificationKeyFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
@ -52,7 +56,10 @@ impl VerificationKeyFile {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, VERIFICATION_KEY_FILE_EXTENSION)));
|
||||
path.push(PathBuf::from(format!(
|
||||
"{}{}",
|
||||
self.package_name, VERIFICATION_KEY_FILE_EXTENSION
|
||||
)));
|
||||
}
|
||||
path
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user