clean
This commit is contained in:
parent
8d9064797c
commit
fc8de3e1f2
25 changed files with 394 additions and 3378 deletions
|
@ -18,9 +18,6 @@ jobs:
|
|||
- run:
|
||||
name: Version information
|
||||
command: rustc --version; cargo --version; rustup --version
|
||||
- run:
|
||||
name: Calculate dependencies
|
||||
command: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
keys:
|
||||
- cargo-cache-{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
|
@ -37,15 +34,12 @@ jobs:
|
|||
test:
|
||||
docker:
|
||||
- image: zokrates/env:latest
|
||||
resource_class: large
|
||||
resource_class: xlarge
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Version information
|
||||
command: rustc --version; cargo --version; rustup --version
|
||||
- run:
|
||||
name: Calculate dependencies
|
||||
command: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
keys:
|
||||
- cargo-cache-{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
|
@ -58,9 +52,6 @@ jobs:
|
|||
- run:
|
||||
name: Run tests
|
||||
command: WITH_LIBSNARK=1 RUSTFLAGS="-D warnings" ./test.sh
|
||||
# - run:
|
||||
# name: Generate code coverage report
|
||||
# command: ./scripts/cov.sh
|
||||
cpp_format:
|
||||
docker:
|
||||
- image: zokrates/env:latest
|
||||
|
@ -77,9 +68,6 @@ jobs:
|
|||
- run:
|
||||
name: Version information
|
||||
command: rustc --version; cargo --version; rustup --version
|
||||
- run:
|
||||
name: Calculate dependencies
|
||||
command: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
keys:
|
||||
- cargo-cache-{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
|
@ -98,9 +86,6 @@ jobs:
|
|||
- run:
|
||||
name: Version information
|
||||
command: rustc --version; cargo --version; rustup --version
|
||||
- run:
|
||||
name: Calculate dependencies
|
||||
command: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
keys:
|
||||
- cargo-cache-{{ .Environment.CACHE_VERSION }}-{{ arch }}-{{ checksum "Cargo.lock" }}
|
||||
|
@ -160,9 +145,6 @@ jobs:
|
|||
executor: << parameters.os >>
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Calculate dependencies
|
||||
command: cargo generate-lockfile
|
||||
- when:
|
||||
condition: << parameters.add-target >>
|
||||
steps:
|
||||
|
|
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -3010,6 +3010,7 @@ dependencies = [
|
|||
"log",
|
||||
"primitive-types",
|
||||
"rand 0.4.6",
|
||||
"rand 0.8.5",
|
||||
"regex 0.2.11",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
|
@ -3169,7 +3170,7 @@ dependencies = [
|
|||
"ethabi",
|
||||
"hex 0.4.3",
|
||||
"primitive-types",
|
||||
"rand 0.4.6",
|
||||
"rand 0.8.5",
|
||||
"revm",
|
||||
"serde_json",
|
||||
"solc",
|
||||
|
|
|
@ -28,7 +28,8 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
dirs = "3.0.1"
|
||||
lazy_static = "1.4.0"
|
||||
byteorder = "1"
|
||||
rand = "0.4"
|
||||
rand_0_4 = { version = "0.4", package = "rand" }
|
||||
rand_0_8 = { version = "0.8", package = "rand" }
|
||||
hex = "0.3.1"
|
||||
blake2 = "0.8.1"
|
||||
sha2 = "0.10.0"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
use fs_extra::copy_items;
|
||||
use fs_extra::dir::CopyOptions;
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
// export js test folder to OUT_DIR
|
||||
export_stdlib();
|
||||
}
|
||||
|
||||
fn export_stdlib() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let mut options = CopyOptions::new();
|
||||
options.overwrite = true;
|
||||
copy_items(&["tests/contract"], out_dir, &options).unwrap();
|
||||
}
|
|
@ -53,9 +53,6 @@ fn cli_inspect<T: Field, I: Iterator<Item = ir::Statement<T>>>(
|
|||
let curve = format!("{:<17} {}", "curve:", T::name());
|
||||
let constraint_count = format!("{:<17} {}", "constraint_count:", ir_prog.constraint_count());
|
||||
|
||||
println!("{}", curve);
|
||||
println!("{}", constraint_count);
|
||||
|
||||
if sub_matches.is_present("ztf") {
|
||||
let output_path =
|
||||
PathBuf::from(sub_matches.value_of("input").unwrap()).with_extension("ztf");
|
||||
|
|
|
@ -87,8 +87,8 @@ fn cli_mpc_beacon<T: Field + BellmanFieldExtensions, S: MpcScheme<T>, B: MpcBack
|
|||
// Create an RNG based on the outcome of the random beacon
|
||||
let mut rng = {
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use rand::chacha::ChaChaRng;
|
||||
use rand::SeedableRng;
|
||||
use rand_0_4::chacha::ChaChaRng;
|
||||
use rand_0_4::SeedableRng;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
// The hash used for the beacon
|
||||
|
|
|
@ -76,8 +76,8 @@ pub fn cli_mpc_contribute<
|
|||
let mut rng = {
|
||||
use blake2::{Blake2b, Digest};
|
||||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
use rand::chacha::ChaChaRng;
|
||||
use rand::{OsRng, Rng, SeedableRng};
|
||||
use rand_0_4::chacha::ChaChaRng;
|
||||
use rand_0_4::{OsRng, Rng, SeedableRng};
|
||||
|
||||
let h = {
|
||||
let mut system_rng = OsRng::new().unwrap();
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use crate::constants::{self, JSON_PROOF_PATH};
|
||||
use crate::helpers::{CurveParameter, SchemeParameter};
|
||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||
use serde_json::Value;
|
||||
use std::convert::TryInto;
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use zokrates_core::proof_system::{
|
||||
marlin, Backend, Marlin, Proof, Scheme, SolidityCompatibleField, SolidityCompatibleScheme, G16,
|
||||
GM17, PGHR13,
|
||||
Marlin, Proof, SolidityCompatibleField, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
};
|
||||
use zokrates_field::{Bls12_381Field, Bn128Field, Field};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
pub fn subcommand() -> App<'static, 'static> {
|
||||
SubCommand::with_name("print-proof")
|
||||
|
@ -32,17 +30,19 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
.help("Format in which the proof should be printed")
|
||||
.takes_value(true)
|
||||
.possible_values(&["remix", "json"])
|
||||
.required(true),
|
||||
.required(true)
|
||||
.default_value("remix"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("proving-scheme")
|
||||
.short("s")
|
||||
.long("proving-scheme")
|
||||
.help("Proving scheme to use in the setup. Available options are G16 (default), PGHR13 and GM17")
|
||||
.help("Proving scheme the proof was created with")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
.default_value(constants::G16)
|
||||
.possible_values(constants::SCHEMES)
|
||||
.default_value(constants::G16),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("curve")
|
||||
|
@ -52,7 +52,7 @@ pub fn subcommand() -> App<'static, 'static> {
|
|||
.takes_value(true)
|
||||
.required(false)
|
||||
.possible_values(constants::CURVES)
|
||||
.default_value(constants::BN128)
|
||||
.default_value(constants::BN128),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -63,18 +63,6 @@ pub fn exec(sub_matches: &ArgMatches) -> Result<(), String> {
|
|||
let parameters: (CurveParameter, SchemeParameter) =
|
||||
(curve.try_into().unwrap(), scheme.try_into().unwrap());
|
||||
|
||||
println!(
|
||||
"Printing proof at location {:?} using proving scheme {:?} and curve {:?}",
|
||||
sub_matches
|
||||
.values_of("proof-path")
|
||||
.clone()
|
||||
.unwrap()
|
||||
.next()
|
||||
.unwrap(),
|
||||
parameters.1,
|
||||
parameters.0
|
||||
);
|
||||
|
||||
match parameters {
|
||||
(CurveParameter::Bn128, SchemeParameter::PGHR13) => {
|
||||
cli_print_proof::<Bn128Field, PGHR13>(sub_matches)
|
||||
|
@ -110,26 +98,25 @@ fn cli_print_proof<T: SolidityCompatibleField, S: SolidityCompatibleScheme<T>>(
|
|||
|
||||
match format {
|
||||
"json" => {
|
||||
println!("~~~~~~~~ Copy the output below for valid ABIv2 format ~~~~~~~~");
|
||||
println!();
|
||||
print!("{}", inputs);
|
||||
print!("{}", proof_object);
|
||||
print!(",");
|
||||
println!("{}", proof_object);
|
||||
print!("{}", inputs);
|
||||
println!();
|
||||
println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
}
|
||||
"remix" => {
|
||||
println!("~~~~~~~~ Copy the output below for valid ABIv1 format ~~~~~~~~");
|
||||
print!(
|
||||
"[{}]",
|
||||
proof_object
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|(_, value)| value.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
print!(",");
|
||||
print!("{}", inputs);
|
||||
println!();
|
||||
|
||||
for (_, value) in proof_object.as_object().unwrap().iter() {
|
||||
print!("{}", value);
|
||||
print!(",");
|
||||
}
|
||||
|
||||
println!("{}", inputs);
|
||||
println!();
|
||||
println!("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
1
zokrates_cli/tests/contract/.gitignore
vendored
1
zokrates_cli/tests/contract/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
node_modules
|
2752
zokrates_cli/tests/contract/package-lock.json
generated
2752
zokrates_cli/tests/contract/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "zokrates-solidity-tester",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "test.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Paul Etscheit",
|
||||
"license": "LGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"solc": "0.8.0",
|
||||
"web3": "^1.0.0"
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
var fs = require("fs");
|
||||
let Web3 = require('web3');
|
||||
const solc = require('solc');
|
||||
const contractPath = process.argv[2]
|
||||
const proofPath = process.argv[3]
|
||||
const format = process.argv[4]
|
||||
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
|
||||
|
||||
const source = fs.readFileSync(contractPath, 'UTF-8');
|
||||
let jsonContractSource = {
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
[contractPath]: {
|
||||
content: source,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true
|
||||
},
|
||||
outputSelection: {
|
||||
[contractPath]: {
|
||||
"Verifier": ['abi', "evm.bytecode"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
(async () => {
|
||||
const accounts = await web3.eth.getAccounts();
|
||||
|
||||
// The BN256G2 library needs to be deployed and linked separately
|
||||
// because it has `public` functions.
|
||||
// This is not needed for the Pairing library because all its functions
|
||||
// are `internal` and therefore are compiled into the contract that uses it.
|
||||
if (format == "gm17") {
|
||||
let library = await deployLibrary();
|
||||
jsonContractSource.settings.libraries = {
|
||||
[contractPath]: {
|
||||
BN256G2: library["_address"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----Compile contract-----
|
||||
let jsonInterface = JSON.parse(solc.compile(JSON.stringify(jsonContractSource)));
|
||||
console.log(jsonInterface);
|
||||
|
||||
let abi = jsonInterface.contracts[contractPath]["Verifier"].abi;
|
||||
let bytecode = jsonInterface.contracts[contractPath]["Verifier"].evm.bytecode;
|
||||
|
||||
let contract = new web3.eth.Contract(abi)
|
||||
.deploy({
|
||||
data: '0x' + bytecode.object
|
||||
})
|
||||
.send({
|
||||
from: accounts[0],
|
||||
gas: '20000000'
|
||||
})
|
||||
.on('receipt', (tx) => {
|
||||
if (tx.status == true) {
|
||||
console.log("Contract Deployed! Gas used: " + tx.gasUsed);
|
||||
}
|
||||
})
|
||||
.then(newContractInstance => {
|
||||
contract = newContractInstance;
|
||||
Promise.all([makeTransaction(accounts[0], true)]);
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
function makeTransaction(account, correct) {
|
||||
let proof = getProof(correct);
|
||||
|
||||
function handleReceipt(tx) {
|
||||
if (tx.status == true && !correct) {
|
||||
console.log("Verification has been successful with invalid proof data! THIS IS A BUG");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (tx.status == true) {
|
||||
console.log("Correct proof works! Gas used: " + tx.gasUsed);
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(err, correct) {
|
||||
if (!correct) {
|
||||
console.log("False proof not verified! Success");
|
||||
} else {
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("PROOF:", proof)
|
||||
|
||||
verifyTx(proof, account, correct).on('receipt', handleReceipt)
|
||||
.catch(handleError);
|
||||
}
|
||||
|
||||
function verifyTx(proof, account, correct) {
|
||||
var args = proof[0];
|
||||
args = proof[1].length > 0 ? [args, proof[1]] : [args];
|
||||
|
||||
console.log(args);
|
||||
|
||||
return contract.methods.verifyTx(...args).send({
|
||||
from: account,
|
||||
gas: '20000000'
|
||||
});
|
||||
}
|
||||
|
||||
function getProof(correct) {
|
||||
let json = JSON.parse(fs.readFileSync(proofPath));
|
||||
let inputs = json["inputs"];
|
||||
let proof = json["proof"];
|
||||
//falsifies proof to check if verification fails
|
||||
if (!correct) {
|
||||
proof["a"][0] = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
|
||||
}
|
||||
return [Object.values(proof), Object.values(inputs)];
|
||||
}
|
||||
|
||||
//function used for deploying BN256G2 Library, used for gm17 only
|
||||
function deployLibrary() {
|
||||
let jsonContractSourceBin = JSON.stringify({
|
||||
language: 'Solidity',
|
||||
sources: {
|
||||
["BN256G2"]: {
|
||||
content: source,
|
||||
},
|
||||
},
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true
|
||||
},
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': ['abi', "evm.bytecode"],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
let jsonInterfaceBin = JSON.parse(solc.compile(jsonContractSourceBin));
|
||||
let abiLib = jsonInterfaceBin.contracts["BN256G2"]["BN256G2"].abi;
|
||||
let bytecodeLib = jsonInterfaceBin.contracts["BN256G2"]['BN256G2'].evm.bytecode;
|
||||
return new web3.eth.Contract(abiLib)
|
||||
.deploy({
|
||||
data: '0x' + bytecodeLib.object
|
||||
})
|
||||
.send({
|
||||
from: accounts[0],
|
||||
gas: '2000000'
|
||||
})
|
||||
.on('receipt', (tx) => {
|
||||
if (tx.status == false) {
|
||||
console.log("Library couldn't be deployed");
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
|
@ -1,7 +1,8 @@
|
|||
extern crate assert_cli;
|
||||
extern crate ethabi;
|
||||
extern crate primitive_types;
|
||||
extern crate rand;
|
||||
extern crate rand_0_4;
|
||||
extern crate rand_0_8;
|
||||
extern crate serde_json;
|
||||
extern crate zokrates_solidity_test;
|
||||
|
||||
|
@ -10,7 +11,7 @@ mod integration {
|
|||
|
||||
use glob::glob;
|
||||
use primitive_types::U256;
|
||||
use serde_json::{from_reader, json};
|
||||
use serde_json::from_reader;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
|
@ -18,10 +19,9 @@ mod integration {
|
|||
use std::path::Path;
|
||||
use tempdir::TempDir;
|
||||
use zokrates_abi::{parse_strict, Encode};
|
||||
use zokrates_core::proof_system::marlin::SolidityProof;
|
||||
use zokrates_core::proof_system::{
|
||||
Fr, G1Affine, Marlin, Proof, Scheme, SolidityCompatibleField, SolidityCompatibleScheme,
|
||||
ToToken, G16, GM17, PGHR13, SOLIDITY_G2_ADDITION_LIB,
|
||||
to_token::ToToken, Marlin, Proof, SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
SOLIDITY_G2_ADDITION_LIB,
|
||||
};
|
||||
use zokrates_core::typed_absy::abi::Abi;
|
||||
use zokrates_field::Bn128Field;
|
||||
|
@ -38,11 +38,8 @@ mod integration {
|
|||
);
|
||||
|
||||
#[test]
|
||||
//#[ignore]
|
||||
#[ignore]
|
||||
fn test_compile_and_witness_dir() {
|
||||
// install nodejs dependencies for the verification contract tester
|
||||
install_nodejs_deps();
|
||||
|
||||
let global_dir = TempDir::new("global").unwrap();
|
||||
let global_base = global_dir.path();
|
||||
let universal_setup_path = global_base.join("universal_setup.dat");
|
||||
|
@ -84,15 +81,6 @@ mod integration {
|
|||
}
|
||||
}
|
||||
|
||||
fn install_nodejs_deps() {
|
||||
let out_dir = concat!(env!("OUT_DIR"), "/contract");
|
||||
|
||||
// assert_cli::Assert::command(&["npm", "install"])
|
||||
// .current_dir(out_dir)
|
||||
// .succeeds()
|
||||
// .unwrap();
|
||||
}
|
||||
|
||||
fn test_compile_and_witness(
|
||||
program_name: &str,
|
||||
program_path: &Path,
|
||||
|
@ -388,11 +376,11 @@ mod integration {
|
|||
proof: Proof<Bn128Field, S>,
|
||||
) {
|
||||
use ethabi::Token;
|
||||
use rand::{SeedableRng, StdRng};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use zokrates_solidity_test::{address::*, contract::*, evm::*, to_be_bytes};
|
||||
|
||||
// Setup EVM
|
||||
let mut rng = StdRng::from_seed(&[0]);
|
||||
let mut rng = StdRng::from_seed([0; 32]);
|
||||
let mut evm = Evm::new();
|
||||
let deployer = Address::random(&mut rng);
|
||||
evm.create_account(&deployer, 0);
|
||||
|
@ -430,7 +418,7 @@ mod integration {
|
|||
let solidity_proof = S::Proof::from(proof.proof);
|
||||
|
||||
// convert to tokens to build a call
|
||||
let proof_token = S::to_token(solidity_proof);
|
||||
let proof_token = S::to_token(solidity_proof.clone());
|
||||
|
||||
let input_token = Token::FixedArray(
|
||||
proof
|
||||
|
@ -444,7 +432,7 @@ mod integration {
|
|||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let inputs = [proof_token, input_token];
|
||||
let inputs = [proof_token, input_token.clone()];
|
||||
|
||||
// Call verify function on contract
|
||||
let result = evm
|
||||
|
@ -456,7 +444,28 @@ mod integration {
|
|||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(&result.out, &to_be_bytes(&U256::from(1)));
|
||||
|
||||
// modify the proof
|
||||
let modified_solidity_proof = S::modify(solidity_proof.clone());
|
||||
|
||||
let modified_proof_token = S::to_token(modified_solidity_proof.clone());
|
||||
|
||||
let inputs = [modified_proof_token, input_token.clone()];
|
||||
|
||||
// Call verify function on contract
|
||||
let result = evm
|
||||
.call(
|
||||
contract
|
||||
.encode_call_contract_bytes("verifyTx", &inputs)
|
||||
.unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(result.op_out, Return::InvalidOpcode);
|
||||
}
|
||||
|
||||
fn test_compile_and_smtlib2(
|
||||
|
|
|
@ -7,7 +7,7 @@ use ark_marlin::Marlin as ArkMarlin;
|
|||
|
||||
use ark_ec::PairingEngine;
|
||||
use ark_ff::{to_bytes, FftField, FromBytes, ToBytes};
|
||||
use ark_poly::{univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain};
|
||||
use ark_poly::univariate::DensePolynomial;
|
||||
use ark_poly_commit::{
|
||||
data_structures::BatchLCProof,
|
||||
kzg10::Commitment as KZG10Commitment,
|
||||
|
@ -17,10 +17,8 @@ use ark_poly_commit::{
|
|||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use digest::Digest;
|
||||
use num::Zero;
|
||||
use rand_0_8::{Error, RngCore, SeedableRng};
|
||||
use sha3::Keccak256;
|
||||
use std::convert::TryInto;
|
||||
use std::{convert::TryFrom, marker::PhantomData};
|
||||
|
||||
use zokrates_field::{ArkFieldExtensions, Field};
|
||||
|
|
|
@ -5,6 +5,8 @@ pub mod bellman;
|
|||
#[cfg(feature = "libsnark")]
|
||||
pub mod libsnark;
|
||||
|
||||
pub mod to_token;
|
||||
|
||||
mod scheme;
|
||||
mod solidity;
|
||||
|
||||
|
@ -13,7 +15,6 @@ pub use self::solidity::*;
|
|||
|
||||
use crate::ir;
|
||||
|
||||
use primitive_types::U256;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::{Bls12_377Field, Bls12_381Field, Bn128Field, Field};
|
||||
|
@ -94,31 +95,6 @@ impl ToString for G2Affine {
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper methods for parsing group structure
|
||||
pub fn encode_g1_element(g: &G1Affine) -> (U256, U256) {
|
||||
(
|
||||
U256::from(&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_g2_element(g: &G2Affine) -> ((U256, U256), (U256, U256)) {
|
||||
(
|
||||
(
|
||||
U256::from(&hex::decode(&g.0 .0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.0 .1.trim_start_matches("0x")).unwrap()[..]),
|
||||
),
|
||||
(
|
||||
U256::from(&hex::decode(&g.1 .0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.1 .1.trim_start_matches("0x")).unwrap()[..]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_fr_element(f: &Fr) -> U256 {
|
||||
U256::from(&hex::decode(&f.trim_start_matches("0x")).unwrap()[..])
|
||||
}
|
||||
|
||||
pub trait Backend<T: Field, S: Scheme<T>> {
|
||||
fn generate_proof<I: IntoIterator<Item = ir::Statement<T>>>(
|
||||
program: ir::ProgIterator<T, I>,
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::proof_system::scheme::{NonUniversalScheme, Scheme};
|
||||
use crate::proof_system::solidity::{solidity_pairing_lib, SOLIDITY_G2_ADDITION_LIB};
|
||||
use crate::proof_system::{
|
||||
encode_g1_element, encode_g2_element, G1Affine, G2Affine, G2AffineFq, NotBw6_761Field,
|
||||
SolidityCompatibleField, SolidityCompatibleScheme, ToToken,
|
||||
G1Affine, G2Affine, G2AffineFq, NotBw6_761Field, SolidityCompatibleField,
|
||||
SolidityCompatibleScheme,
|
||||
};
|
||||
use ethabi::Token;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::{Bw6_761Field, Field};
|
||||
|
@ -12,7 +11,7 @@ use zokrates_field::{Bw6_761Field, Field};
|
|||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct GM17;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ProofPoints<G1, G2> {
|
||||
pub a: G1,
|
||||
pub b: G2,
|
||||
|
@ -43,32 +42,6 @@ impl Scheme<Bw6_761Field> for GM17 {
|
|||
type ProofPoints = ProofPoints<G1Affine, G2AffineFq>;
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field> ToToken<T> for GM17 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, b, c];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> for GM17 {
|
||||
type Proof = Self::ProofPoints;
|
||||
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
use crate::proof_system::scheme::{NonUniversalScheme, Scheme};
|
||||
use crate::proof_system::solidity::solidity_pairing_lib;
|
||||
use crate::proof_system::{
|
||||
encode_g1_element, encode_g2_element, G1Affine, G2Affine, MpcScheme, SolidityCompatibleField,
|
||||
SolidityCompatibleScheme, ToToken,
|
||||
G1Affine, G2Affine, MpcScheme, SolidityCompatibleField, SolidityCompatibleScheme,
|
||||
};
|
||||
use ethabi::Token;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub struct G16;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ProofPoints<G1, G2> {
|
||||
pub a: G1,
|
||||
pub b: G2,
|
||||
|
@ -35,32 +33,6 @@ impl<T: Field> Scheme<T> for G16 {
|
|||
impl<T: Field> NonUniversalScheme<T> for G16 {}
|
||||
impl<T: Field> MpcScheme<T> for G16 {}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for G16 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, b, c];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> SolidityCompatibleScheme<T> for G16 {
|
||||
type Proof = Self::ProofPoints;
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
use crate::proof_system::ark::parse_fr;
|
||||
use crate::proof_system::scheme::{Scheme, UniversalScheme};
|
||||
use crate::proof_system::solidity::{
|
||||
solidity_pairing_lib, SolidityCompatibleField, SolidityCompatibleScheme,
|
||||
};
|
||||
use crate::proof_system::{
|
||||
encode_fr_element, encode_g1_element, Fr, G1Affine, G2Affine, NotBw6_761Field, ToToken,
|
||||
};
|
||||
use ethabi::Token;
|
||||
use crate::proof_system::{Fr, G1Affine, G2Affine, NotBw6_761Field};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::{ArkFieldExtensions, Field};
|
||||
use zokrates_field::Field;
|
||||
|
||||
pub struct Marlin;
|
||||
|
||||
|
@ -22,7 +18,7 @@ pub struct ProofPoints<Fr, G1> {
|
|||
pub prover_messages_count: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct SolidityProof<Fr, G1> {
|
||||
pub comms_1: Vec<G1>,
|
||||
pub comms_2: Vec<G1>,
|
||||
|
@ -90,86 +86,7 @@ impl<T: Field> Scheme<T> for Marlin {
|
|||
|
||||
impl<T: Field> UniversalScheme<T> for Marlin {}
|
||||
|
||||
impl<T: SolidityCompatibleField + ArkFieldExtensions + NotBw6_761Field> ToToken<T> for Marlin {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let comms_1_token = Token::Array(
|
||||
proof
|
||||
.comms_1
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let comms_2_token = Token::Array(
|
||||
proof
|
||||
.comms_2
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_2_g1_token = {
|
||||
let (x, y) = encode_g1_element(&proof.degree_bound_comms_2_g1);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let comms_3_token = Token::Array(
|
||||
proof
|
||||
.comms_3
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_3_g2_token = {
|
||||
let (x, y) = encode_g1_element(&proof.degree_bound_comms_3_g2);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let evals_token = Token::Array(
|
||||
proof
|
||||
.evals
|
||||
.into_iter()
|
||||
.map(|f| encode_fr_element(&f))
|
||||
.map(Token::Uint)
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let pc_lc_opening_1_token = {
|
||||
let (x, y) = encode_g1_element(&proof.batch_lc_proof_1);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let degree_bound_pc_lc_opening_1_token =
|
||||
Token::Uint(encode_fr_element(&proof.batch_lc_proof_1_r));
|
||||
|
||||
let pc_lc_opening_2_token = {
|
||||
let (x, y) = encode_g1_element(&proof.batch_lc_proof_2);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![
|
||||
comms_1_token,
|
||||
comms_2_token,
|
||||
degree_bound_comms_2_g1_token,
|
||||
comms_3_token,
|
||||
degree_bound_comms_3_g2_token,
|
||||
evals_token,
|
||||
pc_lc_opening_1_token,
|
||||
degree_bound_pc_lc_opening_1_token,
|
||||
pc_lc_opening_2_token,
|
||||
];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field + ArkFieldExtensions> SolidityCompatibleScheme<T>
|
||||
for Marlin
|
||||
{
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> for Marlin {
|
||||
type Proof = SolidityProof<Fr, G1Affine>;
|
||||
|
||||
fn export_solidity_verifier(vk: <Marlin as Scheme<T>>::VerificationKey) -> String {
|
||||
|
@ -770,123 +687,95 @@ contract Verifier {
|
|||
mod tests {
|
||||
use crate::flat_absy::{FlatParameter, FlatVariable};
|
||||
use crate::ir::{Interpreter, Prog, QuadComb, Statement};
|
||||
use crate::proof_system::ark::{parse_fr, Ark};
|
||||
use crate::proof_system::{Backend, Fr, Proof, UniversalBackend};
|
||||
use crate::proof_system::ark::Ark;
|
||||
use crate::proof_system::to_token::ToToken;
|
||||
use crate::proof_system::{Backend, UniversalBackend};
|
||||
|
||||
use super::*;
|
||||
use ethabi::token::{LenientTokenizer, StrictTokenizer, Tokenizer};
|
||||
use ethabi::Token;
|
||||
use primitive_types::{H160, U256};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_solidity_test::{address::Address, contract::Contract, evm::Evm, to_be_bytes};
|
||||
|
||||
#[test]
|
||||
fn verify_solidity_bn128() {
|
||||
// let program: Prog<Bn128Field> = Prog {
|
||||
// arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
// return_count: 1,
|
||||
// statements: vec![
|
||||
// Statement::constraint(
|
||||
// QuadComb::from_linear_combinations(
|
||||
// FlatVariable::new(0).into(),
|
||||
// FlatVariable::new(0).into(),
|
||||
// ),
|
||||
// FlatVariable::new(1),
|
||||
// ),
|
||||
// Statement::constraint(FlatVariable::new(1), FlatVariable::public(0)),
|
||||
// ],
|
||||
// };
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
arguments: vec![FlatParameter::private(FlatVariable::new(0))],
|
||||
return_count: 1,
|
||||
statements: vec![
|
||||
Statement::constraint(
|
||||
QuadComb::from_linear_combinations(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::new(0).into(),
|
||||
),
|
||||
FlatVariable::new(1),
|
||||
),
|
||||
Statement::constraint(FlatVariable::new(1), FlatVariable::public(0)),
|
||||
],
|
||||
};
|
||||
|
||||
// let srs = <Ark as UniversalBackend<Bn128Field, Marlin>>::universal_setup(5);
|
||||
// let keypair =
|
||||
// <Ark as UniversalBackend<Bn128Field, Marlin>>::setup(srs, program.clone().into())
|
||||
// .unwrap();
|
||||
// let interpreter = Interpreter::default();
|
||||
let srs = <Ark as UniversalBackend<Bn128Field, Marlin>>::universal_setup(5);
|
||||
let keypair =
|
||||
<Ark as UniversalBackend<Bn128Field, Marlin>>::setup(srs, program.clone().into())
|
||||
.unwrap();
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
// let witness = interpreter
|
||||
// .execute(program.clone(), &[Bn128Field::from(42u32)])
|
||||
// .unwrap();
|
||||
let witness = interpreter
|
||||
.execute(program.clone(), &[Bn128Field::from(42u32)])
|
||||
.unwrap();
|
||||
|
||||
// let proof = <Ark as Backend<Bn128Field, Marlin>>::generate_proof(
|
||||
// program.clone(),
|
||||
// witness,
|
||||
// keypair.pk,
|
||||
// );
|
||||
let proof = <Ark as Backend<Bn128Field, Marlin>>::generate_proof(
|
||||
program.clone(),
|
||||
witness,
|
||||
keypair.pk,
|
||||
);
|
||||
|
||||
// let mut src =
|
||||
// <Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
|
||||
// src = src.replace("\"", "\\\"");
|
||||
let src =
|
||||
<Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
|
||||
|
||||
// let solc_config = r#"
|
||||
// {
|
||||
// "language": "Solidity",
|
||||
// "sources": {
|
||||
// "input.sol": { "content": "<%src%>" }
|
||||
// },
|
||||
// "settings": {
|
||||
// "optimizer": { "enabled": <%opt%> },
|
||||
// "outputSelection": {
|
||||
// "*": {
|
||||
// "*": [
|
||||
// "evm.bytecode.object", "abi"
|
||||
// ],
|
||||
// "": [ "*" ] } }
|
||||
// }
|
||||
// }"#
|
||||
// .replace("<%opt%>", &true.to_string())
|
||||
// .replace("<%src%>", &src);
|
||||
let contract = Contract::compile_from_src_string(&src, "Verifier", true, &[]).unwrap();
|
||||
|
||||
// let contract = Contract::compile_from_config(&solc_config, "Verifier").unwrap();
|
||||
// Setup EVM
|
||||
let mut evm = Evm::new();
|
||||
let deployer = Address::from(H160::zero());
|
||||
evm.create_account(&deployer, 0);
|
||||
|
||||
// // Setup EVM
|
||||
// let mut rng = StdRng::seed_from_u64(0u64);
|
||||
// let mut evm = Evm::new();
|
||||
// let deployer = Address::from(H160::zero());
|
||||
// evm.create_account(&deployer, 0);
|
||||
// Deploy contract
|
||||
let create_result = evm
|
||||
.deploy(
|
||||
contract.encode_create_contract_bytes(&[]).unwrap(),
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
let contract_addr = create_result.addr.clone();
|
||||
|
||||
// // Deploy contract
|
||||
// let create_result = evm
|
||||
// .deploy(
|
||||
// contract.encode_create_contract_bytes(&[]).unwrap(),
|
||||
// &deployer,
|
||||
// )
|
||||
// .unwrap();
|
||||
// let contract_addr = create_result.addr.clone();
|
||||
// //println!("Contract deploy gas cost: {}", create_result.gas);
|
||||
let solidity_proof =
|
||||
<Marlin as SolidityCompatibleScheme<Bn128Field>>::Proof::from(proof.proof);
|
||||
let proof_token = <Marlin as ToToken<Bn128Field>>::to_token(solidity_proof);
|
||||
|
||||
// let solidity_proof =
|
||||
// <Marlin as SolidityCompatibleScheme<Bn128Field>>::Proof::from(proof.proof);
|
||||
// let proof_token = <Marlin as ToToken<Bn128Field>>::to_token(solidity_proof);
|
||||
let input_token = Token::FixedArray(
|
||||
proof
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let bytes = hex::decode(s.trim_start_matches("0x")).unwrap();
|
||||
debug_assert_eq!(bytes.len(), 32);
|
||||
Token::Uint(U256::from(&bytes[..]))
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
let inputs = [proof_token, input_token];
|
||||
|
||||
// println!("{:?}", proof.inputs);
|
||||
|
||||
// let input_token = Token::FixedArray(
|
||||
// proof
|
||||
// .inputs
|
||||
// .iter()
|
||||
// .map(|s| {
|
||||
// let bytes = hex::decode(s.trim_start_matches("0x")).unwrap();
|
||||
// debug_assert_eq!(bytes.len(), 32);
|
||||
// Token::Uint(U256::from(&bytes[..]))
|
||||
// })
|
||||
// .collect::<Vec<_>>(),
|
||||
// );
|
||||
// let inputs = [proof_token, input_token];
|
||||
|
||||
// println!("{:?}", inputs);
|
||||
|
||||
// // Call verify function on contract
|
||||
// let result = evm
|
||||
// .call(
|
||||
// contract
|
||||
// .encode_call_contract_bytes("verifyTx", &inputs)
|
||||
// .unwrap(),
|
||||
// &contract_addr,
|
||||
// &deployer,
|
||||
// )
|
||||
// .unwrap();
|
||||
// assert_eq!(&result.out, &to_be_bytes(&U256::from(1)));
|
||||
// println!("{:?}", result);
|
||||
// Call verify function on contract
|
||||
let result = evm
|
||||
.call(
|
||||
contract
|
||||
.encode_call_contract_bytes("verifyTx", &inputs)
|
||||
.unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(&result.out, &to_be_bytes(&U256::from(1)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
use crate::proof_system::scheme::{NonUniversalScheme, Scheme};
|
||||
use crate::proof_system::solidity::solidity_pairing_lib;
|
||||
use crate::proof_system::{
|
||||
encode_g1_element, encode_g2_element, G1Affine, G2Affine, SolidityCompatibleField,
|
||||
SolidityCompatibleScheme, ToToken,
|
||||
};
|
||||
use ethabi::Token;
|
||||
use crate::proof_system::{G1Affine, G2Affine, SolidityCompatibleField, SolidityCompatibleScheme};
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::Field;
|
||||
|
@ -12,7 +8,7 @@ use zokrates_field::Field;
|
|||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct PGHR13;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct ProofPoints<G1, G2> {
|
||||
pub a: G1,
|
||||
pub a_p: G1,
|
||||
|
@ -43,57 +39,6 @@ impl<T: Field> Scheme<T> for PGHR13 {
|
|||
|
||||
impl<T: Field> NonUniversalScheme<T> for PGHR13 {}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for PGHR13 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let a_p = {
|
||||
let (x, y) = encode_g1_element(&proof.a_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let b_p = {
|
||||
let (x, y) = encode_g1_element(&proof.b_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c_p = {
|
||||
let (x, y) = encode_g1_element(&proof.c_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let h = {
|
||||
let (x, y) = encode_g1_element(&proof.h);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let k = {
|
||||
let (x, y) = encode_g1_element(&proof.k);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, a_p, b, b_p, c, c_p, h, k];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> SolidityCompatibleScheme<T> for PGHR13 {
|
||||
type Proof = Self::ProofPoints;
|
||||
|
||||
|
|
|
@ -4,15 +4,11 @@ use zokrates_field::{Bn128Field, Field};
|
|||
|
||||
pub trait SolidityCompatibleField: Field {}
|
||||
impl SolidityCompatibleField for Bn128Field {}
|
||||
|
||||
pub trait SolidityCompatibleScheme<T: SolidityCompatibleField>: Scheme<T> {
|
||||
type Proof: From<Self::ProofPoints> + Serialize + DeserializeOwned;
|
||||
type Proof: From<Self::ProofPoints> + Serialize + DeserializeOwned + Clone;
|
||||
|
||||
fn export_solidity_verifier(vk: Self::VerificationKey) -> String;
|
||||
}
|
||||
pub trait ToToken<T: SolidityCompatibleField>: SolidityCompatibleScheme<T> {
|
||||
fn to_token(proof: Self::Proof) -> ethabi::Token;
|
||||
}
|
||||
|
||||
pub const SOLIDITY_G2_ADDITION_LIB: &str = r#"// SPDX-License-Identifier: LGPL-3.0-only
|
||||
// This file is LGPL3 Licensed
|
||||
|
|
238
zokrates_core/src/proof_system/to_token.rs
Normal file
238
zokrates_core/src/proof_system/to_token.rs
Normal file
|
@ -0,0 +1,238 @@
|
|||
use ethabi::Token;
|
||||
use primitive_types::U256;
|
||||
|
||||
use super::{
|
||||
Fr, G1Affine, G2Affine, Marlin, NotBw6_761Field, SolidityCompatibleField,
|
||||
SolidityCompatibleScheme, G16, GM17, PGHR13,
|
||||
};
|
||||
|
||||
/// Helper methods for parsing group structure
|
||||
pub fn encode_g1_element(g: &G1Affine) -> (U256, U256) {
|
||||
(
|
||||
U256::from(&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..]),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_g2_element(g: &G2Affine) -> ((U256, U256), (U256, U256)) {
|
||||
(
|
||||
(
|
||||
U256::from(&hex::decode(&g.0 .0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.0 .1.trim_start_matches("0x")).unwrap()[..]),
|
||||
),
|
||||
(
|
||||
U256::from(&hex::decode(&g.1 .0.trim_start_matches("0x")).unwrap()[..]),
|
||||
U256::from(&hex::decode(&g.1 .1.trim_start_matches("0x")).unwrap()[..]),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encode_fr_element(f: &Fr) -> U256 {
|
||||
U256::from(&hex::decode(&f.trim_start_matches("0x")).unwrap()[..])
|
||||
}
|
||||
|
||||
pub trait ToToken<T: SolidityCompatibleField>: SolidityCompatibleScheme<T> {
|
||||
fn to_token(proof: Self::Proof) -> ethabi::Token;
|
||||
|
||||
fn modify(proof: Self::Proof) -> Self::Proof;
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for PGHR13 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let a_p = {
|
||||
let (x, y) = encode_g1_element(&proof.a_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let b_p = {
|
||||
let (x, y) = encode_g1_element(&proof.b_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let c_p = {
|
||||
let (x, y) = encode_g1_element(&proof.c_p);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let h = {
|
||||
let (x, y) = encode_g1_element(&proof.h);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let k = {
|
||||
let (x, y) = encode_g1_element(&proof.k);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, a_p, b, b_p, c, c_p, h, k];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
|
||||
fn modify(mut proof: Self::Proof) -> Self::Proof {
|
||||
proof.a.0 = str::replace(&proof.a.0, 'a', "f");
|
||||
proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField> ToToken<T> for G16 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, b, c];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
|
||||
fn modify(mut proof: Self::Proof) -> Self::Proof {
|
||||
proof.a.0 = str::replace(&proof.a.0, 'a', "f");
|
||||
proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field> ToToken<T> for GM17 {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let a = {
|
||||
let (x, y) = encode_g1_element(&proof.a);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let b = {
|
||||
let ((x0, y0), (x1, y1)) = encode_g2_element(&proof.b);
|
||||
Token::Tuple(vec![
|
||||
Token::FixedArray(vec![Token::Uint(x0), Token::Uint(y0)]),
|
||||
Token::FixedArray(vec![Token::Uint(x1), Token::Uint(y1)]),
|
||||
])
|
||||
};
|
||||
|
||||
let c = {
|
||||
let (x, y) = encode_g1_element(&proof.c);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![a, b, c];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
|
||||
fn modify(mut proof: Self::Proof) -> Self::Proof {
|
||||
proof.a.0 = str::replace(&proof.a.0, 'a', "f");
|
||||
proof
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SolidityCompatibleField + NotBw6_761Field> ToToken<T> for Marlin {
|
||||
fn to_token(proof: Self::Proof) -> Token {
|
||||
let comms_1_token = Token::Array(
|
||||
proof
|
||||
.comms_1
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let comms_2_token = Token::Array(
|
||||
proof
|
||||
.comms_2
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_2_g1_token = {
|
||||
let (x, y) = encode_g1_element(&proof.degree_bound_comms_2_g1);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let comms_3_token = Token::Array(
|
||||
proof
|
||||
.comms_3
|
||||
.iter()
|
||||
.map(encode_g1_element)
|
||||
.map(|(x, y)| Token::Tuple(vec![Token::Uint(x), Token::Uint(y)]))
|
||||
.collect(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_3_g2_token = {
|
||||
let (x, y) = encode_g1_element(&proof.degree_bound_comms_3_g2);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let evals_token = Token::Array(
|
||||
proof
|
||||
.evals
|
||||
.into_iter()
|
||||
.map(|f| encode_fr_element(&f))
|
||||
.map(Token::Uint)
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let pc_lc_opening_1_token = {
|
||||
let (x, y) = encode_g1_element(&proof.batch_lc_proof_1);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let degree_bound_pc_lc_opening_1_token =
|
||||
Token::Uint(encode_fr_element(&proof.batch_lc_proof_1_r));
|
||||
|
||||
let pc_lc_opening_2_token = {
|
||||
let (x, y) = encode_g1_element(&proof.batch_lc_proof_2);
|
||||
Token::Tuple(vec![Token::Uint(x), Token::Uint(y)])
|
||||
};
|
||||
|
||||
let proof_tokens = vec![
|
||||
comms_1_token,
|
||||
comms_2_token,
|
||||
degree_bound_comms_2_g1_token,
|
||||
comms_3_token,
|
||||
degree_bound_comms_3_g2_token,
|
||||
evals_token,
|
||||
pc_lc_opening_1_token,
|
||||
degree_bound_pc_lc_opening_1_token,
|
||||
pc_lc_opening_2_token,
|
||||
];
|
||||
|
||||
Token::Tuple(proof_tokens)
|
||||
}
|
||||
|
||||
fn modify(mut proof: Self::Proof) -> Self::Proof {
|
||||
proof.degree_bound_comms_3_g2.0 = str::replace(&proof.degree_bound_comms_3_g2.0, 'a', "f");
|
||||
proof
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ primitive-types = { version = "0.11", features = ["rlp"] }
|
|||
hex = { version = "0.4" }
|
||||
bytes = { version = "1.1", default-features = false }
|
||||
serde_json = { version = "1.0" }
|
||||
rand = { version = "0.4" }
|
||||
rand = { version = "0.8" }
|
||||
|
||||
revm = { git = "https://github.com/bluealloy/revm", version = "1.2" }
|
||||
solc = { git = "https://github.com/g-r-a-n-t/solc-rust", rev = "52d4146" }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ethabi::{Address, Contract as ContractAbi, Token};
|
||||
use ethabi::{Contract as ContractAbi, Token};
|
||||
use serde_json::{from_str, json};
|
||||
use solc::compile;
|
||||
|
||||
|
@ -100,10 +100,8 @@ impl Contract {
|
|||
.to_string()
|
||||
.replace("\"", "");
|
||||
|
||||
let binary = hex::decode(&hex_code).map_err(|e| {
|
||||
println!("{}", e);
|
||||
Box::new(EvmTestError("decode hex binary failed".to_string()))
|
||||
})?;
|
||||
let binary = hex::decode(&hex_code)
|
||||
.map_err(|_| Box::new(EvmTestError("decode hex binary failed".to_string())))?;
|
||||
binary
|
||||
};
|
||||
let abi = {
|
||||
|
@ -147,7 +145,7 @@ impl Contract {
|
|||
) -> Result<Vec<u8>, Error> {
|
||||
match self.abi.functions.get(fn_name) {
|
||||
Some(f) => {
|
||||
let call_binary = f[0].encode_input(input).map_err(|e| {
|
||||
let call_binary = f[0].encode_input(input).map_err(|_| {
|
||||
Box::new(EvmTestError(
|
||||
"abi function failed to encode inputs".to_string(),
|
||||
))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use primitive_types::U256;
|
||||
use revm::{AccountInfo, InMemoryDB, Log, Return, TransactOut, TransactTo, EVM};
|
||||
pub use revm::Return;
|
||||
use revm::{AccountInfo, InMemoryDB, Log, TransactOut, TransactTo, EVM};
|
||||
|
||||
use crate::{address::Address, Error, EvmTestError};
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ mod tests {
|
|||
assert_eq!(&get_result.out, &to_be_bytes(&U256::from(0)));
|
||||
|
||||
// Call set function on contract
|
||||
let set_result = evm
|
||||
let _ = evm
|
||||
.call(
|
||||
contract
|
||||
.encode_call_contract_bytes(
|
||||
|
|
Loading…
Reference in a new issue