commit
574435914d
72 changed files with 1576 additions and 9815 deletions
|
@ -106,7 +106,7 @@ jobs:
|
|||
- run:
|
||||
name: Build
|
||||
no_output_timeout: "30m"
|
||||
command: npm run build:dev && npm pack --dry-run
|
||||
command: npm ci && npm run build:dev && npm pack --dry-run
|
||||
- save-sccache-cache
|
||||
zokrates_js_test:
|
||||
docker:
|
||||
|
@ -127,7 +127,7 @@ jobs:
|
|||
- run:
|
||||
name: Run tests
|
||||
no_output_timeout: "30m"
|
||||
command: npm run test
|
||||
command: npm ci && npm run test
|
||||
- save-sccache-cache
|
||||
cross_build:
|
||||
parameters:
|
||||
|
@ -164,11 +164,6 @@ jobs:
|
|||
name: "Publish artifacts on GitHub"
|
||||
command: |
|
||||
go install github.com/github-release/github-release@latest
|
||||
github-release release \
|
||||
-s ${GH_TOKEN} \
|
||||
-u ${CIRCLE_PROJECT_USERNAME} \
|
||||
-r ${CIRCLE_PROJECT_REPONAME} \
|
||||
-t ${CIRCLE_TAG} || true
|
||||
find /tmp/artifacts -type f -name *.tar.gz -exec basename {} \; | xargs -I {} github-release upload \
|
||||
-s ${GH_TOKEN} \
|
||||
-u ${CIRCLE_PROJECT_USERNAME} \
|
||||
|
@ -214,8 +209,8 @@ commands:
|
|||
install_cross:
|
||||
steps:
|
||||
- run:
|
||||
name: Install rust-embedded/cross
|
||||
command: cargo install --git https://github.com/rust-embedded/cross
|
||||
name: Install cross
|
||||
command: cargo install cross --git https://github.com/cross-rs/cross
|
||||
tar_artifacts:
|
||||
parameters:
|
||||
target:
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
Language: Cpp
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
AllowShortFunctionsOnASingleLine: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
# make adding new members at the end less noisy in diffs
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|||
## [Unreleased]
|
||||
https://github.com/Zokrates/ZoKrates/compare/latest...develop
|
||||
|
||||
## [0.8.1] - 2022-08-22
|
||||
|
||||
### Release
|
||||
- https://github.com/Zokrates/ZoKrates/releases/tag/0.8.1 <!-- markdown-link-check-disable-line -->
|
||||
|
||||
### Changes
|
||||
- Error out at compile time if the type of a logged value could not be inferred (#1209, @dark64)
|
||||
- Add `backend` option in `zokrates-js`, bring back bellman, add a log writer to support printing logs in js (#1199, @dark64)
|
||||
- Fix padding bug in keccak implementation, add support for keccak-224 and sha3-224 (#1197, @dark64)
|
||||
- Update syntax highlighters (#1195, @schaeff)
|
||||
- Avoid validity checks on the deserialization of the proving key to improve proving time (#1192, @dark64)
|
||||
|
||||
## [0.8.0] - 2022-07-07
|
||||
|
||||
### Release
|
||||
|
|
27
Cargo.lock
generated
27
Cargo.lock
generated
|
@ -1480,6 +1480,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.2"
|
||||
|
@ -2993,7 +2999,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_ark"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"ark-bn254",
|
||||
|
@ -3020,7 +3026,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_ast"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"cfg-if 0.1.10",
|
||||
|
@ -3066,7 +3072,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_cli"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
dependencies = [
|
||||
"assert_cli",
|
||||
"blake2 0.8.1",
|
||||
|
@ -3111,7 +3117,7 @@ version = "0.1.1"
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_core"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"csv",
|
||||
|
@ -3193,7 +3199,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_interpreter"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"ark-bls12-377",
|
||||
"num 0.1.42",
|
||||
|
@ -3208,18 +3214,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_js"
|
||||
version = "1.1.0"
|
||||
version = "1.1.2"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"indexmap",
|
||||
"js-sys",
|
||||
"json",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
"typed-arena",
|
||||
"walkdir",
|
||||
"wasm-bindgen",
|
||||
"zokrates_abi",
|
||||
"zokrates_ark",
|
||||
"zokrates_ast",
|
||||
"zokrates_bellman",
|
||||
"zokrates_circom",
|
||||
"zokrates_common",
|
||||
"zokrates_core",
|
||||
|
@ -3230,7 +3241,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_parser"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"glob 0.2.11",
|
||||
"pest",
|
||||
|
@ -3281,7 +3292,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zokrates_stdlib"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
dependencies = [
|
||||
"fs_extra",
|
||||
"zokrates_test",
|
||||
|
|
|
@ -8,9 +8,7 @@ RUN cd src; ./build_release.sh
|
|||
FROM ubuntu:20.04
|
||||
ENV ZOKRATES_HOME=/home/zokrates/.zokrates
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends libgmp3-dev \
|
||||
&& useradd -u 1000 -m zokrates
|
||||
RUN useradd -u 1000 -m zokrates
|
||||
|
||||
USER zokrates
|
||||
WORKDIR /home/zokrates
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
FROM ubuntu:20.04
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
ARG RUST_VERSION=nightly
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
ENV RUSTUP_HOME=/usr/local/rustup \
|
||||
|
@ -25,12 +24,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain none -y \
|
||||
&& rustup toolchain install $RUST_VERSION --allow-downgrade --profile minimal --component rustfmt clippy \
|
||||
&& curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs && npm i -g solc \
|
||||
&& curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh \
|
||||
&& curl -sL https://raw.githubusercontent.com/Sarcasm/run-clang-format/master/run-clang-format.py > /opt/run-clang-format.py \
|
||||
&& chmod +x /opt/run-clang-format.py \
|
||||
&& ln -s /opt/run-clang-format.py /usr/bin \
|
||||
&& rustup --version; cargo --version; rustc --version; wasm-pack --version; echo nodejs $(node -v);
|
||||
|
||||
RUN cd /opt && curl -LO https://github.com/mozilla/geckodriver/releases/download/v0.28.0/geckodriver-v0.28.0-linux64.tar.gz \
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
cmake \
|
||||
libboost-dev \
|
||||
libboost-program-options-dev \
|
||||
libgmp3-dev \
|
||||
libprocps-dev \
|
||||
libssl-dev \
|
||||
pkg-config \
|
||||
python-markdown \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
|
@ -33,6 +33,14 @@ git tag -f $TAG
|
|||
git push origin -f latest
|
||||
git push origin $TAG
|
||||
|
||||
# Create a release draft
|
||||
curl \
|
||||
-X POST \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "Authorization: token $GH_TOKEN" \
|
||||
https://api.github.com/repos/Zokrates/ZoKrates/releases \
|
||||
-d "{\"tag_name\":\"$TAG\",\"draft\":true}"
|
||||
|
||||
# Build zokrates js
|
||||
docker build -t zokrates_js -f zokrates_js/Dockerfile .
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_ark"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -25,7 +25,7 @@ impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, GM17> for Ark {
|
|||
let (pk, vk) = ArkGM17::<T::ArkEngine>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
pk.serialize_uncompressed(&mut pk_vec).unwrap();
|
||||
pk.serialize_unchecked(&mut pk_vec).unwrap();
|
||||
|
||||
let vk = VerificationKey {
|
||||
h: parse_g2::<T>(&vk.h_g2),
|
||||
|
@ -54,7 +54,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, GM17> for Ark {
|
|||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pk = ProvingKey::<<T as ArkFieldExtensions>::ArkEngine>::deserialize_uncompressed(
|
||||
let pk = ProvingKey::<<T as ArkFieldExtensions>::ArkEngine>::deserialize_unchecked(
|
||||
&mut proving_key.as_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
|
|
|
@ -34,7 +34,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, G16> for Ark {
|
|||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let pk = ProvingKey::<<T as ArkFieldExtensions>::ArkEngine>::deserialize_uncompressed(
|
||||
let pk = ProvingKey::<<T as ArkFieldExtensions>::ArkEngine>::deserialize_unchecked(
|
||||
&mut proving_key.as_slice(),
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -97,7 +97,7 @@ impl<T: Field + ArkFieldExtensions> NonUniversalBackend<T, G16> for Ark {
|
|||
let (pk, vk) = Groth16::<T::ArkEngine>::circuit_specific_setup(computation, rng).unwrap();
|
||||
|
||||
let mut pk_vec: Vec<u8> = Vec::new();
|
||||
pk.serialize_uncompressed(&mut pk_vec).unwrap();
|
||||
pk.serialize_unchecked(&mut pk_vec).unwrap();
|
||||
|
||||
let vk = VerificationKey {
|
||||
alpha: parse_g1::<T>(&vk.alpha_g1),
|
||||
|
|
|
@ -164,7 +164,7 @@ impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark
|
|||
})?;
|
||||
|
||||
let mut serialized_pk: Vec<u8> = Vec::new();
|
||||
pk.serialize_uncompressed(&mut serialized_pk).unwrap();
|
||||
pk.serialize_unchecked(&mut serialized_pk).unwrap();
|
||||
|
||||
// Precompute some useful values for solidity contract
|
||||
let fs_seed = to_bytes![&MarlinInst::<T>::PROTOCOL_NAME, &vk].unwrap();
|
||||
|
@ -225,7 +225,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
T::ArkEngine,
|
||||
DensePolynomial<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
|
||||
>,
|
||||
>::deserialize_uncompressed(&mut proving_key.as_slice())
|
||||
>::deserialize_unchecked(&mut proving_key.as_slice())
|
||||
.unwrap();
|
||||
|
||||
let public_inputs = computation.public_inputs_values();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_ast"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
|
|
|
@ -4,6 +4,27 @@ use crate::zir::types::UBitwidth;
|
|||
use crate::zir::*;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait Fold<'ast, T: Field>: Sized {
|
||||
fn fold<F: Folder<'ast, T>>(self, f: &mut F) -> Self;
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Fold<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
fn fold<F: Folder<'ast, T>>(self, f: &mut F) -> Self {
|
||||
f.fold_field_expression(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Fold<'ast, T> for BooleanExpression<'ast, T> {
|
||||
fn fold<F: Folder<'ast, T>>(self, f: &mut F) -> Self {
|
||||
f.fold_boolean_expression(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Fold<'ast, T> for UExpression<'ast, T> {
|
||||
fn fold<F: Folder<'ast, T>>(self, f: &mut F) -> Self {
|
||||
f.fold_uint_expression(self)
|
||||
}
|
||||
}
|
||||
pub trait Folder<'ast, T: Field>: Sized {
|
||||
fn fold_program(&mut self, p: ZirProgram<'ast, T>) -> ZirProgram<'ast, T> {
|
||||
fold_program(self, p)
|
||||
|
@ -39,6 +60,22 @@ pub trait Folder<'ast, T: Field>: Sized {
|
|||
fold_statement(self, s)
|
||||
}
|
||||
|
||||
fn fold_conditional_expression<E: Expr<'ast, T> + Fold<'ast, T> + Conditional<'ast, T>>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> ConditionalOrExpression<'ast, T, E> {
|
||||
fold_conditional_expression(self, ty, e)
|
||||
}
|
||||
|
||||
fn fold_select_expression<E: Expr<'ast, T> + Fold<'ast, T> + Select<'ast, T>>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> SelectOrExpression<'ast, T, E> {
|
||||
fold_select_expression(self, ty, e)
|
||||
}
|
||||
|
||||
fn fold_expression(&mut self, e: ZirExpression<'ast, T>) -> ZirExpression<'ast, T> {
|
||||
match e {
|
||||
ZirExpression::FieldElement(e) => self.fold_field_expression(e).into(),
|
||||
|
@ -141,10 +178,12 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
FieldElementExpression::Identifier(id) => {
|
||||
FieldElementExpression::Identifier(f.fold_name(id))
|
||||
}
|
||||
FieldElementExpression::Select(a, box i) => FieldElementExpression::Select(
|
||||
a.into_iter().map(|a| f.fold_field_expression(a)).collect(),
|
||||
box f.fold_uint_expression(i),
|
||||
),
|
||||
FieldElementExpression::Select(e) => {
|
||||
match f.fold_select_expression(&Type::FieldElement, e) {
|
||||
SelectOrExpression::Select(s) => FieldElementExpression::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Add(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
|
@ -170,11 +209,11 @@ pub fn fold_field_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let e2 = f.fold_uint_expression(e2);
|
||||
FieldElementExpression::Pow(box e1, box e2)
|
||||
}
|
||||
FieldElementExpression::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond);
|
||||
let cons = f.fold_field_expression(cons);
|
||||
let alt = f.fold_field_expression(alt);
|
||||
FieldElementExpression::Conditional(box cond, box cons, box alt)
|
||||
FieldElementExpression::Conditional(c) => {
|
||||
match f.fold_conditional_expression(&Type::FieldElement, c) {
|
||||
ConditionalOrExpression::Conditional(s) => FieldElementExpression::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,12 +225,10 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
match e {
|
||||
BooleanExpression::Value(v) => BooleanExpression::Value(v),
|
||||
BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)),
|
||||
BooleanExpression::Select(a, box i) => BooleanExpression::Select(
|
||||
a.into_iter()
|
||||
.map(|a| f.fold_boolean_expression(a))
|
||||
.collect(),
|
||||
box f.fold_uint_expression(i),
|
||||
),
|
||||
BooleanExpression::Select(e) => match f.fold_select_expression(&Type::Boolean, e) {
|
||||
SelectOrExpression::Select(s) => BooleanExpression::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
},
|
||||
BooleanExpression::FieldEq(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
|
@ -212,41 +249,21 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let e2 = f.fold_field_expression(e2);
|
||||
BooleanExpression::FieldLt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldLe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
BooleanExpression::FieldLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldGt(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
BooleanExpression::FieldGt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldGe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
BooleanExpression::FieldGe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintLt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1);
|
||||
let e2 = f.fold_uint_expression(e2);
|
||||
BooleanExpression::UintLt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldLe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1);
|
||||
let e2 = f.fold_field_expression(e2);
|
||||
BooleanExpression::FieldLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintLe(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1);
|
||||
let e2 = f.fold_uint_expression(e2);
|
||||
BooleanExpression::UintLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintGt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1);
|
||||
let e2 = f.fold_uint_expression(e2);
|
||||
BooleanExpression::UintGt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintGe(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1);
|
||||
let e2 = f.fold_uint_expression(e2);
|
||||
BooleanExpression::UintGe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::Or(box e1, box e2) => {
|
||||
let e1 = f.fold_boolean_expression(e1);
|
||||
let e2 = f.fold_boolean_expression(e2);
|
||||
|
@ -261,12 +278,11 @@ pub fn fold_boolean_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
let e = f.fold_boolean_expression(e);
|
||||
BooleanExpression::Not(box e)
|
||||
}
|
||||
BooleanExpression::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond);
|
||||
let cons = f.fold_boolean_expression(cons);
|
||||
let alt = f.fold_boolean_expression(alt);
|
||||
BooleanExpression::Conditional(box cond, box cons, box alt)
|
||||
}
|
||||
BooleanExpression::Conditional(c) => match f.fold_conditional_expression(&Type::Boolean, c)
|
||||
{
|
||||
ConditionalOrExpression::Conditional(s) => BooleanExpression::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -282,16 +298,16 @@ pub fn fold_uint_expression<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
|
||||
pub fn fold_uint_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
||||
f: &mut F,
|
||||
_: UBitwidth,
|
||||
ty: UBitwidth,
|
||||
e: UExpressionInner<'ast, T>,
|
||||
) -> UExpressionInner<'ast, T> {
|
||||
match e {
|
||||
UExpressionInner::Value(v) => UExpressionInner::Value(v),
|
||||
UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)),
|
||||
UExpressionInner::Select(a, box i) => UExpressionInner::Select(
|
||||
a.into_iter().map(|a| f.fold_uint_expression(a)).collect(),
|
||||
box f.fold_uint_expression(i),
|
||||
),
|
||||
UExpressionInner::Select(e) => match f.fold_select_expression(&ty, e) {
|
||||
SelectOrExpression::Select(s) => UExpressionInner::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
},
|
||||
UExpressionInner::Add(box left, box right) => {
|
||||
let left = f.fold_uint_expression(left);
|
||||
let right = f.fold_uint_expression(right);
|
||||
|
@ -355,12 +371,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
|
||||
UExpressionInner::Not(box e)
|
||||
}
|
||||
UExpressionInner::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond);
|
||||
let cons = f.fold_uint_expression(cons);
|
||||
let alt = f.fold_uint_expression(alt);
|
||||
UExpressionInner::Conditional(box cond, box cons, box alt)
|
||||
}
|
||||
UExpressionInner::Conditional(c) => match f.fold_conditional_expression(&ty, c) {
|
||||
ConditionalOrExpression::Conditional(s) => UExpressionInner::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,3 +405,36 @@ pub fn fold_program<'ast, T: Field, F: Folder<'ast, T>>(
|
|||
main: f.fold_function(p.main),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fold_conditional_expression<
|
||||
'ast,
|
||||
T: Field,
|
||||
E: Expr<'ast, T> + Fold<'ast, T> + Conditional<'ast, T>,
|
||||
F: Folder<'ast, T>,
|
||||
>(
|
||||
f: &mut F,
|
||||
_: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> ConditionalOrExpression<'ast, T, E> {
|
||||
ConditionalOrExpression::Conditional(ConditionalExpression::new(
|
||||
f.fold_boolean_expression(*e.condition),
|
||||
e.consequence.fold(f),
|
||||
e.alternative.fold(f),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn fold_select_expression<
|
||||
'ast,
|
||||
T: Field,
|
||||
E: Expr<'ast, T> + Fold<'ast, T> + Select<'ast, T>,
|
||||
F: Folder<'ast, T>,
|
||||
>(
|
||||
f: &mut F,
|
||||
_: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> SelectOrExpression<'ast, T, E> {
|
||||
SelectOrExpression::Select(SelectExpression::new(
|
||||
e.array.into_iter().map(|e| e.fold(f)).collect(),
|
||||
e.index.fold(f),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ mod uint;
|
|||
mod variable;
|
||||
|
||||
pub use self::parameter::Parameter;
|
||||
pub use self::types::Type;
|
||||
pub use self::types::{Type, UBitwidth};
|
||||
pub use self::variable::Variable;
|
||||
use crate::common::{FlatEmbed, FormatString};
|
||||
use crate::typed::ConcreteType;
|
||||
|
@ -23,7 +23,7 @@ pub use self::folder::Folder;
|
|||
pub use self::identifier::{Identifier, SourceIdentifier};
|
||||
|
||||
/// A typed program as a collection of modules, one of them being the main
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
||||
pub struct ZirProgram<'ast, T> {
|
||||
pub main: ZirFunction<'ast, T>,
|
||||
}
|
||||
|
@ -138,14 +138,15 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> {
|
|||
write!(f, "{}", "\t".repeat(depth))?;
|
||||
match self {
|
||||
ZirStatement::Return(ref exprs) => {
|
||||
write!(f, "return ")?;
|
||||
for (i, expr) in exprs.iter().enumerate() {
|
||||
write!(f, "{}", expr)?;
|
||||
if i < exprs.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ";")
|
||||
write!(
|
||||
f,
|
||||
"return {};",
|
||||
exprs
|
||||
.iter()
|
||||
.map(|e| e.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
ZirStatement::Definition(ref lhs, ref rhs) => {
|
||||
write!(f, "{} = {};", lhs, rhs)
|
||||
|
@ -181,7 +182,7 @@ impl<'ast, T: fmt::Display> ZirStatement<'ast, T> {
|
|||
}
|
||||
ZirStatement::Log(ref l, ref expressions) => write!(
|
||||
f,
|
||||
"log(\"{}\"), {})",
|
||||
"log(\"{}\"), {});",
|
||||
l,
|
||||
expressions
|
||||
.iter()
|
||||
|
@ -203,6 +204,63 @@ pub trait Typed {
|
|||
fn get_type(&self) -> Type;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq)]
|
||||
pub struct ConditionalExpression<'ast, T, E> {
|
||||
pub condition: Box<BooleanExpression<'ast, T>>,
|
||||
pub consequence: Box<E>,
|
||||
pub alternative: Box<E>,
|
||||
}
|
||||
|
||||
impl<'ast, T, E> ConditionalExpression<'ast, T, E> {
|
||||
pub fn new(condition: BooleanExpression<'ast, T>, consequence: E, alternative: E) -> Self {
|
||||
ConditionalExpression {
|
||||
condition: box condition,
|
||||
consequence: box consequence,
|
||||
alternative: box alternative,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display, E: fmt::Display> fmt::Display for ConditionalExpression<'ast, T, E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{} ? {} : {}",
|
||||
self.condition, self.consequence, self.alternative
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, Eq)]
|
||||
pub struct SelectExpression<'ast, T, E> {
|
||||
pub array: Vec<E>,
|
||||
pub index: Box<UExpression<'ast, T>>,
|
||||
}
|
||||
|
||||
impl<'ast, T, E> SelectExpression<'ast, T, E> {
|
||||
pub fn new(array: Vec<E>, index: UExpression<'ast, T>) -> Self {
|
||||
SelectExpression {
|
||||
array,
|
||||
index: box index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: fmt::Display, E: fmt::Display> fmt::Display for SelectExpression<'ast, T, E> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}[{}]",
|
||||
self.array
|
||||
.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
self.index
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// A typed expression
|
||||
#[derive(Clone, PartialEq, Hash, Eq)]
|
||||
pub enum ZirExpression<'ast, T> {
|
||||
|
@ -291,7 +349,7 @@ pub enum ZirExpressionList<'ast, T> {
|
|||
pub enum FieldElementExpression<'ast, T> {
|
||||
Number(T),
|
||||
Identifier(Identifier<'ast>),
|
||||
Select(Vec<Self>, Box<UExpression<'ast, T>>),
|
||||
Select(SelectExpression<'ast, T, Self>),
|
||||
Add(
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
|
@ -312,11 +370,7 @@ pub enum FieldElementExpression<'ast, T> {
|
|||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<UExpression<'ast, T>>,
|
||||
),
|
||||
Conditional(
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
Conditional(ConditionalExpression<'ast, T, FieldElementExpression<'ast, T>>),
|
||||
}
|
||||
|
||||
/// An expression of type `bool`
|
||||
|
@ -324,7 +378,7 @@ pub enum FieldElementExpression<'ast, T> {
|
|||
pub enum BooleanExpression<'ast, T> {
|
||||
Value(bool),
|
||||
Identifier(Identifier<'ast>),
|
||||
Select(Vec<Self>, Box<UExpression<'ast, T>>),
|
||||
Select(SelectExpression<'ast, T, Self>),
|
||||
FieldLt(
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
|
@ -333,22 +387,12 @@ pub enum BooleanExpression<'ast, T> {
|
|||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
FieldGe(
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
FieldGt(
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
FieldEq(
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
Box<FieldElementExpression<'ast, T>>,
|
||||
),
|
||||
UintLt(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
UintLe(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
UintGe(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
UintGt(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
UintEq(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
BoolEq(
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
|
@ -363,11 +407,7 @@ pub enum BooleanExpression<'ast, T> {
|
|||
Box<BooleanExpression<'ast, T>>,
|
||||
),
|
||||
Not(Box<BooleanExpression<'ast, T>>),
|
||||
Conditional(
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
),
|
||||
Conditional(ConditionalExpression<'ast, T, BooleanExpression<'ast, T>>),
|
||||
}
|
||||
|
||||
pub struct ConjunctionIterator<T> {
|
||||
|
@ -438,26 +478,14 @@ impl<'ast, T: fmt::Display> fmt::Display for FieldElementExpression<'ast, T> {
|
|||
match *self {
|
||||
FieldElementExpression::Number(ref i) => write!(f, "{}", i),
|
||||
FieldElementExpression::Identifier(ref var) => write!(f, "{}", var),
|
||||
FieldElementExpression::Select(ref a, ref i) => write!(
|
||||
f,
|
||||
"[{}][{}]",
|
||||
a.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
i
|
||||
),
|
||||
FieldElementExpression::Select(ref e) => write!(f, "{}", e),
|
||||
FieldElementExpression::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
|
||||
FieldElementExpression::Sub(ref lhs, ref rhs) => write!(f, "({} - {})", lhs, rhs),
|
||||
FieldElementExpression::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
|
||||
FieldElementExpression::Div(ref lhs, ref rhs) => write!(f, "({} / {})", lhs, rhs),
|
||||
FieldElementExpression::Pow(ref lhs, ref rhs) => write!(f, "{}**{}", lhs, rhs),
|
||||
FieldElementExpression::Conditional(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} {{ {} }} else {{ {} }}",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
FieldElementExpression::Conditional(ref c) => {
|
||||
write!(f, "{}", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,15 +496,7 @@ impl<'ast, T: fmt::Display> fmt::Display for UExpression<'ast, T> {
|
|||
match self.inner {
|
||||
UExpressionInner::Value(ref v) => write!(f, "{}", v),
|
||||
UExpressionInner::Identifier(ref var) => write!(f, "{}", var),
|
||||
UExpressionInner::Select(ref a, ref i) => write!(
|
||||
f,
|
||||
"[{}][{}]",
|
||||
a.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
i
|
||||
),
|
||||
UExpressionInner::Select(ref e) => write!(f, "{}", e),
|
||||
UExpressionInner::Add(ref lhs, ref rhs) => write!(f, "({} + {})", lhs, rhs),
|
||||
UExpressionInner::Sub(ref lhs, ref rhs) => write!(f, "({} - {})", lhs, rhs),
|
||||
UExpressionInner::Mult(ref lhs, ref rhs) => write!(f, "({} * {})", lhs, rhs),
|
||||
|
@ -488,12 +508,8 @@ impl<'ast, T: fmt::Display> fmt::Display for UExpression<'ast, T> {
|
|||
UExpressionInner::LeftShift(ref e, ref by) => write!(f, "({} << {})", e, by),
|
||||
UExpressionInner::RightShift(ref e, ref by) => write!(f, "({} >> {})", e, by),
|
||||
UExpressionInner::Not(ref e) => write!(f, "!{}", e),
|
||||
UExpressionInner::Conditional(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} {{ {} }} else {{ {} }}",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
UExpressionInner::Conditional(ref c) => {
|
||||
write!(f, "{}", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,35 +520,19 @@ impl<'ast, T: fmt::Display> fmt::Display for BooleanExpression<'ast, T> {
|
|||
match *self {
|
||||
BooleanExpression::Identifier(ref var) => write!(f, "{}", var),
|
||||
BooleanExpression::Value(b) => write!(f, "{}", b),
|
||||
BooleanExpression::Select(ref a, ref i) => write!(
|
||||
f,
|
||||
"[{}][{}]",
|
||||
a.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
i
|
||||
),
|
||||
BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
||||
BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
BooleanExpression::FieldGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
BooleanExpression::FieldGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
||||
BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "{} < {}", lhs, rhs),
|
||||
BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "{} <= {}", lhs, rhs),
|
||||
BooleanExpression::UintGe(ref lhs, ref rhs) => write!(f, "{} >= {}", lhs, rhs),
|
||||
BooleanExpression::UintGt(ref lhs, ref rhs) => write!(f, "{} > {}", lhs, rhs),
|
||||
BooleanExpression::FieldEq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
BooleanExpression::BoolEq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
BooleanExpression::UintEq(ref lhs, ref rhs) => write!(f, "{} == {}", lhs, rhs),
|
||||
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "{} || {}", lhs, rhs),
|
||||
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "{} && {}", lhs, rhs),
|
||||
BooleanExpression::Select(ref e) => write!(f, "{}", e),
|
||||
BooleanExpression::FieldLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
|
||||
BooleanExpression::UintLt(ref lhs, ref rhs) => write!(f, "({} < {})", lhs, rhs),
|
||||
BooleanExpression::FieldLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
|
||||
BooleanExpression::UintLe(ref lhs, ref rhs) => write!(f, "({} <= {})", lhs, rhs),
|
||||
BooleanExpression::FieldEq(ref lhs, ref rhs) => write!(f, "({} == {})", lhs, rhs),
|
||||
BooleanExpression::BoolEq(ref lhs, ref rhs) => write!(f, "({} == {})", lhs, rhs),
|
||||
BooleanExpression::UintEq(ref lhs, ref rhs) => write!(f, "({} == {})", lhs, rhs),
|
||||
BooleanExpression::Or(ref lhs, ref rhs) => write!(f, "({} || {})", lhs, rhs),
|
||||
BooleanExpression::And(ref lhs, ref rhs) => write!(f, "({} && {})", lhs, rhs),
|
||||
BooleanExpression::Not(ref exp) => write!(f, "!{}", exp),
|
||||
BooleanExpression::Conditional(ref condition, ref consequent, ref alternative) => {
|
||||
write!(
|
||||
f,
|
||||
"if {} {{ {} }} else {{ {} }}",
|
||||
condition, consequent, alternative
|
||||
)
|
||||
BooleanExpression::Conditional(ref c) => {
|
||||
write!(f, "{}", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -584,7 +584,81 @@ impl<'ast, T: fmt::Debug> fmt::Debug for ZirExpressionList<'ast, T> {
|
|||
}
|
||||
|
||||
// Common behaviour accross expressions
|
||||
pub trait Expr<'ast, T>: fmt::Display + PartialEq {
|
||||
type Inner;
|
||||
type Ty: Clone + IntoType;
|
||||
|
||||
fn ty(&self) -> &Self::Ty;
|
||||
|
||||
fn into_inner(self) -> Self::Inner;
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner;
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner;
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Expr<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
type Inner = Self;
|
||||
type Ty = Type;
|
||||
|
||||
fn ty(&self) -> &Self::Ty {
|
||||
&Type::FieldElement
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Self::Inner {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Expr<'ast, T> for BooleanExpression<'ast, T> {
|
||||
type Inner = Self;
|
||||
type Ty = Type;
|
||||
|
||||
fn ty(&self) -> &Self::Ty {
|
||||
&Type::Boolean
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Self::Inner {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> Expr<'ast, T> for UExpression<'ast, T> {
|
||||
type Inner = UExpressionInner<'ast, T>;
|
||||
type Ty = UBitwidth;
|
||||
|
||||
fn ty(&self) -> &Self::Ty {
|
||||
&self.bitwidth
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Self::Inner {
|
||||
self.inner
|
||||
}
|
||||
|
||||
fn as_inner(&self) -> &Self::Inner {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
fn as_inner_mut(&mut self) -> &mut Self::Inner {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
pub trait Conditional<'ast, T> {
|
||||
fn conditional(
|
||||
condition: BooleanExpression<'ast, T>,
|
||||
|
@ -593,13 +667,22 @@ pub trait Conditional<'ast, T> {
|
|||
) -> Self;
|
||||
}
|
||||
|
||||
pub enum ConditionalOrExpression<'ast, T, E: Expr<'ast, T>> {
|
||||
Conditional(ConditionalExpression<'ast, T, E>),
|
||||
Expression(E::Inner),
|
||||
}
|
||||
|
||||
impl<'ast, T> Conditional<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
fn conditional(
|
||||
condition: BooleanExpression<'ast, T>,
|
||||
consequence: Self,
|
||||
alternative: Self,
|
||||
) -> Self {
|
||||
FieldElementExpression::Conditional(box condition, box consequence, box alternative)
|
||||
FieldElementExpression::Conditional(ConditionalExpression::new(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,7 +692,11 @@ impl<'ast, T> Conditional<'ast, T> for BooleanExpression<'ast, T> {
|
|||
consequence: Self,
|
||||
alternative: Self,
|
||||
) -> Self {
|
||||
BooleanExpression::Conditional(box condition, box consequence, box alternative)
|
||||
BooleanExpression::Conditional(ConditionalExpression::new(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,7 +708,56 @@ impl<'ast, T> Conditional<'ast, T> for UExpression<'ast, T> {
|
|||
) -> Self {
|
||||
let bitwidth = consequence.bitwidth;
|
||||
|
||||
UExpressionInner::Conditional(box condition, box consequence, box alternative)
|
||||
.annotate(bitwidth)
|
||||
UExpressionInner::Conditional(ConditionalExpression::new(
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
))
|
||||
.annotate(bitwidth)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Select<'ast, T>: Sized {
|
||||
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self;
|
||||
}
|
||||
|
||||
pub enum SelectOrExpression<'ast, T, E: Expr<'ast, T>> {
|
||||
Select(SelectExpression<'ast, T, E>),
|
||||
Expression(E::Inner),
|
||||
}
|
||||
|
||||
impl<'ast, T> Select<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self {
|
||||
FieldElementExpression::Select(SelectExpression::new(array, index))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> Select<'ast, T> for BooleanExpression<'ast, T> {
|
||||
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self {
|
||||
BooleanExpression::Select(SelectExpression::new(array, index))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T> Select<'ast, T> for UExpression<'ast, T> {
|
||||
fn select(array: Vec<Self>, index: UExpression<'ast, T>) -> Self {
|
||||
let bitwidth = array[0].bitwidth;
|
||||
|
||||
UExpressionInner::Select(SelectExpression::new(array, index)).annotate(bitwidth)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoType {
|
||||
fn into_type(self) -> Type;
|
||||
}
|
||||
|
||||
impl IntoType for Type {
|
||||
fn into_type(self) -> Type {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoType for UBitwidth {
|
||||
fn into_type(self) -> Type {
|
||||
Type::Uint(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,27 @@ use crate::zir::types::UBitwidth;
|
|||
use crate::zir::*;
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub trait ResultFold<'ast, T: Field>: Sized {
|
||||
fn fold<F: ResultFolder<'ast, T>>(self, f: &mut F) -> Result<Self, F::Error>;
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> ResultFold<'ast, T> for FieldElementExpression<'ast, T> {
|
||||
fn fold<F: ResultFolder<'ast, T>>(self, f: &mut F) -> Result<Self, F::Error> {
|
||||
f.fold_field_expression(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> ResultFold<'ast, T> for BooleanExpression<'ast, T> {
|
||||
fn fold<F: ResultFolder<'ast, T>>(self, f: &mut F) -> Result<Self, F::Error> {
|
||||
f.fold_boolean_expression(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ast, T: Field> ResultFold<'ast, T> for UExpression<'ast, T> {
|
||||
fn fold<F: ResultFolder<'ast, T>>(self, f: &mut F) -> Result<Self, F::Error> {
|
||||
f.fold_uint_expression(self)
|
||||
}
|
||||
}
|
||||
pub trait ResultFolder<'ast, T: Field>: Sized {
|
||||
type Error;
|
||||
|
||||
|
@ -76,6 +97,24 @@ pub trait ResultFolder<'ast, T: Field>: Sized {
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_conditional_expression<
|
||||
E: Expr<'ast, T> + ResultFold<'ast, T> + Conditional<'ast, T>,
|
||||
>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> Result<ConditionalOrExpression<'ast, T, E>, Self::Error> {
|
||||
fold_conditional_expression(self, ty, e)
|
||||
}
|
||||
|
||||
fn fold_select_expression<E: Clone + Expr<'ast, T> + ResultFold<'ast, T> + Select<'ast, T>>(
|
||||
&mut self,
|
||||
ty: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> Result<SelectOrExpression<'ast, T, E>, Self::Error> {
|
||||
fold_select_expression(self, ty, e)
|
||||
}
|
||||
|
||||
fn fold_field_expression(
|
||||
&mut self,
|
||||
e: FieldElementExpression<'ast, T>,
|
||||
|
@ -173,12 +212,12 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
FieldElementExpression::Identifier(id) => {
|
||||
FieldElementExpression::Identifier(f.fold_name(id)?)
|
||||
}
|
||||
FieldElementExpression::Select(a, box i) => FieldElementExpression::Select(
|
||||
a.into_iter()
|
||||
.map(|a| f.fold_field_expression(a))
|
||||
.collect::<Result<_, _>>()?,
|
||||
box f.fold_uint_expression(i)?,
|
||||
),
|
||||
FieldElementExpression::Select(e) => {
|
||||
match f.fold_select_expression(&Type::FieldElement, e)? {
|
||||
SelectOrExpression::Select(s) => FieldElementExpression::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Add(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
|
@ -204,11 +243,11 @@ pub fn fold_field_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
let e2 = f.fold_uint_expression(e2)?;
|
||||
FieldElementExpression::Pow(box e1, box e2)
|
||||
}
|
||||
FieldElementExpression::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond)?;
|
||||
let cons = f.fold_field_expression(cons)?;
|
||||
let alt = f.fold_field_expression(alt)?;
|
||||
FieldElementExpression::Conditional(box cond, box cons, box alt)
|
||||
FieldElementExpression::Conditional(c) => {
|
||||
match f.fold_conditional_expression(&Type::FieldElement, c)? {
|
||||
ConditionalOrExpression::Conditional(s) => FieldElementExpression::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -220,12 +259,10 @@ pub fn fold_boolean_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
Ok(match e {
|
||||
BooleanExpression::Value(v) => BooleanExpression::Value(v),
|
||||
BooleanExpression::Identifier(id) => BooleanExpression::Identifier(f.fold_name(id)?),
|
||||
BooleanExpression::Select(a, box i) => BooleanExpression::Select(
|
||||
a.into_iter()
|
||||
.map(|a| f.fold_boolean_expression(a))
|
||||
.collect::<Result<_, _>>()?,
|
||||
box f.fold_uint_expression(i)?,
|
||||
),
|
||||
BooleanExpression::Select(e) => match f.fold_select_expression(&Type::Boolean, e)? {
|
||||
SelectOrExpression::Select(s) => BooleanExpression::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
},
|
||||
BooleanExpression::FieldEq(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
|
@ -246,41 +283,21 @@ pub fn fold_boolean_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
let e2 = f.fold_field_expression(e2)?;
|
||||
BooleanExpression::FieldLt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldLe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
BooleanExpression::FieldLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldGt(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
BooleanExpression::FieldGt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldGe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
BooleanExpression::FieldGe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintLt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1)?;
|
||||
let e2 = f.fold_uint_expression(e2)?;
|
||||
BooleanExpression::UintLt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::FieldLe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(e1)?;
|
||||
let e2 = f.fold_field_expression(e2)?;
|
||||
BooleanExpression::FieldLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintLe(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1)?;
|
||||
let e2 = f.fold_uint_expression(e2)?;
|
||||
BooleanExpression::UintLe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintGt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1)?;
|
||||
let e2 = f.fold_uint_expression(e2)?;
|
||||
BooleanExpression::UintGt(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::UintGe(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(e1)?;
|
||||
let e2 = f.fold_uint_expression(e2)?;
|
||||
BooleanExpression::UintGe(box e1, box e2)
|
||||
}
|
||||
BooleanExpression::Or(box e1, box e2) => {
|
||||
let e1 = f.fold_boolean_expression(e1)?;
|
||||
let e2 = f.fold_boolean_expression(e2)?;
|
||||
|
@ -295,11 +312,11 @@ pub fn fold_boolean_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
let e = f.fold_boolean_expression(e)?;
|
||||
BooleanExpression::Not(box e)
|
||||
}
|
||||
BooleanExpression::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond)?;
|
||||
let cons = f.fold_boolean_expression(cons)?;
|
||||
let alt = f.fold_boolean_expression(alt)?;
|
||||
BooleanExpression::Conditional(box cond, box cons, box alt)
|
||||
BooleanExpression::Conditional(c) => {
|
||||
match f.fold_conditional_expression(&Type::Boolean, c)? {
|
||||
ConditionalOrExpression::Conditional(s) => BooleanExpression::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -316,18 +333,16 @@ pub fn fold_uint_expression<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
|
||||
pub fn fold_uint_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
||||
f: &mut F,
|
||||
_: UBitwidth,
|
||||
ty: UBitwidth,
|
||||
e: UExpressionInner<'ast, T>,
|
||||
) -> Result<UExpressionInner<'ast, T>, F::Error> {
|
||||
Ok(match e {
|
||||
UExpressionInner::Value(v) => UExpressionInner::Value(v),
|
||||
UExpressionInner::Identifier(id) => UExpressionInner::Identifier(f.fold_name(id)?),
|
||||
UExpressionInner::Select(a, box i) => UExpressionInner::Select(
|
||||
a.into_iter()
|
||||
.map(|a| f.fold_uint_expression(a))
|
||||
.collect::<Result<_, _>>()?,
|
||||
box f.fold_uint_expression(i)?,
|
||||
),
|
||||
UExpressionInner::Select(e) => match f.fold_select_expression(&ty, e)? {
|
||||
SelectOrExpression::Select(s) => UExpressionInner::Select(s),
|
||||
SelectOrExpression::Expression(u) => u,
|
||||
},
|
||||
UExpressionInner::Add(box left, box right) => {
|
||||
let left = f.fold_uint_expression(left)?;
|
||||
let right = f.fold_uint_expression(right)?;
|
||||
|
@ -391,13 +406,10 @@ pub fn fold_uint_expression_inner<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
|
||||
UExpressionInner::Not(box e)
|
||||
}
|
||||
UExpressionInner::Conditional(box cond, box cons, box alt) => {
|
||||
let cond = f.fold_boolean_expression(cond)?;
|
||||
let cons = f.fold_uint_expression(cons)?;
|
||||
let alt = f.fold_uint_expression(alt)?;
|
||||
|
||||
UExpressionInner::Conditional(box cond, box cons, box alt)
|
||||
}
|
||||
UExpressionInner::Conditional(c) => match f.fold_conditional_expression(&ty, c)? {
|
||||
ConditionalOrExpression::Conditional(s) => UExpressionInner::Conditional(s),
|
||||
ConditionalOrExpression::Expression(u) => u,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -431,3 +443,41 @@ pub fn fold_program<'ast, T: Field, F: ResultFolder<'ast, T>>(
|
|||
main: f.fold_function(p.main)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fold_conditional_expression<
|
||||
'ast,
|
||||
T: Field,
|
||||
E: Expr<'ast, T> + ResultFold<'ast, T> + Conditional<'ast, T>,
|
||||
F: ResultFolder<'ast, T>,
|
||||
>(
|
||||
f: &mut F,
|
||||
_: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> Result<ConditionalOrExpression<'ast, T, E>, F::Error> {
|
||||
Ok(ConditionalOrExpression::Conditional(
|
||||
ConditionalExpression::new(
|
||||
f.fold_boolean_expression(*e.condition)?,
|
||||
e.consequence.fold(f)?,
|
||||
e.alternative.fold(f)?,
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn fold_select_expression<
|
||||
'ast,
|
||||
T: Field,
|
||||
E: Expr<'ast, T> + ResultFold<'ast, T> + Select<'ast, T>,
|
||||
F: ResultFolder<'ast, T>,
|
||||
>(
|
||||
f: &mut F,
|
||||
_: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> Result<SelectOrExpression<'ast, T, E>, F::Error> {
|
||||
Ok(SelectOrExpression::Select(SelectExpression::new(
|
||||
e.array
|
||||
.into_iter()
|
||||
.map(|e| e.fold(f))
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
e.index.fold(f)?,
|
||||
)))
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::zir::identifier::Identifier;
|
||||
use crate::zir::types::UBitwidth;
|
||||
use crate::zir::BooleanExpression;
|
||||
use zokrates_field::Field;
|
||||
|
||||
use super::{ConditionalExpression, SelectExpression};
|
||||
|
||||
impl<'ast, T: Field> UExpression<'ast, T> {
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn add(self, other: Self) -> UExpression<'ast, T> {
|
||||
|
@ -20,7 +21,7 @@ impl<'ast, T: Field> UExpression<'ast, T> {
|
|||
|
||||
pub fn select(values: Vec<Self>, index: Self) -> UExpression<'ast, T> {
|
||||
let bitwidth = values[0].bitwidth;
|
||||
UExpressionInner::Select(values, box index).annotate(bitwidth)
|
||||
UExpressionInner::Select(SelectExpression::new(values, index)).annotate(bitwidth)
|
||||
}
|
||||
|
||||
pub fn mult(self, other: Self) -> UExpression<'ast, T> {
|
||||
|
@ -178,7 +179,7 @@ pub struct UExpression<'ast, T> {
|
|||
pub enum UExpressionInner<'ast, T> {
|
||||
Value(u128),
|
||||
Identifier(Identifier<'ast>),
|
||||
Select(Vec<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
Select(SelectExpression<'ast, T, UExpression<'ast, T>>),
|
||||
Add(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
Sub(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
Mult(Box<UExpression<'ast, T>>, Box<UExpression<'ast, T>>),
|
||||
|
@ -190,11 +191,7 @@ pub enum UExpressionInner<'ast, T> {
|
|||
LeftShift(Box<UExpression<'ast, T>>, u32),
|
||||
RightShift(Box<UExpression<'ast, T>>, u32),
|
||||
Not(Box<UExpression<'ast, T>>),
|
||||
Conditional(
|
||||
Box<BooleanExpression<'ast, T>>,
|
||||
Box<UExpression<'ast, T>>,
|
||||
Box<UExpression<'ast, T>>,
|
||||
),
|
||||
Conditional(ConditionalExpression<'ast, T, UExpression<'ast, T>>),
|
||||
}
|
||||
|
||||
impl<'ast, T> UExpressionInner<'ast, T> {
|
||||
|
|
|
@ -64,14 +64,19 @@ Returns a `ZoKratesProvider` configured with given options.
|
|||
|
||||
```js
|
||||
initialize().then((defaultProvider) => {
|
||||
let zokratesProvider = defaultProvider.withOptions({ curve: "bls12_381", scheme: "g16" });
|
||||
let zokratesProvider = defaultProvider.withOptions({
|
||||
backend: "ark",
|
||||
curve: "bls12_381",
|
||||
scheme: "g16"
|
||||
});
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
Options:
|
||||
* `curve` - Elliptic curve (`bn128` | `bls12_381` | `bls12_377` | `bw6_761`)
|
||||
* `scheme` - Proving scheme (`g16` | `gm17` | `marlin`)
|
||||
* `backend` - Backend (options: `ark` | `bellman`, default: `ark`)
|
||||
* `curve` - Elliptic curve (options: `bn128` | `bls12_381` | `bls12_377` | `bw6_761`, default: `bn128`)
|
||||
* `scheme` - Proving scheme (options: `g16` | `gm17` | `marlin`, default: `g16`)
|
||||
|
||||
Returns: `ZoKratesProvider`
|
||||
|
||||
|
@ -123,12 +128,13 @@ const fileSystemResolver = (from, to) => {
|
|||
};
|
||||
```
|
||||
|
||||
##### computeWitness(artifacts, args)
|
||||
##### computeWitness(artifacts, args[, options])
|
||||
Computes a valid assignment of the variables, which include the results of the computation.
|
||||
|
||||
Parameters:
|
||||
* `artifacts` - Compilation artifacts
|
||||
* `args` - Array of arguments (eg. `["1", "2", true]`)
|
||||
* `options` - Computation options
|
||||
|
||||
Returns: `ComputationResult`
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_cli"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>", "Thibaut Schaeffer <thibaut@schaeff.fr>"]
|
||||
repository = "https://github.com/Zokrates/ZoKrates.git"
|
||||
edition = "2018"
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
def main() {
|
||||
log("{}", 1 + 1); // 1 is of internal type {integer}
|
||||
return;
|
||||
}
|
4
zokrates_cli/examples/compile_errors/log_wrong_count.zok
Normal file
4
zokrates_cli/examples/compile_errors/log_wrong_count.zok
Normal file
|
@ -0,0 +1,4 @@
|
|||
def main() {
|
||||
log("{} {}", 1f);
|
||||
return;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_core"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
edition = "2018"
|
||||
authors = ["Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>", "Dennis Kuhnert <mail@kyroy.com>"]
|
||||
repository = "https://github.com/Zokrates/ZoKrates"
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
mod utils;
|
||||
|
||||
use self::utils::flat_expression_from_bits;
|
||||
use zokrates_ast::zir::{ShouldReduce, UMetadata, ZirExpressionList};
|
||||
use zokrates_ast::zir::{
|
||||
ConditionalExpression, SelectExpression, ShouldReduce, UMetadata, ZirExpressionList,
|
||||
};
|
||||
use zokrates_interpreter::Interpreter;
|
||||
|
||||
use crate::compile::CompileConfig;
|
||||
|
@ -558,13 +560,15 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
/// * `alternative` - the alternative of type U.
|
||||
/// # Remarks
|
||||
/// * U is the type of the expression
|
||||
fn flatten_if_else_expression<U: Flatten<'ast, T>>(
|
||||
fn flatten_conditional_expression<U: Flatten<'ast, T>>(
|
||||
&mut self,
|
||||
statements_flattened: &mut FlatStatements<T>,
|
||||
condition: BooleanExpression<'ast, T>,
|
||||
consequence: U,
|
||||
alternative: U,
|
||||
e: ConditionalExpression<'ast, T, U>,
|
||||
) -> FlatUExpression<T> {
|
||||
let condition = *e.condition;
|
||||
let consequence = *e.consequence;
|
||||
let alternative = *e.alternative;
|
||||
|
||||
let condition_flat =
|
||||
self.flatten_boolean_expression(statements_flattened, condition.clone());
|
||||
|
||||
|
@ -859,8 +863,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
BooleanExpression::Identifier(x) => {
|
||||
FlatExpression::Identifier(*self.layout.get(&x).unwrap())
|
||||
}
|
||||
BooleanExpression::Select(a, box index) => self
|
||||
.flatten_select_expression(statements_flattened, a, index)
|
||||
BooleanExpression::Select(e) => self
|
||||
.flatten_select_expression(statements_flattened, e)
|
||||
.get_field_unchecked(),
|
||||
BooleanExpression::FieldLt(box lhs, box rhs) => {
|
||||
// Get the bit width to know the size of the binary decompositions for this Field
|
||||
|
@ -949,14 +953,6 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
);
|
||||
FlatExpression::Add(box eq, box lt)
|
||||
}
|
||||
BooleanExpression::FieldGt(lhs, rhs) => self.flatten_boolean_expression(
|
||||
statements_flattened,
|
||||
BooleanExpression::FieldLt(rhs, lhs),
|
||||
),
|
||||
BooleanExpression::FieldGe(lhs, rhs) => self.flatten_boolean_expression(
|
||||
statements_flattened,
|
||||
BooleanExpression::FieldLe(rhs, lhs),
|
||||
),
|
||||
BooleanExpression::UintLt(box lhs, box rhs) => {
|
||||
let bit_width = lhs.bitwidth.to_usize();
|
||||
assert!(lhs.metadata.as_ref().unwrap().should_reduce.to_bool());
|
||||
|
@ -987,14 +983,6 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
);
|
||||
FlatExpression::Add(box eq, box lt)
|
||||
}
|
||||
BooleanExpression::UintGt(lhs, rhs) => self.flatten_boolean_expression(
|
||||
statements_flattened,
|
||||
BooleanExpression::UintLt(rhs, lhs),
|
||||
),
|
||||
BooleanExpression::UintGe(lhs, rhs) => self.flatten_boolean_expression(
|
||||
statements_flattened,
|
||||
BooleanExpression::UintLe(rhs, lhs),
|
||||
),
|
||||
BooleanExpression::Or(box lhs, box rhs) => {
|
||||
let x = self.flatten_boolean_expression(statements_flattened, lhs);
|
||||
let y = self.flatten_boolean_expression(statements_flattened, rhs);
|
||||
|
@ -1036,13 +1024,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
true => T::from(1),
|
||||
false => T::from(0),
|
||||
}),
|
||||
BooleanExpression::Conditional(box condition, box consequence, box alternative) => self
|
||||
.flatten_if_else_expression(
|
||||
statements_flattened,
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
)
|
||||
BooleanExpression::Conditional(e) => self
|
||||
.flatten_conditional_expression(statements_flattened, e)
|
||||
.get_field_unchecked(),
|
||||
}
|
||||
}
|
||||
|
@ -1473,9 +1456,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
});
|
||||
FlatUExpression::with_field(field).bits(bits)
|
||||
}
|
||||
UExpressionInner::Select(a, box index) => {
|
||||
self.flatten_select_expression(statements_flattened, a, index)
|
||||
}
|
||||
UExpressionInner::Select(e) => self.flatten_select_expression(statements_flattened, e),
|
||||
UExpressionInner::Not(box e) => {
|
||||
let e = self.flatten_uint_expression(statements_flattened, e);
|
||||
|
||||
|
@ -1633,13 +1614,9 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
|
||||
FlatUExpression::with_field(r)
|
||||
}
|
||||
UExpressionInner::Conditional(box condition, box consequence, box alternative) => self
|
||||
.flatten_if_else_expression(
|
||||
statements_flattened,
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
),
|
||||
UExpressionInner::Conditional(e) => {
|
||||
self.flatten_conditional_expression(statements_flattened, e)
|
||||
}
|
||||
UExpressionInner::Xor(box left, box right) => {
|
||||
let left_metadata = left.metadata.clone().unwrap();
|
||||
let right_metadata = right.metadata.clone().unwrap();
|
||||
|
@ -2039,10 +2016,12 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
fn flatten_select_expression<U: Flatten<'ast, T>>(
|
||||
&mut self,
|
||||
statements_flattened: &mut FlatStatements<T>,
|
||||
a: Vec<U>,
|
||||
index: UExpression<'ast, T>,
|
||||
e: SelectExpression<'ast, T, U>,
|
||||
) -> FlatUExpression<T> {
|
||||
let (range_check, result) = a
|
||||
let array = e.array;
|
||||
let index = *e.index;
|
||||
|
||||
let (range_check, result) = array
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, e)| {
|
||||
|
@ -2108,8 +2087,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
FieldElementExpression::Identifier(x) => {
|
||||
FlatExpression::Identifier(*self.layout.get(&x).unwrap_or_else(|| panic!("{}", x)))
|
||||
}
|
||||
FieldElementExpression::Select(a, box index) => self
|
||||
.flatten_select_expression(statements_flattened, a, index)
|
||||
FieldElementExpression::Select(e) => self
|
||||
.flatten_select_expression(statements_flattened, e)
|
||||
.get_field_unchecked(),
|
||||
FieldElementExpression::Add(box left, box right) => {
|
||||
let left_flattened = self.flatten_field_expression(statements_flattened, left);
|
||||
|
@ -2294,17 +2273,8 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
_ => panic!("Expected number as pow exponent"),
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Conditional(
|
||||
box condition,
|
||||
box consequence,
|
||||
box alternative,
|
||||
) => self
|
||||
.flatten_if_else_expression(
|
||||
statements_flattened,
|
||||
condition,
|
||||
consequence,
|
||||
alternative,
|
||||
)
|
||||
FieldElementExpression::Conditional(e) => self
|
||||
.flatten_conditional_expression(statements_flattened, e)
|
||||
.get_field_unchecked(),
|
||||
}
|
||||
}
|
||||
|
@ -2428,8 +2398,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
error.into(),
|
||||
)
|
||||
}
|
||||
BooleanExpression::FieldLt(box lhs, box rhs)
|
||||
| BooleanExpression::FieldGt(box rhs, box lhs) => {
|
||||
BooleanExpression::FieldLt(box lhs, box rhs) => {
|
||||
let lhs = self.flatten_field_expression(statements_flattened, lhs);
|
||||
let rhs = self.flatten_field_expression(statements_flattened, rhs);
|
||||
|
||||
|
@ -2459,8 +2428,7 @@ impl<'ast, T: Field> Flattener<'ast, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
BooleanExpression::FieldLe(box lhs, box rhs)
|
||||
| BooleanExpression::FieldGe(box rhs, box lhs) => {
|
||||
BooleanExpression::FieldLe(box lhs, box rhs) => {
|
||||
let lhs = self.flatten_field_expression(statements_flattened, lhs);
|
||||
let rhs = self.flatten_field_expression(statements_flattened, rhs);
|
||||
|
||||
|
@ -3531,13 +3499,13 @@ mod tests {
|
|||
#[test]
|
||||
fn if_else() {
|
||||
let config = CompileConfig::default();
|
||||
let expression = FieldElementExpression::Conditional(
|
||||
box BooleanExpression::FieldEq(
|
||||
let expression = FieldElementExpression::conditional(
|
||||
BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Number(Bn128Field::from(32)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(4)),
|
||||
),
|
||||
box FieldElementExpression::Number(Bn128Field::from(12)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(51)),
|
||||
FieldElementExpression::Number(Bn128Field::from(12)),
|
||||
FieldElementExpression::Number(Bn128Field::from(51)),
|
||||
);
|
||||
|
||||
let mut flattener = Flattener::new(config);
|
||||
|
@ -3554,13 +3522,6 @@ mod tests {
|
|||
box FieldElementExpression::Number(Bn128Field::from(4)),
|
||||
);
|
||||
flattener.flatten_boolean_expression(&mut FlatStatements::new(), expression_le);
|
||||
|
||||
let mut flattener = Flattener::new(config);
|
||||
let expression_ge = BooleanExpression::FieldGe(
|
||||
box FieldElementExpression::Number(Bn128Field::from(32)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(4)),
|
||||
);
|
||||
flattener.flatten_boolean_expression(&mut FlatStatements::new(), expression_ge);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -3568,8 +3529,8 @@ mod tests {
|
|||
let config = CompileConfig::default();
|
||||
let mut flattener = Flattener::new(config);
|
||||
|
||||
let expression = FieldElementExpression::Conditional(
|
||||
box BooleanExpression::And(
|
||||
let expression = FieldElementExpression::conditional(
|
||||
BooleanExpression::And(
|
||||
box BooleanExpression::FieldEq(
|
||||
box FieldElementExpression::Number(Bn128Field::from(4)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(4)),
|
||||
|
@ -3579,8 +3540,8 @@ mod tests {
|
|||
box FieldElementExpression::Number(Bn128Field::from(20)),
|
||||
),
|
||||
),
|
||||
box FieldElementExpression::Number(Bn128Field::from(12)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(51)),
|
||||
FieldElementExpression::Number(Bn128Field::from(12)),
|
||||
FieldElementExpression::Number(Bn128Field::from(51)),
|
||||
);
|
||||
|
||||
flattener.flatten_field_expression(&mut FlatStatements::new(), expression);
|
||||
|
|
|
@ -1804,15 +1804,30 @@ impl<'ast, T: Field> Checker<'ast, T> {
|
|||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|e| vec![e])?;
|
||||
|
||||
let mut errors = vec![];
|
||||
|
||||
for e in &expressions {
|
||||
if let TypedExpression::Int(e) = e {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!("Cannot determine type for expression `{}`", e),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if expressions.len() != l.len() {
|
||||
return Err(vec![ErrorInner {
|
||||
errors.push(ErrorInner {
|
||||
pos: Some(pos),
|
||||
message: format!(
|
||||
"Wrong argument count in log call: expected {}, got {}",
|
||||
l.len(),
|
||||
expressions.len()
|
||||
),
|
||||
}]);
|
||||
});
|
||||
}
|
||||
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
Ok(TypedStatement::Log(l, expressions))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::marker::PhantomData;
|
||||
use zokrates_ast::typed::types::UBitwidth;
|
||||
use zokrates_ast::typed::{self, Expr, Typed};
|
||||
use zokrates_ast::zir;
|
||||
use zokrates_ast::zir::{self, Select};
|
||||
use zokrates_field::Field;
|
||||
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
|
@ -746,36 +746,35 @@ fn fold_select_expression<'ast, T: Field, E>(
|
|||
let ty = a[0].get_type();
|
||||
|
||||
match ty {
|
||||
zir::Type::Boolean => zir::BooleanExpression::Select(
|
||||
zir::Type::Boolean => zir::BooleanExpression::select(
|
||||
a.into_iter()
|
||||
.map(|e| match e {
|
||||
zir::ZirExpression::Boolean(e) => e.clone(),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect(),
|
||||
box index.clone(),
|
||||
index.clone(),
|
||||
)
|
||||
.into(),
|
||||
zir::Type::FieldElement => zir::FieldElementExpression::Select(
|
||||
zir::Type::FieldElement => zir::FieldElementExpression::select(
|
||||
a.into_iter()
|
||||
.map(|e| match e {
|
||||
zir::ZirExpression::FieldElement(e) => e.clone(),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect(),
|
||||
box index.clone(),
|
||||
index.clone(),
|
||||
)
|
||||
.into(),
|
||||
zir::Type::Uint(bitwidth) => zir::UExpressionInner::Select(
|
||||
zir::Type::Uint(_) => zir::UExpression::select(
|
||||
a.into_iter()
|
||||
.map(|e| match e {
|
||||
zir::ZirExpression::Uint(e) => e.clone(),
|
||||
_ => unreachable!(),
|
||||
})
|
||||
.collect(),
|
||||
box index.clone(),
|
||||
index.clone(),
|
||||
)
|
||||
.annotate(bitwidth)
|
||||
.into(),
|
||||
}
|
||||
})
|
||||
|
@ -987,12 +986,12 @@ fn fold_boolean_expression<'ast, T: Field>(
|
|||
typed::BooleanExpression::FieldGt(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(statements_buffer, e1);
|
||||
let e2 = f.fold_field_expression(statements_buffer, e2);
|
||||
zir::BooleanExpression::FieldGt(box e1, box e2)
|
||||
zir::BooleanExpression::FieldLt(box e2, box e1)
|
||||
}
|
||||
typed::BooleanExpression::FieldGe(box e1, box e2) => {
|
||||
let e1 = f.fold_field_expression(statements_buffer, e1);
|
||||
let e2 = f.fold_field_expression(statements_buffer, e2);
|
||||
zir::BooleanExpression::FieldGe(box e1, box e2)
|
||||
zir::BooleanExpression::FieldLe(box e2, box e1)
|
||||
}
|
||||
typed::BooleanExpression::UintLt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(statements_buffer, e1);
|
||||
|
@ -1007,12 +1006,12 @@ fn fold_boolean_expression<'ast, T: Field>(
|
|||
typed::BooleanExpression::UintGt(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(statements_buffer, e1);
|
||||
let e2 = f.fold_uint_expression(statements_buffer, e2);
|
||||
zir::BooleanExpression::UintGt(box e1, box e2)
|
||||
zir::BooleanExpression::UintLt(box e2, box e1)
|
||||
}
|
||||
typed::BooleanExpression::UintGe(box e1, box e2) => {
|
||||
let e1 = f.fold_uint_expression(statements_buffer, e1);
|
||||
let e2 = f.fold_uint_expression(statements_buffer, e2);
|
||||
zir::BooleanExpression::UintGe(box e1, box e2)
|
||||
zir::BooleanExpression::UintLe(box e2, box e1)
|
||||
}
|
||||
typed::BooleanExpression::Or(box e1, box e2) => {
|
||||
let e1 = f.fold_boolean_expression(statements_buffer, e1);
|
||||
|
|
|
@ -55,22 +55,15 @@ fn force_no_reduce<T: Field>(e: UExpression<T>) -> UExpression<T> {
|
|||
}
|
||||
|
||||
impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
||||
fn fold_field_expression(
|
||||
fn fold_select_expression<E: Expr<'ast, T> + Fold<'ast, T> + Select<'ast, T>>(
|
||||
&mut self,
|
||||
e: FieldElementExpression<'ast, T>,
|
||||
) -> FieldElementExpression<'ast, T> {
|
||||
match e {
|
||||
FieldElementExpression::Select(a, box i) => {
|
||||
let a = a
|
||||
.into_iter()
|
||||
.map(|e| self.fold_field_expression(e))
|
||||
.collect();
|
||||
let i = self.fold_uint_expression(i);
|
||||
_: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> SelectOrExpression<'ast, T, E> {
|
||||
let array = e.array.into_iter().map(|e| e.fold(self)).collect();
|
||||
let index = e.index.fold(self);
|
||||
|
||||
FieldElementExpression::Select(a, box force_reduce(i))
|
||||
}
|
||||
_ => fold_field_expression(self, e),
|
||||
}
|
||||
SelectOrExpression::Select(SelectExpression::new(array, force_reduce(index)))
|
||||
}
|
||||
|
||||
fn fold_boolean_expression(
|
||||
|
@ -78,15 +71,6 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
e: BooleanExpression<'ast, T>,
|
||||
) -> BooleanExpression<'ast, T> {
|
||||
match e {
|
||||
BooleanExpression::Select(a, box i) => {
|
||||
let a = a
|
||||
.into_iter()
|
||||
.map(|e| self.fold_boolean_expression(e))
|
||||
.collect();
|
||||
let i = self.fold_uint_expression(i);
|
||||
|
||||
BooleanExpression::Select(a, box force_reduce(i))
|
||||
}
|
||||
BooleanExpression::UintEq(box left, box right) => {
|
||||
let left = self.fold_uint_expression(left);
|
||||
let right = self.fold_uint_expression(right);
|
||||
|
@ -114,24 +98,6 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
|
||||
BooleanExpression::UintLe(box left, box right)
|
||||
}
|
||||
BooleanExpression::UintGt(box left, box right) => {
|
||||
let left = self.fold_uint_expression(left);
|
||||
let right = self.fold_uint_expression(right);
|
||||
|
||||
let left = force_reduce(left);
|
||||
let right = force_reduce(right);
|
||||
|
||||
BooleanExpression::UintGt(box left, box right)
|
||||
}
|
||||
BooleanExpression::UintGe(box left, box right) => {
|
||||
let left = self.fold_uint_expression(left);
|
||||
let right = self.fold_uint_expression(right);
|
||||
|
||||
let left = force_reduce(left);
|
||||
let right = force_reduce(right);
|
||||
|
||||
BooleanExpression::UintGe(box left, box right)
|
||||
}
|
||||
e => fold_boolean_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
@ -161,12 +127,15 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
.cloned()
|
||||
.unwrap_or_else(|| panic!("identifier should have been defined: {}", id)),
|
||||
),
|
||||
Select(values, box index) => {
|
||||
Select(e) => {
|
||||
let index = *e.index;
|
||||
let array = e.array;
|
||||
|
||||
let index = self.fold_uint_expression(index);
|
||||
|
||||
let index = force_reduce(index);
|
||||
|
||||
let values: Vec<_> = values
|
||||
let values: Vec<_> = array
|
||||
.into_iter()
|
||||
.map(|v| force_no_reduce(self.fold_uint_expression(v)))
|
||||
.collect();
|
||||
|
@ -389,10 +358,10 @@ impl<'ast, T: Field> Folder<'ast, T> for UintOptimizer<'ast, T> {
|
|||
|
||||
UExpression::right_shift(force_reduce(e), by).with_max(max)
|
||||
}
|
||||
Conditional(box condition, box consequence, box alternative) => {
|
||||
let condition = self.fold_boolean_expression(condition);
|
||||
let consequence = self.fold_uint_expression(consequence);
|
||||
let alternative = self.fold_uint_expression(alternative);
|
||||
Conditional(e) => {
|
||||
let condition = self.fold_boolean_expression(*e.condition);
|
||||
let consequence = e.consequence.fold(self);
|
||||
let alternative = e.alternative.fold(self);
|
||||
|
||||
let consequence_max = consequence.metadata.clone().unwrap().max;
|
||||
let alternative_max = alternative.metadata.clone().unwrap().max;
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use zokrates_ast::zir::result_folder::fold_boolean_expression;
|
||||
use zokrates_ast::zir::result_folder::fold_field_expression;
|
||||
use zokrates_ast::zir::result_folder::fold_statement;
|
||||
use zokrates_ast::zir::result_folder::fold_uint_expression_inner;
|
||||
use zokrates_ast::zir::result_folder::ResultFold;
|
||||
use zokrates_ast::zir::result_folder::ResultFolder;
|
||||
use zokrates_ast::zir::types::UBitwidth;
|
||||
use zokrates_ast::zir::Conditional;
|
||||
use zokrates_ast::zir::ConditionalExpression;
|
||||
use zokrates_ast::zir::ConditionalOrExpression;
|
||||
use zokrates_ast::zir::Expr;
|
||||
use zokrates_ast::zir::SelectExpression;
|
||||
use zokrates_ast::zir::SelectOrExpression;
|
||||
use zokrates_ast::zir::{
|
||||
BooleanExpression, FieldElementExpression, Identifier, RuntimeError, UExpression,
|
||||
UExpressionInner, ZirExpression, ZirProgram, ZirStatement,
|
||||
|
@ -136,24 +146,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
}
|
||||
_ => Ok(FieldElementExpression::Identifier(id)),
|
||||
},
|
||||
FieldElementExpression::Select(e, box index) => {
|
||||
let index = self.fold_uint_expression(index)?;
|
||||
let e: Vec<FieldElementExpression<'ast, T>> = e
|
||||
.into_iter()
|
||||
.map(|e| self.fold_field_expression(e))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
match index.into_inner() {
|
||||
UExpressionInner::Value(v) => e
|
||||
.get(v as usize)
|
||||
.cloned()
|
||||
.ok_or(Error::OutOfBounds(v as usize, e.len())),
|
||||
i => Ok(FieldElementExpression::Select(
|
||||
e,
|
||||
box i.annotate(UBitwidth::B32),
|
||||
)),
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Add(box e1, box e2) => {
|
||||
match (
|
||||
self.fold_field_expression(e1)?,
|
||||
|
@ -237,28 +229,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
)),
|
||||
}
|
||||
}
|
||||
FieldElementExpression::Conditional(
|
||||
box condition,
|
||||
box consequence,
|
||||
box alternative,
|
||||
) => {
|
||||
let condition = self.fold_boolean_expression(condition)?;
|
||||
let consequence = self.fold_field_expression(consequence)?;
|
||||
let alternative = self.fold_field_expression(alternative)?;
|
||||
|
||||
match (condition, consequence, alternative) {
|
||||
(_, consequence, alternative) if consequence == alternative => Ok(consequence),
|
||||
(BooleanExpression::Value(true), consequence, _) => Ok(consequence),
|
||||
(BooleanExpression::Value(false), _, alternative) => Ok(alternative),
|
||||
(condition, consequence, alternative) => {
|
||||
Ok(FieldElementExpression::Conditional(
|
||||
box condition,
|
||||
box consequence,
|
||||
box alternative,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
e => fold_field_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,21 +245,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
}
|
||||
_ => Ok(BooleanExpression::Identifier(id)),
|
||||
},
|
||||
BooleanExpression::Select(e, box index) => {
|
||||
let index = self.fold_uint_expression(index)?;
|
||||
let e: Vec<BooleanExpression<'ast, T>> = e
|
||||
.into_iter()
|
||||
.map(|e| self.fold_boolean_expression(e))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
match index.as_inner() {
|
||||
UExpressionInner::Value(v) => e
|
||||
.get(*v as usize)
|
||||
.cloned()
|
||||
.ok_or(Error::OutOfBounds(*v as usize, e.len())),
|
||||
_ => Ok(BooleanExpression::Select(e, box index)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::FieldLt(box e1, box e2) => {
|
||||
match (
|
||||
self.fold_field_expression(e1)?,
|
||||
|
@ -317,34 +273,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
(e1, e2) => Ok(BooleanExpression::FieldLe(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::FieldGe(box e1, box e2) => {
|
||||
match (
|
||||
self.fold_field_expression(e1)?,
|
||||
self.fold_field_expression(e2)?,
|
||||
) {
|
||||
(FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => {
|
||||
Ok(BooleanExpression::Value(n1 >= n2))
|
||||
}
|
||||
(e1, e2) => Ok(BooleanExpression::FieldGe(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::FieldGt(box e1, box e2) => {
|
||||
match (
|
||||
self.fold_field_expression(e1)?,
|
||||
self.fold_field_expression(e2)?,
|
||||
) {
|
||||
(FieldElementExpression::Number(n1), FieldElementExpression::Number(n2)) => {
|
||||
Ok(BooleanExpression::Value(n1 > n2))
|
||||
}
|
||||
(_, FieldElementExpression::Number(c)) if c == T::max_value() => {
|
||||
Ok(BooleanExpression::Value(false))
|
||||
}
|
||||
(FieldElementExpression::Number(c), _) if c == T::zero() => {
|
||||
Ok(BooleanExpression::Value(false))
|
||||
}
|
||||
(e1, e2) => Ok(BooleanExpression::FieldGt(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::FieldEq(box e1, box e2) => {
|
||||
match (
|
||||
self.fold_field_expression(e1)?,
|
||||
|
@ -384,28 +312,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
_ => Ok(BooleanExpression::UintLe(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::UintGe(box e1, box e2) => {
|
||||
let e1 = self.fold_uint_expression(e1)?;
|
||||
let e2 = self.fold_uint_expression(e2)?;
|
||||
|
||||
match (e1.as_inner(), e2.as_inner()) {
|
||||
(UExpressionInner::Value(v1), UExpressionInner::Value(v2)) => {
|
||||
Ok(BooleanExpression::Value(v1 >= v2))
|
||||
}
|
||||
_ => Ok(BooleanExpression::UintGe(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::UintGt(box e1, box e2) => {
|
||||
let e1 = self.fold_uint_expression(e1)?;
|
||||
let e2 = self.fold_uint_expression(e2)?;
|
||||
|
||||
match (e1.as_inner(), e2.as_inner()) {
|
||||
(UExpressionInner::Value(v1), UExpressionInner::Value(v2)) => {
|
||||
Ok(BooleanExpression::Value(v1 > v2))
|
||||
}
|
||||
_ => Ok(BooleanExpression::UintGt(box e1, box e2)),
|
||||
}
|
||||
}
|
||||
BooleanExpression::UintEq(box e1, box e2) => {
|
||||
let e1 = self.fold_uint_expression(e1)?;
|
||||
let e2 = self.fold_uint_expression(e2)?;
|
||||
|
@ -475,22 +381,33 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
BooleanExpression::Value(v) => Ok(BooleanExpression::Value(!v)),
|
||||
e => Ok(BooleanExpression::Not(box e)),
|
||||
},
|
||||
BooleanExpression::Conditional(box condition, box consequence, box alternative) => {
|
||||
let condition = self.fold_boolean_expression(condition)?;
|
||||
let consequence = self.fold_boolean_expression(consequence)?;
|
||||
let alternative = self.fold_boolean_expression(alternative)?;
|
||||
e => fold_boolean_expression(self, e),
|
||||
}
|
||||
}
|
||||
|
||||
match (condition, consequence, alternative) {
|
||||
(_, consequence, alternative) if consequence == alternative => Ok(consequence),
|
||||
(BooleanExpression::Value(true), consequence, _) => Ok(consequence),
|
||||
(BooleanExpression::Value(false), _, alternative) => Ok(alternative),
|
||||
(condition, consequence, alternative) => Ok(BooleanExpression::Conditional(
|
||||
box condition,
|
||||
box consequence,
|
||||
box alternative,
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn fold_select_expression<
|
||||
E: Clone + Expr<'ast, T> + ResultFold<'ast, T> + zokrates_ast::zir::Select<'ast, T>,
|
||||
>(
|
||||
&mut self,
|
||||
_: &E::Ty,
|
||||
e: SelectExpression<'ast, T, E>,
|
||||
) -> Result<zokrates_ast::zir::SelectOrExpression<'ast, T, E>, Self::Error> {
|
||||
let index = self.fold_uint_expression(*e.index)?;
|
||||
let array = e
|
||||
.array
|
||||
.into_iter()
|
||||
.map(|e| e.fold(self))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
match index.as_inner() {
|
||||
UExpressionInner::Value(v) => array
|
||||
.get(*v as usize)
|
||||
.cloned()
|
||||
.ok_or(Error::OutOfBounds(*v as usize, array.len()))
|
||||
.map(|e| SelectOrExpression::Expression(e.into_inner())),
|
||||
_ => Ok(SelectOrExpression::Expression(
|
||||
E::select(array, index).into_inner(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -505,22 +422,6 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
Some(ZirExpression::Uint(e)) => Ok(e.as_inner().clone()),
|
||||
_ => Ok(UExpressionInner::Identifier(id)),
|
||||
},
|
||||
UExpressionInner::Select(e, box index) => {
|
||||
let index = self.fold_uint_expression(index)?;
|
||||
let e: Vec<UExpression<'ast, T>> = e
|
||||
.into_iter()
|
||||
.map(|e| self.fold_uint_expression(e))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
match index.into_inner() {
|
||||
UExpressionInner::Value(v) => e
|
||||
.get(v as usize)
|
||||
.cloned()
|
||||
.ok_or(Error::OutOfBounds(v as usize, e.len()))
|
||||
.map(|e| e.into_inner()),
|
||||
i => Ok(UExpressionInner::Select(e, box i.annotate(UBitwidth::B32))),
|
||||
}
|
||||
}
|
||||
UExpressionInner::Add(box e1, box e2) => {
|
||||
let e1 = self.fold_uint_expression(e1)?;
|
||||
let e2 = self.fold_uint_expression(e2)?;
|
||||
|
@ -687,22 +588,34 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> {
|
|||
e => Ok(UExpressionInner::Not(box e.annotate(bitwidth))),
|
||||
}
|
||||
}
|
||||
UExpressionInner::Conditional(box condition, box consequence, box alternative) => {
|
||||
let condition = self.fold_boolean_expression(condition)?;
|
||||
let consequence = self.fold_uint_expression(consequence)?.into_inner();
|
||||
let alternative = self.fold_uint_expression(alternative)?.into_inner();
|
||||
e => fold_uint_expression_inner(self, bitwidth, e),
|
||||
}
|
||||
}
|
||||
|
||||
match (condition, consequence, alternative) {
|
||||
(_, consequence, alternative) if consequence == alternative => Ok(consequence),
|
||||
(BooleanExpression::Value(true), consequence, _) => Ok(consequence),
|
||||
(BooleanExpression::Value(false), _, alternative) => Ok(alternative),
|
||||
(condition, consequence, alternative) => Ok(UExpressionInner::Conditional(
|
||||
box condition,
|
||||
box consequence.annotate(bitwidth),
|
||||
box alternative.annotate(bitwidth),
|
||||
)),
|
||||
}
|
||||
}
|
||||
fn fold_conditional_expression<
|
||||
E: Expr<'ast, T> + ResultFold<'ast, T> + Conditional<'ast, T>,
|
||||
>(
|
||||
&mut self,
|
||||
_: &E::Ty,
|
||||
e: ConditionalExpression<'ast, T, E>,
|
||||
) -> Result<ConditionalOrExpression<'ast, T, E>, Self::Error> {
|
||||
let condition = self.fold_boolean_expression(*e.condition)?;
|
||||
let consequence = e.consequence.fold(self)?;
|
||||
let alternative = e.alternative.fold(self)?;
|
||||
|
||||
match (condition, consequence, alternative) {
|
||||
(_, consequence, alternative) if consequence == alternative => Ok(
|
||||
ConditionalOrExpression::Expression(consequence.into_inner()),
|
||||
),
|
||||
(BooleanExpression::Value(true), consequence, _) => Ok(
|
||||
ConditionalOrExpression::Expression(consequence.into_inner()),
|
||||
),
|
||||
(BooleanExpression::Value(false), _, alternative) => Ok(
|
||||
ConditionalOrExpression::Expression(alternative.into_inner()),
|
||||
),
|
||||
(condition, consequence, alternative) => Ok(ConditionalOrExpression::Conditional(
|
||||
ConditionalExpression::new(condition, consequence, alternative),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -754,6 +667,8 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod field {
|
||||
use zokrates_ast::zir::Select;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -761,23 +676,23 @@ mod tests {
|
|||
let mut propagator = ZirPropagator::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::Select(
|
||||
propagator.fold_field_expression(FieldElementExpression::select(
|
||||
vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
],
|
||||
box UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(FieldElementExpression::Number(Bn128Field::from(2)))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::Select(
|
||||
propagator.fold_field_expression(FieldElementExpression::select(
|
||||
vec![
|
||||
FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
],
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Err(Error::OutOfBounds(3, 2))
|
||||
);
|
||||
|
@ -923,28 +838,28 @@ mod tests {
|
|||
let mut propagator = ZirPropagator::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::Conditional(
|
||||
box BooleanExpression::Value(true),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
propagator.fold_field_expression(FieldElementExpression::conditional(
|
||||
BooleanExpression::Value(true),
|
||||
FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(FieldElementExpression::Number(Bn128Field::from(1)))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::Conditional(
|
||||
box BooleanExpression::Value(false),
|
||||
box FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
propagator.fold_field_expression(FieldElementExpression::conditional(
|
||||
BooleanExpression::Value(false),
|
||||
FieldElementExpression::Number(Bn128Field::from(1)),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(FieldElementExpression::Number(Bn128Field::from(2)))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_field_expression(FieldElementExpression::Conditional(
|
||||
box BooleanExpression::Identifier("a".into()),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
propagator.fold_field_expression(FieldElementExpression::conditional(
|
||||
BooleanExpression::Identifier("a".into()),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(FieldElementExpression::Number(Bn128Field::from(2)))
|
||||
);
|
||||
|
@ -953,6 +868,8 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod bool {
|
||||
use zokrates_ast::zir::Select;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
@ -960,23 +877,23 @@ mod tests {
|
|||
let mut propagator = ZirPropagator::<Bn128Field>::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::Select(
|
||||
propagator.fold_boolean_expression(BooleanExpression::select(
|
||||
vec![
|
||||
BooleanExpression::Value(false),
|
||||
BooleanExpression::Value(true),
|
||||
],
|
||||
box UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::Select(
|
||||
propagator.fold_boolean_expression(BooleanExpression::select(
|
||||
vec![
|
||||
BooleanExpression::Value(false),
|
||||
BooleanExpression::Value(true),
|
||||
],
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Err(Error::OutOfBounds(3, 2))
|
||||
);
|
||||
|
@ -1040,64 +957,6 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_ge() {
|
||||
let mut propagator = ZirPropagator::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGe(
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGe(
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_gt() {
|
||||
let mut propagator = ZirPropagator::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGt(
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(2)),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGt(
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
box FieldElementExpression::Number(Bn128Field::from(3)),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(false))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGt(
|
||||
box FieldElementExpression::Number(Bn128Field::from(0)),
|
||||
box FieldElementExpression::Identifier("a".into()),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(false))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::FieldGt(
|
||||
box FieldElementExpression::Identifier("a".into()),
|
||||
box FieldElementExpression::Number(Bn128Field::max_value()),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(false))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn field_eq() {
|
||||
let mut propagator = ZirPropagator::default();
|
||||
|
@ -1161,48 +1020,6 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_ge() {
|
||||
let mut propagator = ZirPropagator::<Bn128Field>::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::UintGe(
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::UintGe(
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_gt() {
|
||||
let mut propagator = ZirPropagator::<Bn128Field>::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::UintGt(
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::UintGt(
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
)),
|
||||
Ok(BooleanExpression::Value(false))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uint_eq() {
|
||||
let mut propagator = ZirPropagator::<Bn128Field>::default();
|
||||
|
@ -1327,28 +1144,28 @@ mod tests {
|
|||
let mut propagator = ZirPropagator::<Bn128Field>::default();
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::Conditional(
|
||||
box BooleanExpression::Value(true),
|
||||
box BooleanExpression::Value(true),
|
||||
box BooleanExpression::Value(false)
|
||||
propagator.fold_boolean_expression(BooleanExpression::conditional(
|
||||
BooleanExpression::Value(true),
|
||||
BooleanExpression::Value(true),
|
||||
BooleanExpression::Value(false)
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::Conditional(
|
||||
box BooleanExpression::Value(false),
|
||||
box BooleanExpression::Value(true),
|
||||
box BooleanExpression::Value(false)
|
||||
propagator.fold_boolean_expression(BooleanExpression::conditional(
|
||||
BooleanExpression::Value(false),
|
||||
BooleanExpression::Value(true),
|
||||
BooleanExpression::Value(false)
|
||||
)),
|
||||
Ok(BooleanExpression::Value(false))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
propagator.fold_boolean_expression(BooleanExpression::Conditional(
|
||||
box BooleanExpression::Identifier("a".into()),
|
||||
box BooleanExpression::Value(true),
|
||||
box BooleanExpression::Value(true)
|
||||
propagator.fold_boolean_expression(BooleanExpression::conditional(
|
||||
BooleanExpression::Identifier("a".into()),
|
||||
BooleanExpression::Value(true),
|
||||
BooleanExpression::Value(true)
|
||||
)),
|
||||
Ok(BooleanExpression::Value(true))
|
||||
);
|
||||
|
@ -1366,13 +1183,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
propagator.fold_uint_expression_inner(
|
||||
UBitwidth::B32,
|
||||
UExpressionInner::Select(
|
||||
UExpression::select(
|
||||
vec![
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
],
|
||||
box UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into_inner()
|
||||
),
|
||||
Ok(UExpressionInner::Value(2))
|
||||
);
|
||||
|
@ -1380,13 +1198,14 @@ mod tests {
|
|||
assert_eq!(
|
||||
propagator.fold_uint_expression_inner(
|
||||
UBitwidth::B32,
|
||||
UExpressionInner::Select(
|
||||
UExpression::select(
|
||||
vec![
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
],
|
||||
box UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(3).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into_inner()
|
||||
),
|
||||
Err(Error::OutOfBounds(3, 2))
|
||||
);
|
||||
|
@ -1752,11 +1571,12 @@ mod tests {
|
|||
assert_eq!(
|
||||
propagator.fold_uint_expression_inner(
|
||||
UBitwidth::B32,
|
||||
UExpressionInner::Conditional(
|
||||
box BooleanExpression::Value(true),
|
||||
box UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
UExpression::conditional(
|
||||
BooleanExpression::Value(true),
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into_inner()
|
||||
),
|
||||
Ok(UExpressionInner::Value(1))
|
||||
);
|
||||
|
@ -1764,11 +1584,12 @@ mod tests {
|
|||
assert_eq!(
|
||||
propagator.fold_uint_expression_inner(
|
||||
UBitwidth::B32,
|
||||
UExpressionInner::Conditional(
|
||||
box BooleanExpression::Value(false),
|
||||
box UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
UExpression::conditional(
|
||||
BooleanExpression::Value(false),
|
||||
UExpressionInner::Value(1).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into_inner()
|
||||
),
|
||||
Ok(UExpressionInner::Value(2))
|
||||
);
|
||||
|
@ -1776,11 +1597,12 @@ mod tests {
|
|||
assert_eq!(
|
||||
propagator.fold_uint_expression_inner(
|
||||
UBitwidth::B32,
|
||||
UExpressionInner::Conditional(
|
||||
box BooleanExpression::Identifier("a".into()),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
box UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
UExpression::conditional(
|
||||
BooleanExpression::Identifier("a".into()),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
UExpressionInner::Value(2).annotate(UBitwidth::B32),
|
||||
)
|
||||
.into_inner()
|
||||
),
|
||||
Ok(UExpressionInner::Value(2))
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_interpreter"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
|
|
|
@ -106,6 +106,8 @@ impl Interpreter {
|
|||
}
|
||||
|
||||
writeln!(log_stream).map_err(|_| Error::LogStream)?;
|
||||
|
||||
log_stream.flush().map_err(|_| Error::LogStream)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_js"
|
||||
version = "1.1.0"
|
||||
version = "1.1.2"
|
||||
authors = ["Darko Macesic"]
|
||||
edition = "2018"
|
||||
|
||||
|
@ -13,14 +13,21 @@ serde = { version = "^1.0.59", features = ["derive"] }
|
|||
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||
wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] }
|
||||
typed-arena = "1.4.1"
|
||||
zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark"] }
|
||||
lazy_static = "1.4.0"
|
||||
zokrates_core = { path = "../zokrates_core", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_ark = { path = "../zokrates_ark", default-features = false}
|
||||
zokrates_common = { path = "../zokrates_common", default-features = false, features = ["ark"] }
|
||||
zokrates_bellman = { path = "../zokrates_bellman", default-features = false}
|
||||
zokrates_common = { path = "../zokrates_common", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_proof_systems = { path = "../zokrates_proof_systems", default-features = false }
|
||||
zokrates_ast = { path = "../zokrates_ast", default-features = false, features = ["ark"] }
|
||||
zokrates_interpreter = { path = "../zokrates_interpreter", default-features = false, features = ["ark"] }
|
||||
zokrates_ast = { path = "../zokrates_ast", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_interpreter = { path = "../zokrates_interpreter", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_field = { path = "../zokrates_field", default-features = false }
|
||||
zokrates_abi = { path = "../zokrates_abi", default-features = false, features = ["ark"] }
|
||||
zokrates_abi = { path = "../zokrates_abi", default-features = false, features = ["ark", "bellman"] }
|
||||
zokrates_circom = { path = "../zokrates_circom" }
|
||||
console_error_panic_hook = "0.1.6"
|
||||
indexmap = "~1.6.2" # see https://github.com/rustwasm/wasm-bindgen/issues/2770#issuecomment-1041102532
|
||||
indexmap = "~1.6.2" # see https://github.com/rustwasm/wasm-bindgen/issues/2770#issuecomment-1041102532
|
||||
|
||||
[build-dependencies]
|
||||
json = "0.12.4"
|
||||
walkdir = "2.3.2"
|
||||
toml = "0.5.9"
|
46
zokrates_js/build.rs
Normal file
46
zokrates_js/build.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
use std::path::Path;
|
||||
use std::{env, fs};
|
||||
use walkdir::WalkDir;
|
||||
|
||||
fn main() {
|
||||
export_stdlib();
|
||||
export_metadata();
|
||||
}
|
||||
|
||||
fn export_stdlib() {
|
||||
let root = "../zokrates_stdlib/stdlib";
|
||||
let mut stdlib = json::JsonValue::new_object();
|
||||
|
||||
for entry in WalkDir::new(root)
|
||||
.into_iter()
|
||||
.map(Result::unwrap)
|
||||
.filter(|e| !e.file_type().is_dir())
|
||||
{
|
||||
let path: &Path = entry.path();
|
||||
let source = fs::read_to_string(path).unwrap();
|
||||
stdlib
|
||||
.insert(path.strip_prefix(root).unwrap().to_str().unwrap(), source)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("stdlib.json");
|
||||
|
||||
fs::write(dest_path, stdlib.dump()).unwrap();
|
||||
}
|
||||
|
||||
fn export_metadata() {
|
||||
let path = "../zokrates_cli/Cargo.toml";
|
||||
let config: toml::Value = toml::from_str(&fs::read_to_string(path).unwrap()).unwrap();
|
||||
|
||||
let mut metadata = json::JsonValue::new_object();
|
||||
metadata
|
||||
.insert("version", config["package"]["version"].as_str().unwrap())
|
||||
.unwrap();
|
||||
|
||||
fs::write(
|
||||
"metadata.js",
|
||||
format!("module.exports = {}", metadata.dump()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
const gulp = require("gulp");
|
||||
const dree = require("dree");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const toml = require("toml");
|
||||
|
||||
const stdlibRoot = "../zokrates_stdlib/stdlib";
|
||||
const options = {
|
||||
extensions: ["zok"],
|
||||
};
|
||||
|
||||
// Serializes the standard library directory tree to a js file.
|
||||
gulp.task("stdlib", (done) => {
|
||||
var stdlib = {};
|
||||
dree.scan(stdlibRoot, options, function (file) {
|
||||
const content = fs.readFileSync(file.path).toString();
|
||||
stdlib[file.relativePath] = content;
|
||||
});
|
||||
|
||||
fs.writeFileSync(
|
||||
path.resolve(__dirname, "stdlib.js"),
|
||||
`module.exports = ${JSON.stringify(stdlib)}`
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("metadata", (done) => {
|
||||
const config = toml.parse(
|
||||
fs.readFileSync("../zokrates_cli/Cargo.toml").toString()
|
||||
);
|
||||
const metadata = JSON.stringify({
|
||||
version: config.package.version,
|
||||
});
|
||||
fs.writeFileSync(
|
||||
path.resolve(__dirname, "metadata.js"),
|
||||
`module.exports = ${metadata}`
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task("setup", gulp.parallel("stdlib", "metadata"));
|
6
zokrates_js/index.d.ts
vendored
6
zokrates_js/index.d.ts
vendored
|
@ -1,4 +1,5 @@
|
|||
declare module "zokrates-js" {
|
||||
export type Backend = "ark" | "bellman";
|
||||
export type Curve = "bn128" | "bls12_381" | "bls12_377" | "bw6_761";
|
||||
export type Scheme = "g16" | "gm17" | "marlin";
|
||||
|
||||
|
@ -12,6 +13,7 @@ declare module "zokrates-js" {
|
|||
|
||||
export interface CompileConfig {
|
||||
isolate_branches?: boolean;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
export interface CompileOptions {
|
||||
|
@ -32,8 +34,11 @@ declare module "zokrates-js" {
|
|||
location: string;
|
||||
}
|
||||
|
||||
export type LogCallback = (log: string) => void;
|
||||
|
||||
export interface ComputeOptions {
|
||||
snarkjs?: boolean;
|
||||
logCallback?: LogCallback;
|
||||
}
|
||||
|
||||
export interface ComputationResult {
|
||||
|
@ -63,6 +68,7 @@ declare module "zokrates-js" {
|
|||
}
|
||||
|
||||
export type Options = {
|
||||
backend: Backend;
|
||||
scheme: Scheme;
|
||||
curve: Curve;
|
||||
};
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import wrapper from "./wrapper.js";
|
||||
import stdlib from "./stdlib.js";
|
||||
import lib from "./lib.js";
|
||||
import metadata from "./metadata.js";
|
||||
|
||||
const initialize = async () => {
|
||||
const zokrates = await import("./pkg/index.js");
|
||||
return wrapper({ zokrates, stdlib });
|
||||
const pkg = await import("./pkg/index.js");
|
||||
return lib(pkg);
|
||||
};
|
||||
|
||||
export { initialize, metadata };
|
||||
export { initialize, metadata };
|
||||
|
|
|
@ -1,38 +1,4 @@
|
|||
const getAbsolutePath = (basePath, relativePath) => {
|
||||
if (relativePath[0] !== ".") {
|
||||
return relativePath;
|
||||
}
|
||||
var stack = basePath.split("/");
|
||||
var chunks = relativePath.split("/");
|
||||
stack.pop();
|
||||
|
||||
for (var i = 0; i < chunks.length; i++) {
|
||||
if (chunks[i] == ".") {
|
||||
continue;
|
||||
} else if (chunks[i] == "..") {
|
||||
stack.pop();
|
||||
} else {
|
||||
stack.push(chunks[i]);
|
||||
}
|
||||
}
|
||||
return stack.join("/");
|
||||
};
|
||||
|
||||
const getImportPath = (currentLocation, importLocation) => {
|
||||
let path = getAbsolutePath(currentLocation, importLocation);
|
||||
const extension = path.slice(((path.lastIndexOf(".") - 1) >>> 0) + 2);
|
||||
return extension ? path : path.concat(".zok");
|
||||
};
|
||||
|
||||
module.exports = (dep) => {
|
||||
const { zokrates, stdlib } = dep;
|
||||
|
||||
const resolveFromStdlib = (currentLocation, importLocation) => {
|
||||
let key = getImportPath(currentLocation, importLocation);
|
||||
let source = stdlib[key];
|
||||
return source ? { source, location: key } : null;
|
||||
};
|
||||
|
||||
module.exports = (pkg) => {
|
||||
const defaultProvider = {
|
||||
compile: (source, compileOptions = {}) => {
|
||||
var {
|
||||
|
@ -45,31 +11,33 @@ module.exports = (dep) => {
|
|||
|
||||
config = { snarkjs, ...config };
|
||||
|
||||
const callback = (currentLocation, importLocation) => {
|
||||
return (
|
||||
resolveFromStdlib(currentLocation, importLocation) ||
|
||||
resolveCallback(currentLocation, importLocation)
|
||||
);
|
||||
};
|
||||
const ptr = zokrates.compile(source, location, callback, config, curve);
|
||||
return Object.assign(
|
||||
const ptr = pkg.compile(source, location, resolveCallback, config, curve);
|
||||
const result = Object.assign(
|
||||
{
|
||||
program: ptr.program(),
|
||||
abi: ptr.abi(),
|
||||
},
|
||||
snarkjs ? { snarkjs: { program: ptr.snarkjs_program() } } : {}
|
||||
);
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
computeWitness: (input, args, computeOptions = {}) => {
|
||||
const { program, abi } =
|
||||
input instanceof Uint8Array ? { program: input, abi: null } : input;
|
||||
|
||||
const { snarkjs = false } = computeOptions;
|
||||
const ptr = zokrates.compute_witness(program, abi, JSON.stringify(args), {
|
||||
snarkjs: snarkjs,
|
||||
});
|
||||
const { snarkjs = false, logCallback = console.log } = computeOptions;
|
||||
const ptr = pkg.compute_witness(
|
||||
program,
|
||||
abi,
|
||||
JSON.stringify(args),
|
||||
{
|
||||
snarkjs: snarkjs,
|
||||
},
|
||||
logCallback
|
||||
);
|
||||
|
||||
return Object.assign(
|
||||
const result = Object.assign(
|
||||
{
|
||||
witness: ptr.witness(),
|
||||
output: ptr.output(),
|
||||
|
@ -82,28 +50,31 @@ module.exports = (dep) => {
|
|||
}
|
||||
: {}
|
||||
);
|
||||
|
||||
ptr.free();
|
||||
return result;
|
||||
},
|
||||
setup: (program, options) => {
|
||||
return zokrates.setup(program, options);
|
||||
return pkg.setup(program, options);
|
||||
},
|
||||
universalSetup: (curve, size) => {
|
||||
return zokrates.universal_setup(curve, size);
|
||||
return pkg.universal_setup(curve, size);
|
||||
},
|
||||
setupWithSrs: (srs, program, options) => {
|
||||
return zokrates.setup_with_srs(srs, program, options);
|
||||
return pkg.setup_with_srs(srs, program, options);
|
||||
},
|
||||
generateProof: (program, witness, provingKey, options) => {
|
||||
return zokrates.generate_proof(program, witness, provingKey, options);
|
||||
return pkg.generate_proof(program, witness, provingKey, options);
|
||||
},
|
||||
verify: (vk, proof) => {
|
||||
return zokrates.verify(vk, proof);
|
||||
verify: (vk, proof, options) => {
|
||||
return pkg.verify(vk, proof, options);
|
||||
},
|
||||
exportSolidityVerifier: (vk) => {
|
||||
return zokrates.export_solidity_verifier(vk);
|
||||
return pkg.export_solidity_verifier(vk);
|
||||
},
|
||||
utils: {
|
||||
formatProof: (proof) => {
|
||||
return zokrates.format_proof(proof);
|
||||
return pkg.format_proof(proof);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -125,7 +96,7 @@ module.exports = (dep) => {
|
|||
defaultProvider.setupWithSrs(srs, program, options),
|
||||
generateProof: (program, witness, provingKey) =>
|
||||
defaultProvider.generateProof(program, witness, provingKey, options),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof),
|
||||
verify: (vk, proof) => defaultProvider.verify(vk, proof, options),
|
||||
exportSolidityVerifier: (vk) =>
|
||||
defaultProvider.exportSolidityVerifier(vk),
|
||||
utils: {
|
||||
|
@ -135,6 +106,6 @@ module.exports = (dep) => {
|
|||
};
|
||||
|
||||
return {
|
||||
...withOptions({ scheme: "g16", curve: "bn128" }),
|
||||
...withOptions({ backend: "ark", scheme: "g16", curve: "bn128" }),
|
||||
};
|
||||
};
|
|
@ -1,12 +1,8 @@
|
|||
const wrapper = require("../wrapper.js");
|
||||
const stdlib = require("../stdlib.js");
|
||||
const lib = require("../lib.js");
|
||||
const metadata = require("../metadata.js");
|
||||
|
||||
const initialize = async () => {
|
||||
return wrapper({
|
||||
zokrates: require("./pkg/index.js"),
|
||||
stdlib,
|
||||
});
|
||||
return lib(require("./pkg/index.js"));
|
||||
};
|
||||
|
||||
module.exports = { initialize, metadata };
|
||||
|
|
8000
zokrates_js/package-lock.json
generated
8000
zokrates_js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "zokrates-js",
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.2",
|
||||
"module": "index.js",
|
||||
"main": "node/index.js",
|
||||
"description": "JavaScript bindings for ZoKrates",
|
||||
|
@ -19,44 +19,34 @@
|
|||
"pkg",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"wrapper.js",
|
||||
"stdlib.js",
|
||||
"lib.js",
|
||||
"metadata.js"
|
||||
],
|
||||
"types": "index.d.ts",
|
||||
"exports": {
|
||||
"import": "./index.js",
|
||||
"require": "./node/index.js"
|
||||
"node": "./node/index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"wasm-pack": "wasm-pack build --out-name index",
|
||||
"setup": "npm install && gulp setup",
|
||||
"prebuild": "npm run setup",
|
||||
"prebuild": "npm install",
|
||||
"build": "npm run build:bundler && npm run build:node",
|
||||
"prebuild:dev": "npm run setup",
|
||||
"build:dev": "npm run build:bundler:dev && npm run build:node:dev",
|
||||
"build:bundler": "rimraf pkg && npm run wasm-pack -- --target bundler --release && npm run clean-pkg",
|
||||
"build:bundler:dev": "rimraf pkg && npm run wasm-pack -- --target bundler --dev && npm run clean-pkg",
|
||||
"build:node": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --release && npm run clean-node-pkg",
|
||||
"build:node:dev": "rimraf node/pkg && npm run wasm-pack -- --target nodejs -d node/pkg --dev && npm run clean-node-pkg",
|
||||
"clean-pkg": "rimraf pkg/README.md pkg/.gitignore",
|
||||
"clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore",
|
||||
"pretest": "npm run setup && npm run build:node:dev",
|
||||
"clean-pkg": "rimraf pkg/README.md pkg/.gitignore pkg/package.json pkg/*.d.ts",
|
||||
"clean-node-pkg": "rimraf node/pkg/README.md node/pkg/.gitignore node/pkg/package.json node/pkg/*.d.ts",
|
||||
"pretest": "npm run build:node:dev",
|
||||
"test": "npm run run-tests",
|
||||
"run-tests": "mocha --timeout 100000 --require esm --recursive tests"
|
||||
"run-tests": "mocha --timeout 100000 --recursive tests"
|
||||
},
|
||||
"devDependencies": {
|
||||
"dree": "^2.6.1",
|
||||
"esm": "^3.2.25",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-cli": "^2.3.0",
|
||||
"mocha": "^9.2.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"serve": "^11.3.2",
|
||||
"snarkjs": "^0.4.19",
|
||||
"text-encoding": "^0.7.0",
|
||||
"toml": "^3.0.0",
|
||||
"wasm-pack": "^0.10.2"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
mod util;
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use crate::util::normalize_path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::to_string_pretty;
|
||||
use std::convert::TryFrom;
|
||||
use std::io::Cursor;
|
||||
use std::path::PathBuf;
|
||||
use std::io::{Cursor, Write};
|
||||
use std::path::{Component, PathBuf};
|
||||
use typed_arena::Arena;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use zokrates_abi::{parse_strict, Decode, Encode, Inputs};
|
||||
|
@ -11,8 +17,9 @@ use zokrates_ast::ir;
|
|||
use zokrates_ast::ir::ProgEnum;
|
||||
use zokrates_ast::typed::abi::Abi;
|
||||
use zokrates_ast::typed::types::{ConcreteSignature, ConcreteType, GTupleType};
|
||||
use zokrates_bellman::Bellman;
|
||||
use zokrates_circom::{write_r1cs, write_witness};
|
||||
use zokrates_common::helpers::{CurveParameter, SchemeParameter};
|
||||
use zokrates_common::helpers::{BackendParameter, CurveParameter, SchemeParameter};
|
||||
use zokrates_common::Resolver;
|
||||
use zokrates_core::compile::{
|
||||
compile as core_compile, CompilationArtifacts, CompileConfig, CompileError,
|
||||
|
@ -26,6 +33,11 @@ use zokrates_proof_systems::{
|
|||
UniversalBackend, UniversalScheme, GM17,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
static ref STDLIB: serde_json::Value =
|
||||
serde_json::from_str(include_str!(concat!(env!("OUT_DIR"), "/stdlib.json"))).unwrap();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct CompilationResult {
|
||||
program: Vec<u8>,
|
||||
|
@ -99,29 +111,107 @@ impl<'a> Resolver<Error> for JsResolver<'a> {
|
|||
current_location: PathBuf,
|
||||
import_location: PathBuf,
|
||||
) -> Result<(String, PathBuf), Error> {
|
||||
let value = self
|
||||
.callback
|
||||
.call2(
|
||||
let base: PathBuf = match import_location.components().next() {
|
||||
Some(Component::CurDir) | Some(Component::ParentDir) => {
|
||||
current_location.parent().unwrap().into()
|
||||
}
|
||||
_ => PathBuf::default(),
|
||||
};
|
||||
|
||||
let path = base.join(import_location.clone()).with_extension("zok");
|
||||
|
||||
match path.components().next() {
|
||||
Some(Component::Normal(_)) => {
|
||||
let path_normalized = normalize_path(path);
|
||||
let source = STDLIB
|
||||
.get(&path_normalized.to_str().unwrap())
|
||||
.ok_or_else(|| {
|
||||
Error::new(format!(
|
||||
"module `{}` not found in stdlib",
|
||||
import_location.display()
|
||||
))
|
||||
})?
|
||||
.as_str()
|
||||
.unwrap();
|
||||
|
||||
Ok((source.to_owned(), path_normalized))
|
||||
}
|
||||
_ => {
|
||||
let value = self
|
||||
.callback
|
||||
.call2(
|
||||
&JsValue::UNDEFINED,
|
||||
¤t_location.to_str().unwrap().into(),
|
||||
&import_location.to_str().unwrap().into(),
|
||||
)
|
||||
.map_err(|_| {
|
||||
Error::new(format!(
|
||||
"could not resolve module `{}`",
|
||||
import_location.display()
|
||||
))
|
||||
})?;
|
||||
|
||||
if value.is_null() || value.is_undefined() {
|
||||
return Err(Error::new(format!(
|
||||
"could not resolve module `{}`",
|
||||
import_location.display()
|
||||
)));
|
||||
}
|
||||
|
||||
let result: serde_json::Value = value.into_serde().unwrap();
|
||||
let source = result
|
||||
.get("source")
|
||||
.ok_or_else(|| Error::new("missing field `source`"))?
|
||||
.as_str()
|
||||
.ok_or_else(|| {
|
||||
Error::new("invalid type for field `source`, should be a string")
|
||||
})?;
|
||||
|
||||
let location = result
|
||||
.get("location")
|
||||
.ok_or_else(|| Error::new("missing field `location`"))?
|
||||
.as_str()
|
||||
.ok_or_else(|| {
|
||||
Error::new("invalid type for field `location`, should be a string")
|
||||
})?;
|
||||
|
||||
Ok((source.to_owned(), PathBuf::from(location.to_owned())))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LogWriter<'a> {
|
||||
buf: Vec<u8>,
|
||||
callback: &'a js_sys::Function,
|
||||
}
|
||||
|
||||
impl<'a> LogWriter<'a> {
|
||||
pub fn new(callback: &'a js_sys::Function) -> Self {
|
||||
Self {
|
||||
buf: Vec::default(),
|
||||
callback,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Write for LogWriter<'a> {
|
||||
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
|
||||
self.buf.write(buf)
|
||||
}
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
self.callback
|
||||
.call1(
|
||||
&JsValue::UNDEFINED,
|
||||
¤t_location.to_str().unwrap().into(),
|
||||
&import_location.to_str().unwrap().into(),
|
||||
&JsValue::from_str(
|
||||
std::str::from_utf8(&self.buf.as_slice()[..self.buf.len() - 1]).unwrap(),
|
||||
),
|
||||
)
|
||||
.map_err(|_| {
|
||||
Error::new(format!(
|
||||
"Could not resolve `{}`: error thrown in resolve callback",
|
||||
import_location.display()
|
||||
))
|
||||
std::io::Error::new(std::io::ErrorKind::Other, "unable to call log callback")
|
||||
})?;
|
||||
|
||||
if value.is_null() || value.is_undefined() {
|
||||
Err(Error::new(format!(
|
||||
"Could not resolve `{}`",
|
||||
import_location.display()
|
||||
)))
|
||||
} else {
|
||||
let result: ResolverResult = value.into_serde().unwrap();
|
||||
Ok((result.source, PathBuf::from(result.location)))
|
||||
}
|
||||
self.buf.clear();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -185,6 +275,7 @@ mod internal {
|
|||
abi: JsValue,
|
||||
args: JsValue,
|
||||
config: JsValue,
|
||||
log_callback: &js_sys::Function,
|
||||
) -> Result<ComputationResult, JsValue> {
|
||||
let input = args.as_string().unwrap();
|
||||
|
||||
|
@ -223,8 +314,9 @@ mod internal {
|
|||
|
||||
let public_inputs = program.public_inputs();
|
||||
|
||||
let mut writer = LogWriter::new(log_callback);
|
||||
let witness = interpreter
|
||||
.execute(program, &inputs.encode())
|
||||
.execute_with_log_stream(program, &inputs.encode(), &mut writer)
|
||||
.map_err(|err| JsValue::from_str(&format!("Execution failed: {}", err)))?;
|
||||
|
||||
let return_values: serde_json::Value =
|
||||
|
@ -371,15 +463,16 @@ pub fn compute_witness(
|
|||
abi: JsValue,
|
||||
args: JsValue,
|
||||
config: JsValue,
|
||||
log_callback: &js_sys::Function,
|
||||
) -> Result<ComputationResult, JsValue> {
|
||||
let prog = ir::ProgEnum::deserialize(program)
|
||||
.map_err(|err| JsValue::from_str(&err))?
|
||||
.collect();
|
||||
match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::compute::<_>(p, abi, args, config),
|
||||
ProgEnum::Bls12_381Program(p) => internal::compute::<_>(p, abi, args, config),
|
||||
ProgEnum::Bls12_377Program(p) => internal::compute::<_>(p, abi, args, config),
|
||||
ProgEnum::Bw6_761Program(p) => internal::compute::<_>(p, abi, args, config),
|
||||
ProgEnum::Bn128Program(p) => internal::compute::<_>(p, abi, args, config, log_callback),
|
||||
ProgEnum::Bls12_381Program(p) => internal::compute::<_>(p, abi, args, config, log_callback),
|
||||
ProgEnum::Bls12_377Program(p) => internal::compute::<_>(p, abi, args, config, log_callback),
|
||||
ProgEnum::Bw6_761Program(p) => internal::compute::<_>(p, abi, args, config, log_callback),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,6 +481,7 @@ pub fn export_solidity_verifier(vk: JsValue) -> Result<JsValue, JsValue> {
|
|||
let vk: serde_json::Value = vk
|
||||
.into_serde()
|
||||
.map_err(|e| JsValue::from_str(&e.to_string()))?;
|
||||
|
||||
let curve = CurveParameter::try_from(
|
||||
vk["curve"]
|
||||
.as_str()
|
||||
|
@ -419,6 +513,13 @@ pub fn export_solidity_verifier(vk: JsValue) -> Result<JsValue, JsValue> {
|
|||
pub fn setup(program: &[u8], options: JsValue) -> Result<JsValue, JsValue> {
|
||||
let options: serde_json::Value = options.into_serde().unwrap();
|
||||
|
||||
let backend = BackendParameter::try_from(
|
||||
options["backend"]
|
||||
.as_str()
|
||||
.ok_or_else(|| JsValue::from_str("Invalid options: missing field `backend`"))?,
|
||||
)
|
||||
.map_err(|e| JsValue::from_str(&e))?;
|
||||
|
||||
let scheme = SchemeParameter::try_from(
|
||||
options["scheme"]
|
||||
.as_str()
|
||||
|
@ -430,20 +531,27 @@ pub fn setup(program: &[u8], options: JsValue) -> Result<JsValue, JsValue> {
|
|||
.map_err(|err| JsValue::from_str(&err))?
|
||||
.collect();
|
||||
|
||||
match scheme {
|
||||
SchemeParameter::G16 => match prog {
|
||||
match (backend, scheme) {
|
||||
(BackendParameter::Bellman, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Bellman>(p)),
|
||||
ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str(
|
||||
"Not supported: https://github.com/Zokrates/ZoKrates/issues/1200",
|
||||
)),
|
||||
_ => Err(JsValue::from_str("Not supported")),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, G16, Ark>(p)),
|
||||
},
|
||||
SchemeParameter::GM17 => match prog {
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match prog {
|
||||
ProgEnum::Bn128Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bls12_381Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bls12_377Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
ProgEnum::Bw6_761Program(p) => Ok(internal::setup_non_universal::<_, GM17, Ark>(p)),
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported scheme")),
|
||||
_ => Err(JsValue::from_str("Unsupported options")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,6 +615,13 @@ pub fn generate_proof(
|
|||
) -> Result<JsValue, JsValue> {
|
||||
let options: serde_json::Value = options.into_serde().unwrap();
|
||||
|
||||
let backend = BackendParameter::try_from(
|
||||
options["backend"]
|
||||
.as_str()
|
||||
.ok_or_else(|| JsValue::from_str("Invalid options: missing field `backend`"))?,
|
||||
)
|
||||
.map_err(|e| JsValue::from_str(&e))?;
|
||||
|
||||
let scheme = SchemeParameter::try_from(
|
||||
options["scheme"]
|
||||
.as_str()
|
||||
|
@ -518,8 +633,17 @@ pub fn generate_proof(
|
|||
.map_err(|err| JsValue::from_str(&err))?
|
||||
.collect();
|
||||
|
||||
match scheme {
|
||||
SchemeParameter::G16 => match prog {
|
||||
match (backend, scheme) {
|
||||
(BackendParameter::Bellman, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => {
|
||||
internal::generate_proof::<_, G16, Bellman>(p, witness, pk)
|
||||
}
|
||||
ProgEnum::Bls12_381Program(_) => Err(JsValue::from_str(
|
||||
"Not supported: https://github.com/Zokrates/ZoKrates/issues/1200",
|
||||
)),
|
||||
_ => Err(JsValue::from_str("Not supported")),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::G16) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk),
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, G16, Ark>(p, witness, pk)
|
||||
|
@ -529,7 +653,7 @@ pub fn generate_proof(
|
|||
}
|
||||
ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, G16, Ark>(p, witness, pk),
|
||||
},
|
||||
SchemeParameter::GM17 => match prog {
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk),
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, GM17, Ark>(p, witness, pk)
|
||||
|
@ -539,7 +663,7 @@ pub fn generate_proof(
|
|||
}
|
||||
ProgEnum::Bw6_761Program(p) => internal::generate_proof::<_, GM17, Ark>(p, witness, pk),
|
||||
},
|
||||
SchemeParameter::MARLIN => match prog {
|
||||
(BackendParameter::Ark, SchemeParameter::MARLIN) => match prog {
|
||||
ProgEnum::Bn128Program(p) => internal::generate_proof::<_, Marlin, Ark>(p, witness, pk),
|
||||
ProgEnum::Bls12_381Program(p) => {
|
||||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
|
@ -551,11 +675,20 @@ pub fn generate_proof(
|
|||
internal::generate_proof::<_, Marlin, Ark>(p, witness, pk)
|
||||
}
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported options")),
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn verify(vk: JsValue, proof: JsValue) -> Result<JsValue, JsValue> {
|
||||
pub fn verify(vk: JsValue, proof: JsValue, options: JsValue) -> Result<JsValue, JsValue> {
|
||||
let options: serde_json::Value = options.into_serde().unwrap();
|
||||
let backend = BackendParameter::try_from(
|
||||
options["backend"]
|
||||
.as_str()
|
||||
.ok_or_else(|| JsValue::from_str("Invalid options: missing field `backend`"))?,
|
||||
)
|
||||
.map_err(|e| JsValue::from_str(&e))?;
|
||||
|
||||
let vk: serde_json::Value = vk.into_serde().unwrap();
|
||||
let proof: serde_json::Value = proof.into_serde().unwrap();
|
||||
let vk_curve = CurveParameter::try_from(
|
||||
|
@ -600,25 +733,33 @@ pub fn verify(vk: JsValue, proof: JsValue) -> Result<JsValue, JsValue> {
|
|||
let scheme = vk_scheme;
|
||||
let curve = vk_curve;
|
||||
|
||||
match scheme {
|
||||
SchemeParameter::G16 => match curve {
|
||||
match (backend, scheme) {
|
||||
(BackendParameter::Bellman, SchemeParameter::G16) => match curve {
|
||||
CurveParameter::Bn128 => internal::verify::<Bn128Field, G16, Bellman>(vk, proof),
|
||||
CurveParameter::Bls12_381 => Err(JsValue::from_str(
|
||||
"Not supported: https://github.com/Zokrates/ZoKrates/issues/1200",
|
||||
)),
|
||||
_ => Err(JsValue::from_str("Not supported")),
|
||||
},
|
||||
(BackendParameter::Ark, SchemeParameter::G16) => match curve {
|
||||
CurveParameter::Bn128 => internal::verify::<Bn128Field, G16, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_381 => internal::verify::<Bls12_381Field, G16, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_377 => internal::verify::<Bls12_377Field, G16, Ark>(vk, proof),
|
||||
CurveParameter::Bw6_761 => internal::verify::<Bw6_761Field, G16, Ark>(vk, proof),
|
||||
},
|
||||
SchemeParameter::GM17 => match curve {
|
||||
(BackendParameter::Ark, SchemeParameter::GM17) => match curve {
|
||||
CurveParameter::Bn128 => internal::verify::<Bn128Field, GM17, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_381 => internal::verify::<Bls12_381Field, GM17, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_377 => internal::verify::<Bls12_377Field, GM17, Ark>(vk, proof),
|
||||
CurveParameter::Bw6_761 => internal::verify::<Bw6_761Field, GM17, Ark>(vk, proof),
|
||||
},
|
||||
SchemeParameter::MARLIN => match curve {
|
||||
(BackendParameter::Ark, SchemeParameter::MARLIN) => match curve {
|
||||
CurveParameter::Bn128 => internal::verify::<Bn128Field, Marlin, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_381 => internal::verify::<Bls12_381Field, Marlin, Ark>(vk, proof),
|
||||
CurveParameter::Bls12_377 => internal::verify::<Bls12_377Field, Marlin, Ark>(vk, proof),
|
||||
CurveParameter::Bw6_761 => internal::verify::<Bw6_761Field, Marlin, Ark>(vk, proof),
|
||||
},
|
||||
_ => Err(JsValue::from_str("Unsupported options")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
zokrates_js/src/util.rs
Normal file
28
zokrates_js/src/util.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
use std::path::{Component, PathBuf};
|
||||
|
||||
pub fn normalize_path(path: PathBuf) -> PathBuf {
|
||||
let mut components = path.components().peekable();
|
||||
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
|
||||
components.next();
|
||||
PathBuf::from(c.as_os_str())
|
||||
} else {
|
||||
PathBuf::new()
|
||||
};
|
||||
|
||||
for component in components {
|
||||
match component {
|
||||
Component::Prefix(..) => unreachable!(),
|
||||
Component::RootDir => {
|
||||
ret.push(component.as_os_str());
|
||||
}
|
||||
Component::CurDir => {}
|
||||
Component::ParentDir => {
|
||||
ret.pop();
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
ret.push(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
|
@ -4,7 +4,7 @@ const fs = require("fs");
|
|||
const os = require("os");
|
||||
const dree = require("dree");
|
||||
const snarkjs = require("snarkjs");
|
||||
const { initialize } = require("../node/index.js");
|
||||
const { initialize, metadata } = require("../node/index.js");
|
||||
|
||||
let zokratesProvider;
|
||||
let tmpFolder;
|
||||
|
@ -14,9 +14,11 @@ describe("tests", () => {
|
|||
before(() => {
|
||||
return initialize().then((defaultProvider) => {
|
||||
zokratesProvider = defaultProvider;
|
||||
return fs.promises.mkdtemp(path.join(os.tmpdir(), path.sep)).then((folder) => {
|
||||
tmpFolder = folder;
|
||||
});
|
||||
return fs.promises
|
||||
.mkdtemp(path.join(os.tmpdir(), path.sep))
|
||||
.then((folder) => {
|
||||
tmpFolder = folder;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -24,14 +26,20 @@ describe("tests", () => {
|
|||
if (globalThis.curve_bn128) globalThis.curve_bn128.terminate();
|
||||
});
|
||||
|
||||
describe("metadata", () => {
|
||||
it("is present", () => {
|
||||
assert.ok(metadata);
|
||||
assert.ok(metadata.version !== undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("compilation", () => {
|
||||
it("should compile", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
|
||||
const artifacts = zokratesProvider.compile(
|
||||
"def main() -> field { return 42; }"
|
||||
);
|
||||
assert.ok(artifacts !== undefined);
|
||||
assert.ok(artifacts);
|
||||
assert.ok(artifacts.snarkjs === undefined);
|
||||
});
|
||||
});
|
||||
|
@ -42,7 +50,7 @@ describe("tests", () => {
|
|||
"def main() -> field { return 42; }",
|
||||
{ snarkjs: true }
|
||||
);
|
||||
assert.ok(artifacts !== undefined);
|
||||
assert.ok(artifacts);
|
||||
assert.ok(artifacts.snarkjs.program !== undefined);
|
||||
});
|
||||
});
|
||||
|
@ -52,11 +60,8 @@ describe("tests", () => {
|
|||
});
|
||||
|
||||
it("should resolve stdlib module", () => {
|
||||
const stdlib = require("../stdlib.js");
|
||||
assert.doesNotThrow(() => {
|
||||
const code = `import "${
|
||||
Object.keys(stdlib)[0]
|
||||
}" as func;\ndef main() { return; }`;
|
||||
const code = `import "utils/pack/bool/unpack" as unpack;\ndef main() { return; }`;
|
||||
zokratesProvider.compile(code);
|
||||
});
|
||||
});
|
||||
|
@ -64,7 +69,7 @@ describe("tests", () => {
|
|||
it("should resolve user module", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const code =
|
||||
'import "test" as test;\ndef main() -> field { return test(); }';
|
||||
'import "./test" as test;\ndef main() -> field { return test(); }';
|
||||
const options = {
|
||||
resolveCallback: (_, path) => {
|
||||
return {
|
||||
|
@ -80,7 +85,7 @@ describe("tests", () => {
|
|||
it("should throw on unresolved module", () => {
|
||||
assert.throws(() => {
|
||||
const code =
|
||||
'import "test" as test;\ndef main() -> field { return test(); }';
|
||||
'import "./test" as test;\ndef main() -> field { return test(); }';
|
||||
zokratesProvider.compile(code);
|
||||
});
|
||||
});
|
||||
|
@ -128,6 +133,22 @@ describe("tests", () => {
|
|||
zokratesProvider.computeWitness(artifacts, [true]);
|
||||
});
|
||||
});
|
||||
|
||||
it("should log in debug", () => {
|
||||
assert.doesNotThrow(() => {
|
||||
const code = 'def main() { log("{}", 1f); log("{}", 2f); return; }';
|
||||
const artifacts = zokratesProvider.compile(code, {
|
||||
config: { debug: true },
|
||||
});
|
||||
let logs = [];
|
||||
zokratesProvider.computeWitness(artifacts, [], {
|
||||
logCallback: (l) => {
|
||||
logs.push(l);
|
||||
},
|
||||
});
|
||||
assert.deepEqual(logs, ['"1"', '"2"']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const runWithOptions = (options) => {
|
||||
|
@ -224,10 +245,25 @@ describe("tests", () => {
|
|||
});
|
||||
};
|
||||
|
||||
for (const scheme of ["g16", "gm17", "marlin"]) {
|
||||
describe(scheme, () => {
|
||||
for (const curve of ["bn128", "bls12_381", "bls12_377", "bw6_761"]) {
|
||||
describe(curve, () => runWithOptions({ scheme, curve }));
|
||||
let combinations = {
|
||||
ark: {
|
||||
schemes: ["g16", "gm17", "marlin"],
|
||||
curves: ["bn128", "bls12_381", "bls12_377", "bw6_761"],
|
||||
},
|
||||
bellman: {
|
||||
schemes: ["g16"],
|
||||
curves: ["bn128"],
|
||||
},
|
||||
};
|
||||
|
||||
for (const backend of Object.keys(combinations)) {
|
||||
describe(backend, () => {
|
||||
for (const scheme of combinations[backend].schemes) {
|
||||
describe(scheme, () => {
|
||||
for (const curve of combinations[backend].curves) {
|
||||
describe(curve, () => runWithOptions({ backend, scheme, curve }));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_parser"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = ["JacobEberhardt <jacob.eberhardt@tu-berlin.de>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
### ZoKrates Ace Mode (Syntax Highlighting for Ace/Brace)
|
||||
|
||||
[Ace](https://ace.c9.io/) Edit Mode for [ZoKrates DSL](https://github.com/Zokrates/ZoKrates).
|
||||
Compatible with browserify version of the ace editor, [brace](https://www.npmjs.com/package/brace).
|
|
@ -1,121 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Distributed under the BSD license:
|
||||
*
|
||||
* Copyright (c) 2019, Ajax.org B.V.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Ajax.org B.V. nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
ace.define("ace/mode/zokrates_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var oop = acequire("../lib/oop");
|
||||
var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules;
|
||||
|
||||
var ZoKratesHighlightRules = function () {
|
||||
|
||||
var keywords = (
|
||||
"assert|as|bool|byte|const|def|do|else|endfor|export|false|field|for|if|then|fi|import|from|in|private|public|return|struct|true|type|u8|u16|u32|u64"
|
||||
);
|
||||
|
||||
var keywordMapper = this.createKeywordMapper({
|
||||
"keyword": keywords
|
||||
}, "identifier");
|
||||
|
||||
var decimalInteger = "(?:(?:[1-9]\\d*)|(?:0))";
|
||||
var decimalSuffix = "(?:_?(?:f|u(?:8|16|32|64)))?";
|
||||
var hexInteger = "(?:0[xX][\\dA-Fa-f]+)";
|
||||
var integer = "(?:" + decimalInteger + decimalSuffix + "|" + hexInteger + ")\\b";
|
||||
|
||||
this.$rules = {
|
||||
"start": [
|
||||
{
|
||||
token: "comment", // single line comment
|
||||
regex: "\\/\\/.*$"
|
||||
}, {
|
||||
token: "comment", // multi line comment
|
||||
regex: "\\/\\*",
|
||||
next: "comment"
|
||||
}, {
|
||||
token: "string", // single line
|
||||
regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
|
||||
}, {
|
||||
token: "constant.numeric", // integer
|
||||
regex: integer
|
||||
}, {
|
||||
token: keywordMapper,
|
||||
regex: "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
|
||||
}, {
|
||||
token: "keyword.operator",
|
||||
regex: "\\+|\\-|\\*\\*?|\\/|\\|\\|?|&&?|\\^|!|<<?|>>?|<=|=>|==|!=|="
|
||||
}, {
|
||||
token: "punctuation",
|
||||
regex: ",|:|;"
|
||||
}, {
|
||||
token: "lparen",
|
||||
regex: "[[({]"
|
||||
}, {
|
||||
token: "rparen",
|
||||
regex: "[\\])}]"
|
||||
}, {
|
||||
token: "text",
|
||||
regex: "\\s+"
|
||||
}
|
||||
],
|
||||
"comment": [
|
||||
{
|
||||
token: "comment", // closing comment
|
||||
regex: "\\*\\/",
|
||||
next: "start"
|
||||
}, {
|
||||
defaultToken: "comment"
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
oop.inherits(ZoKratesHighlightRules, TextHighlightRules);
|
||||
|
||||
exports.ZoKratesHighlightRules = ZoKratesHighlightRules;
|
||||
});
|
||||
|
||||
ace.define("ace/mode/zokrates",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/zokrates_highlight_rules"], function(acequire, exports, module) {
|
||||
"use strict";
|
||||
|
||||
var oop = acequire("../lib/oop");
|
||||
var TextMode = acequire("./text").Mode;
|
||||
var ZoKratesHighlightRules = acequire("./zokrates_highlight_rules").ZoKratesHighlightRules;
|
||||
|
||||
var Mode = function () {
|
||||
this.HighlightRules = ZoKratesHighlightRules;
|
||||
};
|
||||
oop.inherits(Mode, TextMode);
|
||||
|
||||
(function () {
|
||||
this.$id = "ace/mode/zokrates";
|
||||
}).call(Mode.prototype);
|
||||
|
||||
exports.Mode = Mode;
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"name": "ace-mode-zokrates",
|
||||
"version": "1.0.4",
|
||||
"description": "Ace Mode for ZoKrates DSL",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"zokrates",
|
||||
"ace",
|
||||
"mode",
|
||||
"brace"
|
||||
],
|
||||
"author": "Darko Macesic",
|
||||
"license": "LGPL"
|
||||
}
|
1
zokrates_parser/src/textmate/.gitignore
vendored
Normal file
1
zokrates_parser/src/textmate/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
*.tmLanguage.json
|
|
@ -1,36 +1,36 @@
|
|||
{
|
||||
"name": "zokrates",
|
||||
"displayName": "zokrates",
|
||||
"description": "Syntax highlighting for the ZoKrates language",
|
||||
"publisher": "zokrates",
|
||||
"repository": "https://github.com/ZoKrates/ZoKrates",
|
||||
"version": "0.0.2",
|
||||
"engines": {
|
||||
"vscode": "^1.53.0"
|
||||
},
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "zokrates",
|
||||
"aliases": [
|
||||
"ZoKrates",
|
||||
"zokrates"
|
||||
],
|
||||
"extensions": [
|
||||
".zok"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "zokrates",
|
||||
"scopeName": "source.zok",
|
||||
"path": "./syntaxes/zokrates.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
"name": "zokrates",
|
||||
"displayName": "zokrates",
|
||||
"description": "Syntax highlighting for the ZoKrates language",
|
||||
"publisher": "zokrates",
|
||||
"repository": "https://github.com/ZoKrates/ZoKrates",
|
||||
"version": "0.1.0",
|
||||
"engines": {
|
||||
"vscode": "^1.53.0"
|
||||
},
|
||||
"categories": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"contributes": {
|
||||
"languages": [
|
||||
{
|
||||
"id": "zokrates",
|
||||
"aliases": [
|
||||
"ZoKrates",
|
||||
"zokrates"
|
||||
],
|
||||
"extensions": [
|
||||
".zok"
|
||||
],
|
||||
"configuration": "./language-configuration.json"
|
||||
}
|
||||
],
|
||||
"grammars": [
|
||||
{
|
||||
"language": "zokrates",
|
||||
"scopeName": "source.zok",
|
||||
"path": "./syntaxes/zokrates.tmLanguage.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,637 +0,0 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
|
||||
"name": "ZoKrates",
|
||||
"fileTypes": [
|
||||
"zok"
|
||||
],
|
||||
"scopeName": "source.zok",
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "attributes",
|
||||
"name": "meta.attribute.zokrates",
|
||||
"begin": "(#)(\\!?)(\\[)",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.attribute.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "keyword.operator.attribute.inner.zokrates"
|
||||
},
|
||||
"3": {
|
||||
"name": "punctuation.brackets.attribute.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "\\]",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.brackets.attribute.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#functions"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "line comments",
|
||||
"name": "comment.line.double-slash.zokrates",
|
||||
"match": "\\s*//.*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"block-comments": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "empty block comments",
|
||||
"name": "comment.block.zokrates",
|
||||
"match": "/\\*\\*/"
|
||||
},
|
||||
{
|
||||
"comment": "block comments",
|
||||
"name": "comment.block.zokrates",
|
||||
"begin": "/\\*(?!\\*)",
|
||||
"end": "\\*/",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"constants": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "ALL CAPS constants",
|
||||
"name": "constant.other.caps.zokrates",
|
||||
"match": "\\b[A-Z]{2}[A-Z0-9_]*\\b"
|
||||
},
|
||||
{
|
||||
"comment": "decimal integers and floats",
|
||||
"name": "constant.numeric.decimal.zokrates",
|
||||
"match": "\\b\\d[\\d_]*(?:u128|u16|u32|u64|u8|f)?\\b"
|
||||
},
|
||||
{
|
||||
"comment": "hexadecimal integers",
|
||||
"name": "constant.numeric.hex.zokrates",
|
||||
"match": "\\b0x[\\da-fA-F_]+\\b"
|
||||
},
|
||||
{
|
||||
"comment": "booleans",
|
||||
"name": "constant.language.bool.zokrates",
|
||||
"match": "\\b(true|false)\\b"
|
||||
}
|
||||
]
|
||||
},
|
||||
"imports": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "explicit import statement",
|
||||
"name": "meta.import.explicit.zokrates",
|
||||
"match": "\\b(from)\\s+(\\\".*\\\")(import)\\s+([A-Za-z0-9_]+)\\s+((as)\\s+[A-Za-z0-9_]+)?\\b",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "main import statement",
|
||||
"name": "meta.import.explicit.zokrates",
|
||||
"match": "\\b(import)\\s+(\\\".*\\\")\\s+((as)\\s+[A-Za-z0-9_]+)?\\b",
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"constant-definitions": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "constant definition",
|
||||
"name": "constant.definition.zokrates",
|
||||
"match": "\\b(const)\\s+([A-Za-z0-9_]+)\\s+([A-Za-z0-9_]+)\\s+=\\s+(?:.+)\\b",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "keyword.other.const.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "entity.name.type.zokrates"
|
||||
},
|
||||
"3": {
|
||||
"name": "entity.name.constant.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"functions": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "function definition",
|
||||
"name": "meta.function.definition.zokrates",
|
||||
"begin": "\\b(def)\\s+([A-Za-z0-9_]+)((\\()|(<))",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "keyword.other.def.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "entity.name.function.zokrates"
|
||||
},
|
||||
"4": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
},
|
||||
"5": {
|
||||
"name": "punctuation.brackets.angle.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "\\:|;",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "keyword.punctuation.colon.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#functions"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "function/method calls, chaining",
|
||||
"name": "meta.function.call.zokrates",
|
||||
"begin": "([A-Za-z0-9_]+)(\\()",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "entity.name.function.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "\\)",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#functions"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "function/method calls with turbofish",
|
||||
"name": "meta.function.call.zokrates",
|
||||
"begin": "([A-Za-z0-9_]+)(?=::<.*>\\()",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "entity.name.function.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "\\)",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#constants"
|
||||
},
|
||||
{
|
||||
"include": "#functions"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#strings"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"keywords": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "argument visibility",
|
||||
"name": "keyword.visibility.zokrates",
|
||||
"match": "\\b(public|private)\\b"
|
||||
},
|
||||
{
|
||||
"comment": "control flow keywords",
|
||||
"name": "keyword.control.zokrates",
|
||||
"match": "\\b(do|else|for|do|endfor|if|then|fi|return|assert)\\b"
|
||||
},
|
||||
{
|
||||
"comment": "storage keywords",
|
||||
"name": "storage.type.zokrates",
|
||||
"match": "\\b(struct)\\b"
|
||||
},
|
||||
{
|
||||
"comment": "const",
|
||||
"name": "keyword.other.const.zokrates",
|
||||
"match": "\\bconst\\b"
|
||||
},
|
||||
{
|
||||
"comment": "def",
|
||||
"name": "keyword.other.def.zokrates",
|
||||
"match": "\\bdef\\b"
|
||||
},
|
||||
{
|
||||
"comment": "import keywords",
|
||||
"name": "keyword.other.import.zokrates",
|
||||
"match": "\\b(import|from|as)\\b"
|
||||
},
|
||||
{
|
||||
"comment": "logical operators",
|
||||
"name": "keyword.operator.logical.zokrates",
|
||||
"match": "(\\^|\\||\\|\\||&|&&|<<|>>|!)(?!=)"
|
||||
},
|
||||
{
|
||||
"comment": "single equal",
|
||||
"name": "keyword.operator.assignment.equal.zokrates",
|
||||
"match": "(?<![<>])=(?!=|>)"
|
||||
},
|
||||
{
|
||||
"comment": "comparison operators",
|
||||
"name": "keyword.operator.comparison.zokrates",
|
||||
"match": "(=(=)?(?!>)|!=|<=|(?<!=)>=)"
|
||||
},
|
||||
{
|
||||
"comment": "math operators",
|
||||
"name": "keyword.operator.math.zokrates",
|
||||
"match": "(([+%]|(\\*(?!\\w)))(?!=))|(-(?!>))|(/(?!/))"
|
||||
},
|
||||
{
|
||||
"comment": "less than, greater than (special case)",
|
||||
"match": "(?:\\b|(?:(\\))|(\\])|(\\})))[ \\t]+([<>])[ \\t]+(?:\\b|(?:(\\()|(\\[)|(\\{)))",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.brackets.square.zokrates"
|
||||
},
|
||||
"3": {
|
||||
"name": "punctuation.brackets.curly.zokrates"
|
||||
},
|
||||
"4": {
|
||||
"name": "keyword.operator.comparison.zokrates"
|
||||
},
|
||||
"5": {
|
||||
"name": "punctuation.brackets.round.zokrates"
|
||||
},
|
||||
"6": {
|
||||
"name": "punctuation.brackets.square.zokrates"
|
||||
},
|
||||
"7": {
|
||||
"name": "punctuation.brackets.curly.zokrates"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "dot access",
|
||||
"name": "keyword.operator.access.dot.zokrates",
|
||||
"match": "\\.(?!\\.)"
|
||||
},
|
||||
{
|
||||
"comment": "ranges, range patterns",
|
||||
"name": "keyword.operator.range.zokrates",
|
||||
"match": "\\.{2}(=|\\.)?"
|
||||
},
|
||||
{
|
||||
"comment": "colon",
|
||||
"name": "keyword.operator.colon.zokrates",
|
||||
"match": ":(?!:)"
|
||||
},
|
||||
{
|
||||
"comment": "dashrocket, skinny arrow",
|
||||
"name": "keyword.operator.arrow.skinny.zokrates",
|
||||
"match": "->"
|
||||
}
|
||||
]
|
||||
},
|
||||
"types": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "numeric types",
|
||||
"match": "(?<![A-Za-z])(u128|u16|u32|u64|u8|field)\\b",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "entity.name.type.numeric.zokrates"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "parameterized types",
|
||||
"begin": "\\b([A-Z][A-Za-z0-9]*)(<)",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "entity.name.type.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.brackets.angle.zokrates"
|
||||
}
|
||||
},
|
||||
"end": ">",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.brackets.angle.zokrates"
|
||||
}
|
||||
},
|
||||
"patterns": [
|
||||
{
|
||||
"include": "#block-comments"
|
||||
},
|
||||
{
|
||||
"include": "#comments"
|
||||
},
|
||||
{
|
||||
"include": "#keywords"
|
||||
},
|
||||
{
|
||||
"include": "#punctuation"
|
||||
},
|
||||
{
|
||||
"include": "#types"
|
||||
},
|
||||
{
|
||||
"include": "#variables"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "primitive types",
|
||||
"name": "entity.name.type.primitive.zokrates",
|
||||
"match": "\\b(bool)\\b"
|
||||
},
|
||||
{
|
||||
"comment": "struct declarations",
|
||||
"match": "\\b(struct)\\s+([A-Z][A-Za-z0-9]*)\\b",
|
||||
"captures": {
|
||||
"1": {
|
||||
"name": "storage.type.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "entity.name.type.struct.zokrates"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "types",
|
||||
"name": "entity.name.type.zokrates",
|
||||
"match": "\\b[A-Z][A-Za-z0-9]*\\b(?!!)"
|
||||
}
|
||||
]
|
||||
},
|
||||
"punctuation": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "comma",
|
||||
"name": "punctuation.comma.zokrates",
|
||||
"match": ","
|
||||
},
|
||||
{
|
||||
"comment": "parentheses, round brackets",
|
||||
"name": "punctuation.brackets.round.zokrates",
|
||||
"match": "[()]"
|
||||
},
|
||||
{
|
||||
"comment": "square brackets",
|
||||
"name": "punctuation.brackets.square.zokrates",
|
||||
"match": "[\\[\\]]"
|
||||
},
|
||||
{
|
||||
"comment": "angle brackets",
|
||||
"name": "punctuation.brackets.angle.zokrates",
|
||||
"match": "(?<!=)[<>]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"strings": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "double-quoted strings and byte strings",
|
||||
"name": "string.quoted.double.zokrates",
|
||||
"begin": "(b?)(\")",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "string.quoted.byte.raw.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.definition.string.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "\"",
|
||||
"endCaptures": {
|
||||
"0": {
|
||||
"name": "punctuation.definition.string.zokrates"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "double-quoted raw strings and raw byte strings",
|
||||
"name": "string.quoted.double.zokrates",
|
||||
"begin": "(b?r)(#*)(\")",
|
||||
"beginCaptures": {
|
||||
"1": {
|
||||
"name": "string.quoted.byte.raw.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.definition.string.raw.zokrates"
|
||||
},
|
||||
"3": {
|
||||
"name": "punctuation.definition.string.zokrates"
|
||||
}
|
||||
},
|
||||
"end": "(\")(\\2)",
|
||||
"endCaptures": {
|
||||
"1": {
|
||||
"name": "punctuation.definition.string.zokrates"
|
||||
},
|
||||
"2": {
|
||||
"name": "punctuation.definition.string.raw.zokrates"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"variables": {
|
||||
"patterns": [
|
||||
{
|
||||
"comment": "variables",
|
||||
"name": "variable.other.zokrates",
|
||||
"match": "\\b(?<!(?<!\\.)\\.)[a-z0-9_]+\\b"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -79,7 +79,7 @@ repository:
|
|||
-
|
||||
comment: 'decimal integers and floats'
|
||||
name: constant.numeric.decimal.zokrates
|
||||
match: '\b\d[\d_]*(?:u128|u16|u32|u64|u8|f)?\b'
|
||||
match: '\b\d[\d_]*(?:u16|u32|u64|u8|f)?\b'
|
||||
-
|
||||
comment: 'hexadecimal integers'
|
||||
name: constant.numeric.hex.zokrates
|
||||
|
@ -202,7 +202,7 @@ repository:
|
|||
-
|
||||
comment: 'control flow keywords'
|
||||
name: keyword.control.zokrates
|
||||
match: \b(for|in|do|endfor|if|then|else|fi|return|assert)\b
|
||||
match: \b(for|in|if|else|return|assert|log)\b
|
||||
-
|
||||
comment: 'storage keywords'
|
||||
name: storage.type.zokrates
|
||||
|
@ -227,6 +227,10 @@ repository:
|
|||
comment: 'logical operators'
|
||||
name: keyword.operator.logical.zokrates
|
||||
match: '(\^|\||\|\||&|&&|<<|>>|!)(?!=)'
|
||||
-
|
||||
comment: 'mut'
|
||||
name: "storage.modifier.mut.zokrates"
|
||||
match: \b(mut)\b
|
||||
-
|
||||
comment: 'single equal'
|
||||
name: keyword.operator.assignment.equal.zokrates
|
||||
|
@ -270,7 +274,7 @@ repository:
|
|||
patterns:
|
||||
-
|
||||
comment: 'numeric types'
|
||||
match: '(?<![A-Za-z])(u128|u16|u32|u64|u8|field)\b'
|
||||
match: '(?<![A-Za-z])(u16|u32|u64|u8|field)\b'
|
||||
captures:
|
||||
'1': {name: entity.name.type.numeric.zokrates}
|
||||
-
|
||||
|
@ -309,10 +313,18 @@ repository:
|
|||
comment: comma
|
||||
name: punctuation.comma.zokrates
|
||||
match: ','
|
||||
-
|
||||
comment: 'curly braces'
|
||||
name: punctuation.brackets.curly.zokrates
|
||||
match: '[{}]'
|
||||
-
|
||||
comment: 'parentheses, round brackets'
|
||||
name: punctuation.brackets.round.zokrates
|
||||
match: '[()]'
|
||||
-
|
||||
comment: 'semicolon'
|
||||
name: punctuation.semi.zokrates
|
||||
match: ';'
|
||||
-
|
||||
comment: 'square brackets'
|
||||
name: punctuation.brackets.square.zokrates
|
||||
|
|
|
@ -180,6 +180,6 @@ COMMENT = _{ ("/*" ~ (!"*/" ~ ANY)* ~ "*/") | ("//" ~ (!NEWLINE ~ ANY)*) }
|
|||
// the ordering of reserved keywords matters: if "as" is before "assert", then "assert" gets parsed as (as)(sert) and incorrectly
|
||||
// accepted
|
||||
keyword = @{
|
||||
"log"|"assert"|"as"|"bool"|"const"|"def"|"else"|"false"|"field"|"for"|"if"|"then"|"fi"|"import"|"from"|
|
||||
"in"|"mut"|"private"|"public"|"return"|"struct"|"true"|"u8"|"u16"|"u32"|"u64"
|
||||
"log"|"assert"|"as"|"bool"|"const"|"def"|"else"|"false"|"field"|"for"|"if"|"import"|"from"|
|
||||
"in"|"mut"|"private"|"public"|"return"|"struct"|"true"|"type"|"u8"|"u16"|"u32"|"u64"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "zokrates_stdlib"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
authors = ["Stefan Deml <stefandeml@gmail.com>", "schaeff <thibaut@schaeff.fr>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
5
zokrates_stdlib/stdlib/hashes/keccak/224bit.zok
Normal file
5
zokrates_stdlib/stdlib/hashes/keccak/224bit.zok
Normal file
|
@ -0,0 +1,5 @@
|
|||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def main<N>(u8[N] input) -> u8[28] {
|
||||
return keccak::<_, 28>(input, 0x01);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def keccak256<N>(u8[N] input) -> u64[4] {
|
||||
return keccak_u8::<_, 256>(input, 0x0000000000000001)[..4];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[4] {
|
||||
return keccak::<_, 256>(input, 0x0000000000000001)[..4];
|
||||
def main<N>(u8[N] input) -> u8[32] {
|
||||
return keccak::<_, 32>(input, 0x01);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def keccak384<N>(u8[N] input) -> u64[6] {
|
||||
return keccak_u8::<_, 384>(input, 0x0000000000000001)[..6];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[6] {
|
||||
return keccak::<_, 384>(input, 0x0000000000000001)[..6];
|
||||
def main<N>(u8[N] input) -> u8[48] {
|
||||
return keccak::<_, 48>(input, 0x01);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def keccak512<N>(u8[N] input) -> u64[8] {
|
||||
return keccak_u8::<_, 512>(input, 0x0000000000000001)[..8];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[8] {
|
||||
return keccak::<_, 512>(input, 0x0000000000000001)[..8];
|
||||
def main<N>(u8[N] input) -> u8[64] {
|
||||
return keccak::<_, 64>(input, 0x01);
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
// based on keccak-f[1600] permutation
|
||||
|
||||
import "utils/casts/u64_from_bits";
|
||||
import "utils/casts/u8_to_bits";
|
||||
import "utils/casts/u8_from_bits";
|
||||
import "utils/casts/u64_to_bits";
|
||||
import "utils/casts/u64_from_bits";
|
||||
|
||||
const u32[24] RHO = [
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
|
@ -10,19 +12,19 @@ const u32[24] RHO = [
|
|||
];
|
||||
|
||||
const u32[24] PI = [
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
];
|
||||
|
||||
const u64[24] RC = [
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
];
|
||||
|
||||
// left rotation
|
||||
|
@ -42,6 +44,10 @@ def keccakf(u64[25] mut st) -> u64[25] {
|
|||
u64[5] mut bc = [0; 5];
|
||||
u64 mut t = 0;
|
||||
|
||||
for u32 i in 0..25 {
|
||||
st[i] = swap_u64(st[i]);
|
||||
}
|
||||
|
||||
for u32 r in 0..24 {
|
||||
// theta
|
||||
for u32 i in 0..5 {
|
||||
|
@ -79,42 +85,15 @@ def keccakf(u64[25] mut st) -> u64[25] {
|
|||
// iota
|
||||
st[0] = st[0] ^ RC[r];
|
||||
}
|
||||
|
||||
for u32 i in 0..25 {
|
||||
st[i] = swap_u64(st[i]);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
def keccak<N, W>(u64[N] mut input, u64 pad) -> u64[25] {
|
||||
u64[25] mut q = [0; 25];
|
||||
u32 rate = (200 - (W / 4)) / 8;
|
||||
u32 mut pt = 0;
|
||||
|
||||
// change endianness of inputs from big endian to little endian
|
||||
for u32 i in 0..N {
|
||||
input[i] = swap_u64(input[i]);
|
||||
}
|
||||
|
||||
// update
|
||||
for u32 i in 0..N {
|
||||
q[pt] = q[pt] ^ input[i];
|
||||
pt = (pt + 1) % rate;
|
||||
q = pt == 0 ? keccakf(q) : q;
|
||||
}
|
||||
|
||||
pt = (pad & 0x00000000000000ff) != 0 ? pt : pt - 1;
|
||||
|
||||
// finalize
|
||||
q[pt] = q[pt] ^ pad;
|
||||
q[rate - 1] = q[rate - 1] ^ 0x8000000000000000;
|
||||
q = keccakf(q);
|
||||
|
||||
// change endianness of output from little endian to big endian
|
||||
for u32 i in 0..W/64 {
|
||||
q[i] = swap_u64(q[i]);
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
def u8_array_to_u64(u8[8] input) -> u64 {
|
||||
def u64_from_u8_array(u8[8] input) -> u64 {
|
||||
bool[64] bits = [
|
||||
...u8_to_bits(input[0]),
|
||||
...u8_to_bits(input[1]),
|
||||
|
@ -128,18 +107,55 @@ def u8_array_to_u64(u8[8] input) -> u64 {
|
|||
return u64_from_bits(bits);
|
||||
}
|
||||
|
||||
def main<N, W>(u8[N] input, u64 pad) -> u64[25] {
|
||||
u32 L = N / 8;
|
||||
u32 R = L * 8 == N ? 0 : 1;
|
||||
u32 len = L + R;
|
||||
def u64_to_u8_array(u64 input) -> u8[8] {
|
||||
bool[64] bits = u64_to_bits(input);
|
||||
return [
|
||||
u8_from_bits(bits[0..8]),
|
||||
u8_from_bits(bits[8..16]),
|
||||
u8_from_bits(bits[16..24]),
|
||||
u8_from_bits(bits[24..32]),
|
||||
u8_from_bits(bits[32..40]),
|
||||
u8_from_bits(bits[40..48]),
|
||||
u8_from_bits(bits[48..56]),
|
||||
u8_from_bits(bits[56..64])
|
||||
];
|
||||
}
|
||||
|
||||
u8[len * 8] padded = [...input, ...[0; len * 8 - N]];
|
||||
u64[len] mut input_u64 = [0; len];
|
||||
def to_bytes(u64[25] input) -> u8[200] {
|
||||
u8[200] mut output = [0; 200];
|
||||
for u32 i in 0..25 {
|
||||
u8[8] t = u64_to_u8_array(input[i]);
|
||||
for u32 j in 0..8 {
|
||||
output[i * 8 + j] = t[j];
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
for u32 i in 0..len {
|
||||
u32 j = i * 8;
|
||||
input_u64[i] = u8_array_to_u64(padded[j..j+8]);
|
||||
def from_bytes(u8[200] input) -> u64[25] {
|
||||
u64[25] mut output = [0; 25];
|
||||
for u32 i in 0..25 {
|
||||
output[i] = u64_from_u8_array(input[i*8..i*8+8]);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
def main<N, W>(u8[N] mut input, u8 delim) -> u8[W] {
|
||||
u8[200] mut b = [0; 200];
|
||||
u32 rate = 200 - (2 * W);
|
||||
u32 mut pt = 0;
|
||||
|
||||
// update
|
||||
for u32 i in 0..N {
|
||||
b[pt] = b[pt] ^ input[i];
|
||||
pt = (pt + 1) % rate;
|
||||
b = pt == 0 ? to_bytes(keccakf(from_bytes(b))) : b;
|
||||
}
|
||||
|
||||
return keccak::<_, W>(input_u64, pad << ((N % 8) * 8));
|
||||
// finalize
|
||||
b[pt] = b[pt] ^ delim;
|
||||
b[rate - 1] = b[rate - 1] ^ 0x80;
|
||||
b = to_bytes(keccakf(from_bytes(b)));
|
||||
|
||||
return b[..W];
|
||||
}
|
|
@ -7,7 +7,7 @@ const u32[8] IV = [
|
|||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||||
];
|
||||
|
||||
// A function that takes N u32[8] arrays as inputs, concatenates them,
|
||||
// A function that takes N u32[16] arrays as inputs, concatenates them,
|
||||
// and returns their sha256 compression as a u32[8].
|
||||
// Note: no padding is applied
|
||||
def main<N>(u32[N][16] a) -> u32[8] {
|
||||
|
|
5
zokrates_stdlib/stdlib/hashes/sha3/224bit.zok
Normal file
5
zokrates_stdlib/stdlib/hashes/sha3/224bit.zok
Normal file
|
@ -0,0 +1,5 @@
|
|||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def main<N>(u8[N] input) -> u8[28] {
|
||||
return keccak::<_, 28>(input, 0x06);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def sha3_256<N>(u8[N] input) -> u64[4] {
|
||||
return keccak_u8::<_, 256>(input, 0x0000000000000006)[..4];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[4] {
|
||||
return keccak::<_, 256>(input, 0x0000000000000006)[..4];
|
||||
def main<N>(u8[N] input) -> u8[32] {
|
||||
return keccak::<_, 32>(input, 0x06);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def sha3_384<N>(u8[N] input) -> u64[6] {
|
||||
return keccak_u8::<_, 384>(input, 0x0000000000000006)[..6];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[6] {
|
||||
return keccak::<_, 384>(input, 0x0000000000000006)[..6];
|
||||
def main<N>(u8[N] input) -> u8[48] {
|
||||
return keccak::<_, 48>(input, 0x06);
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
from "hashes/keccak/keccak" import keccak, main as keccak_u8;
|
||||
from "hashes/keccak/keccak" import main as keccak;
|
||||
|
||||
def sha3_512<N>(u8[N] input) -> u64[8] {
|
||||
return keccak_u8::<_, 512>(input, 0x0000000000000006)[..8];
|
||||
}
|
||||
|
||||
def main<N>(u64[N] input) -> u64[8] {
|
||||
return keccak::<_, 512>(input, 0x0000000000000006)[..8];
|
||||
def main<N>(u8[N] input) -> u8[64] {
|
||||
return keccak::<_, 64>(input, 0x06);
|
||||
}
|
15
zokrates_stdlib/tests/tests/hashes/keccak/224bit.json
Normal file
15
zokrates_stdlib/tests/tests/hashes/keccak/224bit.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/hashes/keccak/224bit.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
47
zokrates_stdlib/tests/tests/hashes/keccak/224bit.zok
Normal file
47
zokrates_stdlib/tests/tests/hashes/keccak/224bit.zok
Normal file
|
@ -0,0 +1,47 @@
|
|||
import "hashes/keccak/224bit" as keccak224;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
// >>> digest = keccak.new(digest_bits=224)
|
||||
// >>> digest.update(b'\x2a')
|
||||
// >>> digest.hexdigest()
|
||||
// '69d40b3f7b3118a1fb193b518a70f279348e4f0835553f37d85f436a'
|
||||
|
||||
u8[28] h1 = keccak224::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x69, 0xd4, 0x0b, 0x3f, 0x7b, 0x31, 0x18, 0xa1, 0xfb, 0x19, 0x3b, 0x51, 0x8a, 0x70,
|
||||
0xf2, 0x79, 0x34, 0x8e, 0x4f, 0x08, 0x35, 0x55, 0x3f, 0x37, 0xd8, 0x5f, 0x43, 0x6a
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
// >>> digest = keccak.new(digest_bits=224)
|
||||
// >>> digest.update(b'\x2a' * 8)
|
||||
// >>> digest.hexdigest()
|
||||
// '463b45a39816aeba7c62a75aed7acaaf11f7646217512a2f992ddce0'
|
||||
|
||||
u8[28] h2 = keccak224::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0x46, 0x3b, 0x45, 0xa3, 0x98, 0x16, 0xae, 0xba, 0x7c, 0x62, 0xa7, 0x5a, 0xed, 0x7a,
|
||||
0xca, 0xaf, 0x11, 0xf7, 0x64, 0x62, 0x17, 0x51, 0x2a, 0x2f, 0x99, 0x2d, 0xdc, 0xe0
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
// >>> input = "hello world".encode()
|
||||
// >>> input.hex()
|
||||
// '68656c6c6f20776f726c64'
|
||||
// >>> digest = keccak.new(digest_bits=224)
|
||||
// >>> digest.update(input)
|
||||
// >>> digest.hexdigest()
|
||||
// '25f3ecfebabe99686282f57f5c9e1f18244cfee2813d33f955aae568'
|
||||
|
||||
u8[28] h3 = keccak224::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x25, 0xf3, 0xec, 0xfe, 0xba, 0xbe, 0x99, 0x68, 0x62, 0x82, 0xf5, 0x7f, 0x5c, 0x9e,
|
||||
0x1f, 0x18, 0x24, 0x4c, 0xfe, 0xe2, 0x81, 0x3d, 0x33, 0xf9, 0x55, 0xaa, 0xe5, 0x68
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/keccak/256bit" import keccak256;
|
||||
import "hashes/keccak/256bit" as keccak256;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,8 +8,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '04994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829'
|
||||
|
||||
u64[4] h1 = keccak256::<1>([0x2a]);
|
||||
assert(h1 == [0x04994f67dc55b09e, 0x814ab7ffc8df3686, 0xb4afb2bb53e60eae, 0x97ef043fe03fb829]);
|
||||
u8[32] h1 = keccak256::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x04, 0x99, 0x4f, 0x67, 0xdc, 0x55, 0xb0, 0x9e, 0x81, 0x4a, 0xb7, 0xff, 0xc8, 0xdf, 0x36, 0x86,
|
||||
0xb4, 0xaf, 0xb2, 0xbb, 0x53, 0xe6, 0x0e, 0xae, 0x97, 0xef, 0x04, 0x3f, 0xe0, 0x3f, 0xb8, 0x29
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
|
@ -18,8 +21,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '4d57ecea94f7735c23ae7c02845a500a815c21fc6d6046d2d7d518fad6bebf89'
|
||||
|
||||
u64[4] h2 = keccak256::<8>([0x2a; 8]);
|
||||
assert(h2 == [0x4d57ecea94f7735c, 0x23ae7c02845a500a, 0x815c21fc6d6046d2, 0xd7d518fad6bebf89]);
|
||||
u8[32] h2 = keccak256::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0x4d, 0x57, 0xec, 0xea, 0x94, 0xf7, 0x73, 0x5c, 0x23, 0xae, 0x7c, 0x02, 0x84, 0x5a, 0x50, 0x0a,
|
||||
0x81, 0x5c, 0x21, 0xfc, 0x6d, 0x60, 0x46, 0xd2, 0xd7, 0xd5, 0x18, 0xfa, 0xd6, 0xbe, 0xbf, 0x89
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
|
@ -31,8 +37,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad'
|
||||
|
||||
u64[4] h3 = keccak256::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [0x47173285a8d7341e, 0x5e972fc677286384, 0xf802f8ef42a5ec5f, 0x03bbfa254cb01fad]);
|
||||
u8[32] h3 = keccak256::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x47, 0x17, 0x32, 0x85, 0xa8, 0xd7, 0x34, 0x1e, 0x5e, 0x97, 0x2f, 0xc6, 0x77, 0x28, 0x63, 0x84,
|
||||
0xf8, 0x02, 0xf8, 0xef, 0x42, 0xa5, 0xec, 0x5f, 0x03, 0xbb, 0xfa, 0x25, 0x4c, 0xb0, 0x1f, 0xad
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/keccak/384bit" import keccak384;
|
||||
import "hashes/keccak/384bit" as keccak384;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,10 +8,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '53403c11270822eebdccc9aca81e0582996de74333909598a4e4c409967fb9da14a1506264996c855eb5d9a42fd21a08'
|
||||
|
||||
u64[6] h1 = keccak384::<1>([0x2a]);
|
||||
u8[48] h1 = keccak384::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x53403c11270822ee, 0xbdccc9aca81e0582, 0x996de74333909598,
|
||||
0xa4e4c409967fb9da, 0x14a1506264996c85, 0x5eb5d9a42fd21a08
|
||||
0x53, 0x40, 0x3c, 0x11, 0x27, 0x08, 0x22, 0xee, 0xbd, 0xcc, 0xc9, 0xac, 0xa8, 0x1e, 0x05, 0x82,
|
||||
0x99, 0x6d, 0xe7, 0x43, 0x33, 0x90, 0x95, 0x98, 0xa4, 0xe4, 0xc4, 0x09, 0x96, 0x7f, 0xb9, 0xda,
|
||||
0x14, 0xa1, 0x50, 0x62, 0x64, 0x99, 0x6c, 0x85, 0x5e, 0xb5, 0xd9, 0xa4, 0x2f, 0xd2, 0x1a, 0x08
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -21,10 +22,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// 'ec7216058c28201daeb6fd1599b81fdbd40e229b31bea3b6b3190f21db81b01baf3d000e40801ab59551133efbac6cce'
|
||||
|
||||
u64[6] h2 = keccak384::<8>([0x2a; 8]);
|
||||
u8[48] h2 = keccak384::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0xec7216058c28201d, 0xaeb6fd1599b81fdb, 0xd40e229b31bea3b6,
|
||||
0xb3190f21db81b01b, 0xaf3d000e40801ab5, 0x9551133efbac6cce
|
||||
0xec, 0x72, 0x16, 0x05, 0x8c, 0x28, 0x20, 0x1d, 0xae, 0xb6, 0xfd, 0x15, 0x99, 0xb8, 0x1f, 0xdb,
|
||||
0xd4, 0x0e, 0x22, 0x9b, 0x31, 0xbe, 0xa3, 0xb6, 0xb3, 0x19, 0x0f, 0x21, 0xdb, 0x81, 0xb0, 0x1b,
|
||||
0xaf, 0x3d, 0x00, 0x0e, 0x40, 0x80, 0x1a, 0xb5, 0x95, 0x51, 0x13, 0x3e, 0xfb, 0xac, 0x6c, 0xce
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -37,10 +39,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '65fc99339a2a40e99d3c40d695b22f278853ca0f925cde4254bcae5e22ece47e6441f91b6568425adc9d95b0072eb49f'
|
||||
|
||||
u64[6] h3 = keccak384::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
u8[48] h3 = keccak384::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x65fc99339a2a40e9, 0x9d3c40d695b22f27, 0x8853ca0f925cde42,
|
||||
0x54bcae5e22ece47e, 0x6441f91b6568425a, 0xdc9d95b0072eb49f
|
||||
0x65, 0xfc, 0x99, 0x33, 0x9a, 0x2a, 0x40, 0xe9, 0x9d, 0x3c, 0x40, 0xd6, 0x95, 0xb2, 0x2f, 0x27,
|
||||
0x88, 0x53, 0xca, 0x0f, 0x92, 0x5c, 0xde, 0x42, 0x54, 0xbc, 0xae, 0x5e, 0x22, 0xec, 0xe4, 0x7e,
|
||||
0x64, 0x41, 0xf9, 0x1b, 0x65, 0x68, 0x42, 0x5a, 0xdc, 0x9d, 0x95, 0xb0, 0x07, 0x2e, 0xb4, 0x9f
|
||||
]);
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/keccak/512bit" import keccak512;
|
||||
import "hashes/keccak/512bit" as keccak512;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,10 +8,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// 'a470459552991801eca017c8bfeedb376469c9b642a2cca455a3271c5751ad3be53d9f4ddce99613515e954bd3d80d218a2f43f953141ec6bdcaf7ba4a4bad67'
|
||||
|
||||
u64[8] h1 = keccak512::<1>([0x2a]);
|
||||
u8[64] h1 = keccak512::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0xa470459552991801, 0xeca017c8bfeedb37, 0x6469c9b642a2cca4, 0x55a3271c5751ad3b,
|
||||
0xe53d9f4ddce99613, 0x515e954bd3d80d21, 0x8a2f43f953141ec6, 0xbdcaf7ba4a4bad67
|
||||
0xa4, 0x70, 0x45, 0x95, 0x52, 0x99, 0x18, 0x01, 0xec, 0xa0, 0x17, 0xc8, 0xbf, 0xee, 0xdb, 0x37,
|
||||
0x64, 0x69, 0xc9, 0xb6, 0x42, 0xa2, 0xcc, 0xa4, 0x55, 0xa3, 0x27, 0x1c, 0x57, 0x51, 0xad, 0x3b,
|
||||
0xe5, 0x3d, 0x9f, 0x4d, 0xdc, 0xe9, 0x96, 0x13, 0x51, 0x5e, 0x95, 0x4b, 0xd3, 0xd8, 0x0d, 0x21,
|
||||
0x8a, 0x2f, 0x43, 0xf9, 0x53, 0x14, 0x1e, 0xc6, 0xbd, 0xca, 0xf7, 0xba, 0x4a, 0x4b, 0xad, 0x67
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -21,10 +23,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '91e7b4ca7569fb43a180354878bcd807578e207c0dec866d7bc7569d86996a86bce7bd05ab32138797693e76882475a819352919cd81585110e5dfb1c8710337'
|
||||
|
||||
u64[8] h2 = keccak512::<8>([0x2a; 8]);
|
||||
u8[64] h2 = keccak512::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0x91e7b4ca7569fb43, 0xa180354878bcd807, 0x578e207c0dec866d, 0x7bc7569d86996a86,
|
||||
0xbce7bd05ab321387, 0x97693e76882475a8, 0x19352919cd815851, 0x10e5dfb1c8710337
|
||||
0x91, 0xe7, 0xb4, 0xca, 0x75, 0x69, 0xfb, 0x43, 0xa1, 0x80, 0x35, 0x48, 0x78, 0xbc, 0xd8, 0x07,
|
||||
0x57, 0x8e, 0x20, 0x7c, 0x0d, 0xec, 0x86, 0x6d, 0x7b, 0xc7, 0x56, 0x9d, 0x86, 0x99, 0x6a, 0x86,
|
||||
0xbc, 0xe7, 0xbd, 0x05, 0xab, 0x32, 0x13, 0x87, 0x97, 0x69, 0x3e, 0x76, 0x88, 0x24, 0x75, 0xa8,
|
||||
0x19, 0x35, 0x29, 0x19, 0xcd, 0x81, 0x58, 0x51, 0x10, 0xe5, 0xdf, 0xb1, 0xc8, 0x71, 0x03, 0x37
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -37,10 +41,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '3ee2b40047b8060f68c67242175660f4174d0af5c01d47168ec20ed619b0b7c42181f40aa1046f39e2ef9efc6910782a998e0013d172458957957fac9405b67d'
|
||||
|
||||
u64[8] h3 = keccak512::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
u8[64] h3 = keccak512::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x3ee2b40047b8060f, 0x68c67242175660f4, 0x174d0af5c01d4716, 0x8ec20ed619b0b7c4,
|
||||
0x2181f40aa1046f39, 0xe2ef9efc6910782a, 0x998e0013d1724589, 0x57957fac9405b67d
|
||||
0x3e, 0xe2, 0xb4, 0x00, 0x47, 0xb8, 0x06, 0x0f, 0x68, 0xc6, 0x72, 0x42, 0x17, 0x56, 0x60, 0xf4,
|
||||
0x17, 0x4d, 0x0a, 0xf5, 0xc0, 0x1d, 0x47, 0x16, 0x8e, 0xc2, 0x0e, 0xd6, 0x19, 0xb0, 0xb7, 0xc4,
|
||||
0x21, 0x81, 0xf4, 0x0a, 0xa1, 0x04, 0x6f, 0x39, 0xe2, 0xef, 0x9e, 0xfc, 0x69, 0x10, 0x78, 0x2a,
|
||||
0x99, 0x8e, 0x00, 0x13, 0xd1, 0x72, 0x45, 0x89, 0x57, 0x95, 0x7f, 0xac, 0x94, 0x05, 0xb6, 0x7d
|
||||
]);
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/keccak/keccak" import keccak;
|
||||
import "hashes/keccak/keccak";
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,8 +8,37 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// 'ca85d1976d40dcb6ca3becc8c6596e83c0774f4185cf016a05834f5856a37f39'
|
||||
|
||||
u64[4] h = keccak::<1, 256>([0x7a6f6b7261746573], 0x0000000000000001)[..4];
|
||||
assert(h == [0xca85d1976d40dcb6, 0xca3becc8c6596e83, 0xc0774f4185cf016a, 0x05834f5856a37f39]);
|
||||
u8[32] h1 = keccak::<_, 32>([0x7a, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x65, 0x73], 0x01);
|
||||
assert(h1 == [
|
||||
0xca, 0x85, 0xd1, 0x97, 0x6d, 0x40, 0xdc, 0xb6, 0xca, 0x3b, 0xec, 0xc8, 0xc6, 0x59, 0x6e, 0x83,
|
||||
0xc0, 0x77, 0x4f, 0x41, 0x85, 0xcf, 0x01, 0x6a, 0x05, 0x83, 0x4f, 0x58, 0x56, 0xa3, 0x7f, 0x39
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
// >>> digest = keccak.new(digest_bits=256)
|
||||
// >>> digest.update(b'\x2a' * 135)
|
||||
// >>> digest.hexdigest()
|
||||
// '723e2ae02ca8d8fb45dca21e5f6369c4f124da72f217dca5e657a4bbc69b917d'
|
||||
|
||||
u8[32] h2 = keccak::<_, 32>([0x2a; 135], 0x01);
|
||||
assert(h2 == [
|
||||
0x72, 0x3e, 0x2a, 0xe0, 0x2c, 0xa8, 0xd8, 0xfb, 0x45, 0xdc, 0xa2, 0x1e, 0x5f, 0x63, 0x69, 0xc4,
|
||||
0xf1, 0x24, 0xda, 0x72, 0xf2, 0x17, 0xdc, 0xa5, 0xe6, 0x57, 0xa4, 0xbb, 0xc6, 0x9b, 0x91, 0x7d
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import keccak
|
||||
// >>> digest = keccak.new(digest_bits=256)
|
||||
// >>> digest.update(b'\x2a' * 136)
|
||||
// >>> digest.hexdigest()
|
||||
// 'e60d5160227cb1b8dc8547deb9c6a2c5e6c3306a1ca155611a73ed2c2324bfc0'
|
||||
|
||||
u8[32] h3 = keccak::<_, 32>([0x2a; 136], 0x01);
|
||||
assert(h3 == [
|
||||
0xe6, 0x0d, 0x51, 0x60, 0x22, 0x7c, 0xb1, 0xb8, 0xdc, 0x85, 0x47, 0xde, 0xb9, 0xc6, 0xa2, 0xc5,
|
||||
0xe6, 0xc3, 0x30, 0x6a, 0x1c, 0xa1, 0x55, 0x61, 0x1a, 0x73, 0xed, 0x2c, 0x23, 0x24, 0xbf, 0xc0
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
15
zokrates_stdlib/tests/tests/hashes/sha3/224bit.json
Normal file
15
zokrates_stdlib/tests/tests/hashes/sha3/224bit.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"entry_point": "./tests/tests/hashes/sha3/224bit.zok",
|
||||
"tests": [
|
||||
{
|
||||
"input": {
|
||||
"values": []
|
||||
},
|
||||
"output": {
|
||||
"Ok": {
|
||||
"value": []
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
47
zokrates_stdlib/tests/tests/hashes/sha3/224bit.zok
Normal file
47
zokrates_stdlib/tests/tests/hashes/sha3/224bit.zok
Normal file
|
@ -0,0 +1,47 @@
|
|||
import "hashes/sha3/224bit" as sha3_224;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import SHA3_224
|
||||
// >>> digest = SHA3_224.new()
|
||||
// >>> digest.update(b'\x2a')
|
||||
// >>> digest.hexdigest()
|
||||
// 'b588579919b3947381b5d6260797296695f30ef82b5a204ec00840e5'
|
||||
|
||||
u8[28] h1 = sha3_224::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0xb5, 0x88, 0x57, 0x99, 0x19, 0xb3, 0x94, 0x73, 0x81, 0xb5, 0xd6, 0x26, 0x07, 0x97,
|
||||
0x29, 0x66, 0x95, 0xf3, 0x0e, 0xf8, 0x2b, 0x5a, 0x20, 0x4e, 0xc0, 0x08, 0x40, 0xe5
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import SHA3_224
|
||||
// >>> digest = SHA3_224.new()
|
||||
// >>> digest.update(b'\x2a' * 8)
|
||||
// >>> digest.hexdigest()
|
||||
// 'e6005b22af6b0f068cf6b158a607ad5ca1b21ca85f2470e6af4b4ca0'
|
||||
|
||||
u8[28] h2 = sha3_224::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0xe6, 0x00, 0x5b, 0x22, 0xaf, 0x6b, 0x0f, 0x06, 0x8c, 0xf6, 0xb1, 0x58, 0xa6, 0x07,
|
||||
0xad, 0x5c, 0xa1, 0xb2, 0x1c, 0xa8, 0x5f, 0x24, 0x70, 0xe6, 0xaf, 0x4b, 0x4c, 0xa0
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import SHA3_224
|
||||
// >>> input = "hello world".encode()
|
||||
// >>> input.hex()
|
||||
// '68656c6c6f20776f726c64'
|
||||
// >>> digest = SHA3_224.new()
|
||||
// >>> digest.update(input)
|
||||
// >>> digest.hexdigest()
|
||||
// 'dfb7f18c77e928bb56faeb2da27291bd790bc1045cde45f3210bb6c5'
|
||||
|
||||
u8[28] h3 = sha3_224::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0xdf, 0xb7, 0xf1, 0x8c, 0x77, 0xe9, 0x28, 0xbb, 0x56, 0xfa, 0xeb, 0x2d, 0xa2, 0x72,
|
||||
0x91, 0xbd, 0x79, 0x0b, 0xc1, 0x04, 0x5c, 0xde, 0x45, 0xf3, 0x21, 0x0b, 0xb6, 0xc5
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/sha3/256bit" import sha3_256;
|
||||
import "hashes/sha3/256bit" as sha3_256;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,8 +8,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '82283b4b030589a7aa0ca28b8e933ac0bd89738a0df509806c864366deec31d7'
|
||||
|
||||
u64[4] h1 = sha3_256::<1>([0x2a]);
|
||||
assert(h1 == [0x82283b4b030589a7, 0xaa0ca28b8e933ac0, 0xbd89738a0df50980, 0x6c864366deec31d7]);
|
||||
u8[32] h1 = sha3_256::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x82, 0x28, 0x3b, 0x4b, 0x03, 0x05, 0x89, 0xa7, 0xaa, 0x0c, 0xa2, 0x8b, 0x8e, 0x93, 0x3a, 0xc0,
|
||||
0xbd, 0x89, 0x73, 0x8a, 0x0d, 0xf5, 0x09, 0x80, 0x6c, 0x86, 0x43, 0x66, 0xde, 0xec, 0x31, 0xd7
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import SHA3_256
|
||||
|
@ -18,8 +21,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '02794645c5d54624a86e237cda0cbe980075f3908ccb00fd67befd2a0bbe0b35'
|
||||
|
||||
u64[4] h2 = sha3_256::<8>([0x2a; 8]);
|
||||
assert(h2 == [0x02794645c5d54624, 0xa86e237cda0cbe98, 0x0075f3908ccb00fd, 0x67befd2a0bbe0b35]);
|
||||
u8[32] h2 = sha3_256::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0x02, 0x79, 0x46, 0x45, 0xc5, 0xd5, 0x46, 0x24, 0xa8, 0x6e, 0x23, 0x7c, 0xda, 0x0c, 0xbe, 0x98,
|
||||
0x00, 0x75, 0xf3, 0x90, 0x8c, 0xcb, 0x00, 0xfd, 0x67, 0xbe, 0xfd, 0x2a, 0x0b, 0xbe, 0x0b, 0x35
|
||||
]);
|
||||
|
||||
// Python:
|
||||
// >>> from Crypto.Hash import SHA3_256
|
||||
|
@ -31,8 +37,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '644bcc7e564373040999aac89e7622f3ca71fba1d972fd94a31c3bfbf24e3938'
|
||||
|
||||
u64[4] h3 = sha3_256::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [0x644bcc7e56437304, 0x0999aac89e7622f3, 0xca71fba1d972fd94, 0xa31c3bfbf24e3938]);
|
||||
u8[32] h3 = sha3_256::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x64, 0x4b, 0xcc, 0x7e, 0x56, 0x43, 0x73, 0x04, 0x09, 0x99, 0xaa, 0xc8, 0x9e, 0x76, 0x22, 0xf3,
|
||||
0xca, 0x71, 0xfb, 0xa1, 0xd9, 0x72, 0xfd, 0x94, 0xa3, 0x1c, 0x3b, 0xfb, 0xf2, 0x4e, 0x39, 0x38
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/sha3/384bit" import sha3_384;
|
||||
import "hashes/sha3/384bit" as sha3_384;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,10 +8,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '386f0e977e65e7609217714a7cd450e145efbc645ad7c7c78d6c9f12b52cb4df22729b2330b7f5267bac9a5750d9130e'
|
||||
|
||||
u64[6] h1 = sha3_384::<1>([0x2a]);
|
||||
u8[48] h1 = sha3_384::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x386f0e977e65e760, 0x9217714a7cd450e1, 0x45efbc645ad7c7c7,
|
||||
0x8d6c9f12b52cb4df, 0x22729b2330b7f526, 0x7bac9a5750d9130e
|
||||
0x38, 0x6f, 0x0e, 0x97, 0x7e, 0x65, 0xe7, 0x60, 0x92, 0x17, 0x71, 0x4a, 0x7c, 0xd4, 0x50, 0xe1,
|
||||
0x45, 0xef, 0xbc, 0x64, 0x5a, 0xd7, 0xc7, 0xc7, 0x8d, 0x6c, 0x9f, 0x12, 0xb5, 0x2c, 0xb4, 0xdf,
|
||||
0x22, 0x72, 0x9b, 0x23, 0x30, 0xb7, 0xf5, 0x26, 0x7b, 0xac, 0x9a, 0x57, 0x50, 0xd9, 0x13, 0x0e
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -21,10 +22,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// 'b5e5109aa62d1633ca3b4c8fcf90b71192b7ebbca1159a65546be6bea5a53f748c513f97556e86d3516b3f9384ff4380'
|
||||
|
||||
u64[6] h2 = sha3_384::<8>([0x2a; 8]);
|
||||
u8[48] h2 = sha3_384::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0xb5e5109aa62d1633, 0xca3b4c8fcf90b711, 0x92b7ebbca1159a65,
|
||||
0x546be6bea5a53f74, 0x8c513f97556e86d3, 0x516b3f9384ff4380
|
||||
0xb5, 0xe5, 0x10, 0x9a, 0xa6, 0x2d, 0x16, 0x33, 0xca, 0x3b, 0x4c, 0x8f, 0xcf, 0x90, 0xb7, 0x11,
|
||||
0x92, 0xb7, 0xeb, 0xbc, 0xa1, 0x15, 0x9a, 0x65, 0x54, 0x6b, 0xe6, 0xbe, 0xa5, 0xa5, 0x3f, 0x74,
|
||||
0x8c, 0x51, 0x3f, 0x97, 0x55, 0x6e, 0x86, 0xd3, 0x51, 0x6b, 0x3f, 0x93, 0x84, 0xff, 0x43, 0x80
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -37,10 +39,11 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '83bff28dde1b1bf5810071c6643c08e5b05bdb836effd70b403ea8ea0a634dc4997eb1053aa3593f590f9c63630dd90b'
|
||||
|
||||
u64[6] h3 = sha3_384::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
u8[48] h3 = sha3_384::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x83bff28dde1b1bf5, 0x810071c6643c08e5, 0xb05bdb836effd70b,
|
||||
0x403ea8ea0a634dc4, 0x997eb1053aa3593f, 0x590f9c63630dd90b
|
||||
0x83, 0xbf, 0xf2, 0x8d, 0xde, 0x1b, 0x1b, 0xf5, 0x81, 0x00, 0x71, 0xc6, 0x64, 0x3c, 0x08, 0xe5,
|
||||
0xb0, 0x5b, 0xdb, 0x83, 0x6e, 0xff, 0xd7, 0x0b, 0x40, 0x3e, 0xa8, 0xea, 0x0a, 0x63, 0x4d, 0xc4,
|
||||
0x99, 0x7e, 0xb1, 0x05, 0x3a, 0xa3, 0x59, 0x3f, 0x59, 0x0f, 0x9c, 0x63, 0x63, 0x0d, 0xd9, 0x0b
|
||||
]);
|
||||
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from "hashes/sha3/512bit" import sha3_512;
|
||||
import "hashes/sha3/512bit" as sha3_512;
|
||||
|
||||
def main() {
|
||||
// Python:
|
||||
|
@ -8,10 +8,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '0f8e235b563113abb8a914eb6efc4a31280f1d2341920dfb88bdd20a00d7e47d601a353e5821142acf0dd9ec53bfe4bfe9a2a16f98933142e1c6938c8939b3a0'
|
||||
|
||||
u64[8] h1 = sha3_512::<1>([0x2a]);
|
||||
u8[64] h1 = sha3_512::<1>([0x2a]);
|
||||
assert(h1 == [
|
||||
0x0f8e235b563113ab, 0xb8a914eb6efc4a31, 0x280f1d2341920dfb, 0x88bdd20a00d7e47d,
|
||||
0x601a353e5821142a, 0xcf0dd9ec53bfe4bf, 0xe9a2a16f98933142, 0xe1c6938c8939b3a0
|
||||
0x0f, 0x8e, 0x23, 0x5b, 0x56, 0x31, 0x13, 0xab, 0xb8, 0xa9, 0x14, 0xeb, 0x6e, 0xfc, 0x4a, 0x31,
|
||||
0x28, 0x0f, 0x1d, 0x23, 0x41, 0x92, 0x0d, 0xfb, 0x88, 0xbd, 0xd2, 0x0a, 0x00, 0xd7, 0xe4, 0x7d,
|
||||
0x60, 0x1a, 0x35, 0x3e, 0x58, 0x21, 0x14, 0x2a, 0xcf, 0x0d, 0xd9, 0xec, 0x53, 0xbf, 0xe4, 0xbf,
|
||||
0xe9, 0xa2, 0xa1, 0x6f, 0x98, 0x93, 0x31, 0x42, 0xe1, 0xc6, 0x93, 0x8c, 0x89, 0x39, 0xb3, 0xa0
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -21,10 +23,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '5e908c2962bcd38fddd1ae4ed4c44eb3396cad53eb36564881979435e18a8e71eda1cbea2fe0fc6ded0672756312b12f8dad38e7528af173ea10095a28cd5555'
|
||||
|
||||
u64[8] h2 = sha3_512::<8>([0x2a; 8]);
|
||||
u8[64] h2 = sha3_512::<8>([0x2a; 8]);
|
||||
assert(h2 == [
|
||||
0x5e908c2962bcd38f, 0xddd1ae4ed4c44eb3, 0x396cad53eb365648, 0x81979435e18a8e71,
|
||||
0xeda1cbea2fe0fc6d, 0xed0672756312b12f, 0x8dad38e7528af173, 0xea10095a28cd5555
|
||||
0x5e, 0x90, 0x8c, 0x29, 0x62, 0xbc, 0xd3, 0x8f, 0xdd, 0xd1, 0xae, 0x4e, 0xd4, 0xc4, 0x4e, 0xb3,
|
||||
0x39, 0x6c, 0xad, 0x53, 0xeb, 0x36, 0x56, 0x48, 0x81, 0x97, 0x94, 0x35, 0xe1, 0x8a, 0x8e, 0x71,
|
||||
0xed, 0xa1, 0xcb, 0xea, 0x2f, 0xe0, 0xfc, 0x6d, 0xed, 0x06, 0x72, 0x75, 0x63, 0x12, 0xb1, 0x2f,
|
||||
0x8d, 0xad, 0x38, 0xe7, 0x52, 0x8a, 0xf1, 0x73, 0xea, 0x10, 0x09, 0x5a, 0x28, 0xcd, 0x55, 0x55
|
||||
]);
|
||||
|
||||
// Python:
|
||||
|
@ -37,10 +41,12 @@ def main() {
|
|||
// >>> digest.hexdigest()
|
||||
// '840006653e9ac9e95117a15c915caab81662918e925de9e004f774ff82d7079a40d4d27b1b372657c61d46d470304c88c788b3a4527ad074d1dccbee5dbaa99a'
|
||||
|
||||
u64[8] h3 = sha3_512::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
u8[64] h3 = sha3_512::<11>([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
|
||||
assert(h3 == [
|
||||
0x840006653e9ac9e9, 0x5117a15c915caab8, 0x1662918e925de9e0, 0x04f774ff82d7079a,
|
||||
0x40d4d27b1b372657, 0xc61d46d470304c88, 0xc788b3a4527ad074, 0xd1dccbee5dbaa99a
|
||||
0x84, 0x00, 0x06, 0x65, 0x3e, 0x9a, 0xc9, 0xe9, 0x51, 0x17, 0xa1, 0x5c, 0x91, 0x5c, 0xaa, 0xb8,
|
||||
0x16, 0x62, 0x91, 0x8e, 0x92, 0x5d, 0xe9, 0xe0, 0x04, 0xf7, 0x74, 0xff, 0x82, 0xd7, 0x07, 0x9a,
|
||||
0x40, 0xd4, 0xd2, 0x7b, 0x1b, 0x37, 0x26, 0x57, 0xc6, 0x1d, 0x46, 0xd4, 0x70, 0x30, 0x4c, 0x88,
|
||||
0xc7, 0x88, 0xb3, 0xa4, 0x52, 0x7a, 0xd0, 0x74, 0xd1, 0xdc, 0xcb, 0xee, 0x5d, 0xba, 0xa9, 0x9a
|
||||
]);
|
||||
|
||||
return;
|
||||
|
|
Loading…
Reference in a new issue