1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

merge dev

This commit is contained in:
schaeff 2020-10-08 15:17:46 +02:00
commit 954ffb943c
18 changed files with 224 additions and 155 deletions

View file

@ -0,0 +1,2 @@
def main():
return 1

View file

@ -1,2 +0,0 @@
def main(field a) -> field:
return a*2**3

View file

@ -2,6 +2,6 @@
// /!\ should be called with a = 0
def main(field a) -> bool:
field p = 21888242871839275222246405745257275088548364400416034343698204186575808495617 + a
field p = 21888242871839275222246405745257275088548364400416034343698204186575808495616 + a
// we added a = 0 to prevent the condition to be evaluated at compile time
return 0 < p - 1
return 0 < p

View file

@ -994,7 +994,7 @@ mod tests {
use super::*;
#[test]
fn examples() {
fn compile_examples() {
for p in glob("./examples/**/*").expect("Failed to read glob pattern") {
let path = match p {
Ok(x) => x,
@ -1007,9 +1007,7 @@ mod tests {
assert!(path.extension().expect("extension expected") == "zok");
if path.to_str().unwrap().contains("error") {
continue;
}
let should_error = path.to_str().unwrap().contains("compile_errors");
println!("Testing {:?}", path);
@ -1022,13 +1020,14 @@ mod tests {
let stdlib = std::fs::canonicalize("../zokrates_stdlib/stdlib").unwrap();
let resolver = FileSystemResolver::with_stdlib_root(stdlib.to_str().unwrap());
let _: CompilationArtifacts<Bn128Field> =
compile(source, path, Some(&resolver)).unwrap();
let res = compile::<Bn128Field, _>(source, path, Some(&resolver));
assert_eq!(res.is_err(), should_error);
}
}
#[test]
fn examples_with_input_success() {
fn execute_examples_ok() {
//these examples should compile and run
for p in glob("./examples/test*").expect("Failed to read glob pattern") {
let path = match p {
@ -1059,7 +1058,7 @@ mod tests {
#[test]
#[should_panic]
fn examples_with_input_failure() {
fn execute_examples_err() {
//these examples should compile but not run
for p in glob("./examples/runtime_errors/*").expect("Failed to read glob pattern") {
let path = match p {

View file

@ -292,7 +292,7 @@ mod test {
#[test]
fn use_struct_declaration_types() {
// when importing types and renaming them, we use the top-most renaming in the ABI
// when importing types and renaming them, we use the canonical struct names in the ABI
// // main.zok
// from foo import Foo as FooMain
@ -305,7 +305,7 @@ mod test {
// struct Bar { field a }
// Expected resolved type for FooMain:
// FooMain { BarFoo b }
// Foo { Bar b }
let main = r#"
from "foo" import Foo as FooMain
@ -370,21 +370,21 @@ struct Bar { field a }
inputs: vec![AbiInput {
name: "f".into(),
public: true,
ty: Type::Struct(StructType {
module: "main".into(),
name: "FooMain".into(),
members: vec![StructMember {
ty: Type::Struct(StructType::new(
"foo".into(),
"Foo".into(),
vec![StructMember {
id: "b".into(),
ty: box Type::Struct(StructType {
module: "foo".into(),
name: "BarFoo".into(),
members: vec![StructMember {
ty: box Type::Struct(StructType::new(
"bar".into(),
"Bar".into(),
vec![StructMember {
id: "a".into(),
ty: box Type::FieldElement
}]
})
))
}]
})
))
}],
outputs: vec![]
}

View file

@ -18,7 +18,9 @@ use crate::parser::Position;
use crate::absy::types::{UnresolvedSignature, UnresolvedType, UserTypeId};
use std::hash::{Hash, Hasher};
use typed_absy::types::{ArrayType, FunctionKey, Signature, StructMember, StructType, Type};
use typed_absy::types::{
ArrayType, FunctionKey, Signature, StructLocation, StructMember, StructType, Type,
};
#[derive(PartialEq, Debug)]
pub struct ErrorInner {
@ -123,6 +125,7 @@ impl fmt::Display for ErrorInner {
}
/// A function query in the current module.
#[derive(Debug)]
struct FunctionQuery<'ast> {
id: Identifier<'ast>,
inputs: Vec<Type>,
@ -448,8 +451,10 @@ impl<'ast> Checker<'ast> {
// rename the type to the declared symbol
let t = match t {
Type::Struct(t) => Type::Struct(StructType {
module: module_id.clone(),
name: declaration.id.into(),
location: Some(StructLocation {
name: declaration.id.into(),
module: module_id.clone()
}),
..t
}),
_ => unreachable!()
@ -685,45 +690,58 @@ impl<'ast> Checker<'ast> {
Ok(statement) => {
let statement = match statement {
TypedStatement::Return(e) => {
match e
.iter()
.zip(s.outputs.clone())
.map(|(e, t)| {
TypedExpression::align_to_type(e.clone(), t.into())
})
.collect::<Result<Vec<_>, _>>()
.map_err(|e| {
vec![ErrorInner {
match e.len() == s.outputs.len() {
true => match e
.iter()
.zip(s.outputs.clone())
.map(|(e, t)| {
TypedExpression::align_to_type(e.clone(), t.into())
})
.collect::<Result<Vec<_>, _>>()
.map_err(|e| {
vec![ErrorInner {
pos: Some(pos),
message: format!("Expected return value to be of type {}, found {}", e.1, e.0),
}]
}) {
Ok(e) => {
match e.iter().map(|e| e.get_type()).collect::<Vec<_>>()
== s.outputs
{
true => {},
false => errors.push(ErrorInner {
pos: Some(pos),
message: format!(
"Expected ({}) in return statement, found ({})",
s.outputs
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", "),
e.iter()
.map(|e| e.get_type())
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", ")
),
}),
};
TypedStatement::Return(e)
}
Err(err) => {
errors.extend(err);
TypedStatement::Return(e)
}
},
false => {
errors.push(ErrorInner {
pos: Some(pos),
message: format!("Expected return value to be of type {}, found {}", e.1, e.0),
}]
}) {
Ok(e) => {
match e.iter().map(|e| e.get_type()).collect::<Vec<_>>()
== s.outputs
{
true => {},
false => errors.push(ErrorInner {
pos: Some(pos),
message: format!(
"Expected ({}) in return statement, found ({})",
s.outputs
.iter()
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", "),
e.iter()
.map(|e| e.get_type())
.map(|t| t.to_string())
.collect::<Vec<_>>()
.join(", ")
),
}),
};
TypedStatement::Return(e)
}
Err(err) => {
errors.extend(err);
message: format!(
"Expected {} expressions in return statement, found {}",
s.outputs.len(),
e.len()
),
});
TypedStatement::Return(e)
}
}

View file

@ -234,15 +234,7 @@ impl<'ast, T: Field> Inliner<'ast, T> {
Ok(res)
}
// if the function is a flat symbol, replace the call with a call to the local function we provide so it can be inlined in flattening
TypedFunctionSymbol::Flat(embed) => {
// increase the number of calls for this function by one
let _ = self
.call_count
.entry((self.module_id().clone(), embed.key::<T>().clone()))
.and_modify(|i| *i += 1)
.or_insert(1);
Err((embed.key::<T>(), expressions.clone()))
}
TypedFunctionSymbol::Flat(embed) => Err((embed.key::<T>(), expressions.clone())),
};
res.map(|exprs| {
@ -348,21 +340,38 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::FieldElement(e) => e,
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
.push(TypedStatement::MultipleDefinition(
vec![Variable::with_id_and_type(id.clone(), tys[0].clone())],
TypedExpressionList::FunctionCall(key, expressions, tys),
TypedExpressionList::FunctionCall(
key.clone(),
expressions.clone(),
tys,
),
));
self.call_cache_mut()
.entry(key.clone())
.or_insert_with(|| HashMap::new())
.insert(
expressions,
vec![FieldElementExpression::Identifier(id.clone()).into()],
);
FieldElementExpression::Identifier(id)
}
}
@ -385,14 +394,18 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::Boolean(e) => e,
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
@ -440,11 +453,15 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), embed_key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
@ -490,22 +507,38 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
TypedExpression::Struct(e) => e.into_inner(),
_ => unreachable!(),
},
Err((key, expressions)) => {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer
.push(TypedStatement::MultipleDefinition(
vec![Variable::with_id_and_type(id.clone(), tys[0].clone())],
TypedExpressionList::FunctionCall(key, expressions, tys),
TypedExpressionList::FunctionCall(
key.clone(),
expressions.clone(),
tys,
),
));
StructExpressionInner::Identifier(id)
let out = StructExpressionInner::Identifier(id);
self.call_cache_mut()
.entry(key.clone())
.or_insert_with(|| HashMap::new())
.insert(expressions, vec![out.clone().annotate(ty.clone()).into()]);
out
}
}
}
@ -531,11 +564,15 @@ impl<'ast, T: Field> Folder<'ast, T> for Inliner<'ast, T> {
Err((embed_key, expressions)) => {
let tys = key.signature.outputs.clone();
let id = Identifier {
id: CoreIdentifier::Call(key.clone()),
version: *self
.call_count
.get(&(self.module_id().clone(), embed_key.clone()))
.unwrap(),
id: CoreIdentifier::Call(
key.clone(),
*self
.call_count
.entry((self.module_id().clone(), embed_key.clone()))
.and_modify(|i| *i += 1)
.or_insert(1),
),
version: 0,
stack: self.stack.clone(),
};
self.statement_buffer

View file

@ -39,6 +39,7 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
pub fn analyse(self) -> ZirProgram<'ast, T> {
// propagated unrolling
let r = PropagatedUnroller::unroll(self).unwrap_or_else(|e| panic!(e));
// return binding
let r = ReturnBinder::bind(r);

View file

@ -6,7 +6,7 @@ use typed_absy::TypedModuleId;
pub enum CoreIdentifier<'ast> {
Source(&'ast str),
Internal(&'static str, usize),
Call(FunctionKey<'ast>),
Call(FunctionKey<'ast>, usize),
}
impl<'ast> fmt::Display for CoreIdentifier<'ast> {
@ -14,7 +14,7 @@ impl<'ast> fmt::Display for CoreIdentifier<'ast> {
match self {
CoreIdentifier::Source(s) => write!(f, "{}", s),
CoreIdentifier::Internal(s, i) => write!(f, "#INTERNAL#_{}_{}", s, i),
CoreIdentifier::Call(k) => write!(f, "{}", k.to_slug()),
CoreIdentifier::Call(k, i) => write!(f, "{}_{}", k.to_slug(), i),
}
}
}

View file

@ -1,5 +1,5 @@
use std::fmt;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
pub type Identifier<'ast> = &'ast str;
@ -20,17 +20,25 @@ pub struct ArrayType {
pub ty: Box<Type>,
}
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct StructType {
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialOrd, Ord, Eq, PartialEq)]
pub struct StructLocation {
#[serde(skip)]
pub module: PathBuf,
pub name: String,
}
#[derive(Debug, Clone, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub struct StructType {
#[serde(flatten)]
pub canonical_location: StructLocation,
#[serde(skip)]
pub location: Option<StructLocation>,
pub members: Vec<StructMember>,
}
impl PartialEq for StructType {
fn eq(&self, other: &Self) -> bool {
self.members.eq(&other.members)
self.canonical_location.eq(&other.canonical_location) && self.members.eq(&other.members)
}
}
@ -39,8 +47,8 @@ impl Eq for StructType {}
impl StructType {
pub fn new(module: PathBuf, name: String, members: Vec<StructMember>) -> Self {
StructType {
module,
name,
canonical_location: StructLocation { module, name },
location: None,
members,
}
}
@ -52,6 +60,18 @@ impl StructType {
pub fn iter(&self) -> std::slice::Iter<StructMember> {
self.members.iter()
}
fn location(&self) -> &StructLocation {
&self.location.as_ref().unwrap_or(&self.canonical_location)
}
pub fn name(&self) -> &str {
&self.location().name
}
pub fn module(&self) -> &Path {
&self.location().module
}
}
impl IntoIterator for StructType {
@ -237,7 +257,7 @@ impl fmt::Display for Type {
Type::Struct(ref struct_type) => write!(
f,
"{} {{{}}}",
struct_type.name,
struct_type.name(),
struct_type
.members
.iter()
@ -257,17 +277,7 @@ impl fmt::Debug for Type {
Type::Int => write!(f, "{{integer}}"),
Type::Uint(ref bitwidth) => write!(f, "u{}", bitwidth),
Type::Array(ref array_type) => write!(f, "{}[{}]", array_type.ty, array_type.size),
Type::Struct(ref struct_type) => write!(
f,
"{} {{{}}}",
struct_type.name,
struct_type
.members
.iter()
.map(|member| format!("{}: {}", member.id, member.ty))
.collect::<Vec<_>>()
.join(", ")
),
Type::Struct(ref struct_type) => write!(f, "{:?}", struct_type),
}
}
}

View file

@ -1,3 +1,4 @@
import "utils/multiplexer/lookup3bitSigned" as sel3s
import "utils/multiplexer/lookup2bit" as sel2
import "ecc/babyjubjubParams" as context
@ -15,35 +16,38 @@ import "EMBED/u32_from_bits" as from_bits
// #%%
// entropy = np.random.bytes(64)
// hasher = PedersenHasher("test")
// hasher.hash_bytes(entropy)
// print(hasher.dsl_code)
// 512bit to 256bit Pedersen hash using compression of the field elements
def main(u32[16] input) -> u32[8]:
bool[512] e = [ \
...to_bits(input[0]),
...to_bits(input[1]),
...to_bits(input[2]),
...to_bits(input[3]),
...to_bits(input[4]),
...to_bits(input[5]),
...to_bits(input[6]),
...to_bits(input[7]),
...to_bits(input[8]),
...to_bits(input[9]),
...to_bits(input[10]),
...to_bits(input[11]),
...to_bits(input[12]),
...to_bits(input[13]),
...to_bits(input[14]),
...to_bits(input[15])
def main(u32[16] inputs) -> u32[8]:
bool[513] e = [\
...to_bits(inputs[0]),
...to_bits(inputs[1]),
...to_bits(inputs[2]),
...to_bits(inputs[3]),
...to_bits(inputs[4]),
...to_bits(inputs[5]),
...to_bits(inputs[6]),
...to_bits(inputs[7]),
...to_bits(inputs[8]),
...to_bits(inputs[9]),
...to_bits(inputs[10]),
...to_bits(inputs[11]),
...to_bits(inputs[12]),
...to_bits(inputs[13]),
...to_bits(inputs[14]),
...to_bits(inputs[15]),
false
]
BabyJubJubParams context = context()
field[2] a = context.INFINITY //Infinity
field cx = 0
field cy = 0
//Round 0
field cx = sel3s([e[0], e[1], e[2]], [13418723823902222986275588345615650707197303761863176429873001977640541977977 , 8366451672790208592553809639953117385619257483837439526516290319251622927412, 1785026334726838136757054176272745265857971873904476677125553010508875025629, 15763987975760561753692294837740043971877392788040801334205375164715487005236])
field cy = sel2([e[0], e[1]], [15255921313433251341520743036334816584226787412845488772781699434149539664639 , 10916775373885716961512013142444429405184550001421868906213743991404593770484, 18533662942827602783563125901366807026309605479742251601915445402562880550265, 12754584346112149619040942896930712185968371085994381911052593922432846916845])
cx = sel3s([e[0], e[1], e[2]], [13418723823902222986275588345615650707197303761863176429873001977640541977977 , 8366451672790208592553809639953117385619257483837439526516290319251622927412, 1785026334726838136757054176272745265857971873904476677125553010508875025629, 15763987975760561753692294837740043971877392788040801334205375164715487005236])
cy = sel2([e[0], e[1]], [15255921313433251341520743036334816584226787412845488772781699434149539664639 , 10916775373885716961512013142444429405184550001421868906213743991404593770484, 18533662942827602783563125901366807026309605479742251601915445402562880550265, 12754584346112149619040942896930712185968371085994381911052593922432846916845])
a = add(a, [cx, cy], context)
//Round 1
cx = sel3s([e[3], e[4], e[5]], [10096735692467598736728394557736034054031417419721869067082824451240861468728 , 6979151010236415881632946866847657030447196774231162748523315765559549846746, 12137947022495312670974525048647679757468392619153927921382150023166867027471, 10624360821702266736197468438435445939719745367234393212061381062942588576905])
@ -722,19 +726,19 @@ def main(u32[16] input) -> u32[8]:
cy = sel2([e[507], e[508]], [18191174947339798787646910619446409943766046946921136035021645191602921923040 , 16559060177998758852323304784771936179434931576336411584121379336820727372618, 13858115732979799183025726471151602712224733686530960054365665740611187232029, 9933192519609817862698304326029579651414877338671776883175639003837130283966])
a = add(a, [cx, cy], context)
//Round 170
cx = sel3s([e[510], e[511], false], [3342564788366736273905106071612128667477972061160313630133110787799686301495 , 13766193863701503939885263345152684798552605679140222504700163745347162493183, 18523279471468319520962369406962457727155204375043681943707151819380964978377, 8094164074569624021939357073285075790695279643883973800173037824312344195506])
cx = sel3s([e[510], e[511], e[512]], [3342564788366736273905106071612128667477972061160313630133110787799686301495 , 13766193863701503939885263345152684798552605679140222504700163745347162493183, 18523279471468319520962369406962457727155204375043681943707151819380964978377, 8094164074569624021939357073285075790695279643883973800173037824312344195506])
cy = sel2([e[510], e[511]], [2329094643034533408459502544740928833981119919633412709248656884170940780093 , 3216329736050668550647765981020076413548845117352735257893224753954595290363, 18710403072495673647060422294369054840513840567808020912157404388689648711093, 9785201456176703812798077455183487364035650707229293534561747881523562553649])
a = add(a, [cx, cy], context)
bool[256] aC = edwardsCompress(a)
return [\
from_bits(aC[0..32]),
from_bits(aC[32..64]),
from_bits(aC[64..96]),
from_bits(aC[96..128]),
from_bits(aC[128..160]),
from_bits(aC[160..192]),
from_bits(aC[192..224]),
from_bits(aC[0..32]),
from_bits(aC[32..64]),
from_bits(aC[64..96]),
from_bits(aC[96..128]),
from_bits(aC[128..160]),
from_bits(aC[160..192]),
from_bits(aC[192..224]),
from_bits(aC[224..256])
]