cargo fmt
This commit is contained in:
parent
30f6f4c697
commit
b8a79d4dda
7 changed files with 244 additions and 121 deletions
|
@ -14,7 +14,7 @@ use crate::proof_system::gm17::{ProofPoints, VerificationKey, GM17};
|
|||
use crate::proof_system::{Backend, NonUniversalBackend, Proof, SetupKeypair};
|
||||
use crate::proof_system::{NotBw6_761Field, Scheme};
|
||||
use ark_bw6_761::BW6_761;
|
||||
use rand_0_8::{SeedableRng, rngs::StdRng};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
|
||||
impl<T: Field + ArkFieldExtensions + NotBw6_761Field> NonUniversalBackend<T, GM17> for Ark {
|
||||
fn setup<I: IntoIterator<Item = Statement<T>>>(
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::proof_system::ark::{parse_g1, parse_g2};
|
|||
use crate::proof_system::groth16::{ProofPoints, VerificationKey, G16};
|
||||
use crate::proof_system::Scheme;
|
||||
use ark_bw6_761::BW6_761;
|
||||
use rand_0_8::{SeedableRng, rngs::StdRng};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
|
||||
const G16_WARNING: &str = "WARNING: You are using the G16 scheme which is subject to malleability. See zokrates.github.io/toolbox/proving_schemes.html#g16-malleability for implications.";
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use ark_marlin::{
|
||||
ahp::indexer::IndexInfo, ahp::prover::ProverMsg, IndexProverKey, IndexVerifierKey,
|
||||
Proof as ArkProof,
|
||||
rng::FiatShamirRng,
|
||||
ahp::indexer::IndexInfo, ahp::prover::ProverMsg, rng::FiatShamirRng, IndexProverKey,
|
||||
IndexVerifierKey, Proof as ArkProof,
|
||||
};
|
||||
|
||||
use ark_marlin::Marlin as ArkMarlin;
|
||||
|
||||
use ark_ff::{FftField, ToBytes, FromBytes, to_bytes};
|
||||
use ark_ec::PairingEngine;
|
||||
use ark_poly::{univariate::DensePolynomial, GeneralEvaluationDomain, EvaluationDomain};
|
||||
use ark_ff::{to_bytes, FftField, FromBytes, ToBytes};
|
||||
use ark_poly::{univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain};
|
||||
use ark_poly_commit::{
|
||||
data_structures::BatchLCProof,
|
||||
kzg10::Commitment as KZG10Commitment,
|
||||
|
@ -17,14 +16,11 @@ use ark_poly_commit::{
|
|||
marlin_pc::{Commitment, MarlinKZG10, VerifierKey},
|
||||
};
|
||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
||||
use sha3::Keccak256;
|
||||
use rand_0_8::{SeedableRng, RngCore, Error};
|
||||
use num::Zero;
|
||||
use digest::Digest;
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
convert::TryFrom,
|
||||
};
|
||||
use num::Zero;
|
||||
use rand_0_8::{Error, RngCore, SeedableRng};
|
||||
use sha3::Keccak256;
|
||||
use std::{convert::TryFrom, marker::PhantomData};
|
||||
|
||||
use zokrates_field::{ArkFieldExtensions, Field};
|
||||
|
||||
|
@ -67,10 +63,12 @@ impl<D: Digest> RngCore for HashFiatShamirRng<D> {
|
|||
let mut h = D::digest(&seed_ctr).to_vec();
|
||||
h.reverse(); // Switch to big endian representation for solidity translation
|
||||
let len = dest.len();
|
||||
if i*bytes_per_hash + bytes_per_hash >= len {
|
||||
dest[i * bytes_per_hash..].copy_from_slice(&h.as_slice()[..len - i*bytes_per_hash]);
|
||||
if i * bytes_per_hash + bytes_per_hash >= len {
|
||||
dest[i * bytes_per_hash..]
|
||||
.copy_from_slice(&h.as_slice()[..len - i * bytes_per_hash]);
|
||||
} else {
|
||||
dest[i * bytes_per_hash..i * bytes_per_hash + bytes_per_hash].copy_from_slice(h.as_slice());
|
||||
dest[i * bytes_per_hash..i * bytes_per_hash + bytes_per_hash]
|
||||
.copy_from_slice(h.as_slice());
|
||||
}
|
||||
self.ctr += 1;
|
||||
seed_ctr.truncate(seed_ctr.len() - 4);
|
||||
|
@ -85,7 +83,9 @@ impl<D: Digest> RngCore for HashFiatShamirRng<D> {
|
|||
impl<D: Digest> FiatShamirRng for HashFiatShamirRng<D> {
|
||||
fn initialize<'a, T: 'a + ToBytes>(initial_input: &'a T) -> Self {
|
||||
let mut bytes = Vec::new();
|
||||
initial_input.write(&mut bytes).expect("failed to convert to bytes");
|
||||
initial_input
|
||||
.write(&mut bytes)
|
||||
.expect("failed to convert to bytes");
|
||||
let seed = FromBytes::read(D::digest(&bytes).as_ref()).expect("failed to get [u8; 32]");
|
||||
Self {
|
||||
seed: seed,
|
||||
|
@ -96,23 +96,34 @@ impl<D: Digest> FiatShamirRng for HashFiatShamirRng<D> {
|
|||
|
||||
fn absorb<'a, T: 'a + ToBytes>(&mut self, new_input: &'a T) {
|
||||
let mut bytes = Vec::new();
|
||||
new_input.write(&mut bytes).expect("failed to convert to bytes");
|
||||
new_input
|
||||
.write(&mut bytes)
|
||||
.expect("failed to convert to bytes");
|
||||
bytes.extend_from_slice(&self.seed);
|
||||
self.seed = FromBytes::read(D::digest(&bytes).as_ref()).expect("failed to get [u8; 32]");
|
||||
self.ctr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
type PCInst<T> = MarlinKZG10<<T as ArkFieldExtensions>::ArkEngine, DensePolynomial<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>>;
|
||||
type MarlinInst<T> = ArkMarlin<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr, PCInst<T>, HashFiatShamirRng<Keccak256>>;
|
||||
type PCInst<T> = MarlinKZG10<
|
||||
<T as ArkFieldExtensions>::ArkEngine,
|
||||
DensePolynomial<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>,
|
||||
>;
|
||||
type MarlinInst<T> = ArkMarlin<
|
||||
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr,
|
||||
PCInst<T>,
|
||||
HashFiatShamirRng<Keccak256>,
|
||||
>;
|
||||
|
||||
impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark {
|
||||
fn universal_setup(size: u32) -> Vec<u8> {
|
||||
|
||||
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
|
||||
|
||||
let srs = MarlinInst::<T>::universal_setup(
|
||||
2usize.pow(size), 2usize.pow(size), 2usize.pow(size), rng
|
||||
2usize.pow(size),
|
||||
2usize.pow(size),
|
||||
2usize.pow(size),
|
||||
rng,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -155,7 +166,11 @@ impl<T: Field + ArkFieldExtensions> UniversalBackend<T, marlin::Marlin> for Ark
|
|||
|
||||
// Precompute some useful values for solidity contract
|
||||
let fs_seed = to_bytes![&MarlinInst::<T>::PROTOCOL_NAME, &vk].unwrap();
|
||||
let x_root_of_unity = <<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr::get_root_of_unity(usize::try_from(vk.index_info.num_instance_variables).unwrap()).unwrap();
|
||||
let x_root_of_unity =
|
||||
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr::get_root_of_unity(
|
||||
usize::try_from(vk.index_info.num_instance_variables).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Ok(SetupKeypair::new(
|
||||
VerificationKey {
|
||||
|
@ -211,19 +226,18 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
.unwrap();
|
||||
|
||||
let mut public_inputs = computation.public_inputs_values();
|
||||
let domain_x = GeneralEvaluationDomain::<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::new(public_inputs.len() + 1).unwrap();
|
||||
let domain_x = GeneralEvaluationDomain::<
|
||||
<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr,
|
||||
>::new(public_inputs.len() + 1)
|
||||
.unwrap();
|
||||
public_inputs.resize(
|
||||
core::cmp::max(public_inputs.len(), domain_x.size() - 1),
|
||||
<<<T as ArkFieldExtensions>::ArkEngine as PairingEngine>::Fr>::zero(),
|
||||
);
|
||||
|
||||
let inputs = public_inputs
|
||||
.iter()
|
||||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
let inputs = public_inputs.iter().map(parse_fr::<T>).collect::<Vec<_>>();
|
||||
|
||||
let proof = MarlinInst::<T>::prove(&pk, computation, rng)
|
||||
.unwrap();
|
||||
let proof = MarlinInst::<T>::prove(&pk, computation, rng).unwrap();
|
||||
|
||||
let mut serialized_proof: Vec<u8> = Vec::new();
|
||||
proof.serialize_uncompressed(&mut serialized_proof).unwrap();
|
||||
|
@ -366,8 +380,7 @@ impl<T: Field + ArkFieldExtensions> Backend<T, marlin::Marlin> for Ark {
|
|||
|
||||
let rng = &mut rand_0_8::rngs::StdRng::from_entropy();
|
||||
|
||||
MarlinInst::<T>::verify(&vk, &inputs, &proof, rng)
|
||||
.unwrap()
|
||||
MarlinInst::<T>::verify(&vk, &inputs, &proof, rng).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use crate::proof_system::scheme::{Scheme, UniversalScheme};
|
||||
use crate::proof_system::{G1Affine, G2Affine, Fr, NotBw6_761Field};
|
||||
use crate::proof_system::solidity::{SolidityCompatibleScheme, SolidityCompatibleField, solidity_pairing_lib};
|
||||
use crate::proof_system::solidity::{
|
||||
solidity_pairing_lib, SolidityCompatibleField, SolidityCompatibleScheme,
|
||||
};
|
||||
use crate::proof_system::{Fr, G1Affine, G2Affine, NotBw6_761Field};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -61,11 +63,18 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
|
|||
|
||||
// Replace public parameters in template
|
||||
let src = template
|
||||
.replace("<%vk_index_comms_length%>", &vk.index_comms.len().to_string())
|
||||
.replace(
|
||||
"<%vk_index_comms_length%>",
|
||||
&vk.index_comms.len().to_string(),
|
||||
)
|
||||
.replace("<%vk_populate_index_comms%>", &{
|
||||
let mut populate_index_comms = String::new();
|
||||
for (i, (g, _)) in vk.index_comms.iter().enumerate() {
|
||||
populate_index_comms.push_str(&format!("vk.index_comms[{}] = Pairing.G1Point({});", i, &g.to_string()));
|
||||
populate_index_comms.push_str(&format!(
|
||||
"vk.index_comms[{}] = Pairing.G1Point({});",
|
||||
i,
|
||||
&g.to_string()
|
||||
));
|
||||
if i < vk.index_comms.len() - 1 {
|
||||
populate_index_comms.push_str("\n ");
|
||||
}
|
||||
|
@ -76,14 +85,29 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
|
|||
.replace("<%vk_kzg_gamma_g%>", &vk.vk.gamma_g.to_string())
|
||||
.replace("<%vk_kzg_h%>", &vk.vk.h.to_string())
|
||||
.replace("<%vk_kzg_beta_h%>", &vk.vk.beta_h.to_string())
|
||||
.replace("<%vk_degree_bounds_length%>", &vk.degree_bounds_and_shift_powers.as_ref().unwrap().len().to_string())
|
||||
.replace(
|
||||
"<%vk_degree_bounds_length%>",
|
||||
&vk.degree_bounds_and_shift_powers
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.len()
|
||||
.to_string(),
|
||||
)
|
||||
.replace("<%vk_g1_shift%>", &{
|
||||
let h_domain_size = if vk.num_constraints.is_power_of_two() {
|
||||
vk.num_constraints
|
||||
} else {
|
||||
vk.num_constraints.next_power_of_two()
|
||||
};
|
||||
vk.degree_bounds_and_shift_powers.as_ref().unwrap().iter().filter(|(b, _)| *b == h_domain_size - 2).next().unwrap().1.to_string()
|
||||
vk.degree_bounds_and_shift_powers
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|(b, _)| *b == h_domain_size - 2)
|
||||
.next()
|
||||
.unwrap()
|
||||
.1
|
||||
.to_string()
|
||||
})
|
||||
.replace("<%vk_g2_shift%>", &{
|
||||
let k_domain_size = if vk.num_non_zero.is_power_of_two() {
|
||||
|
@ -91,19 +115,29 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
|
|||
} else {
|
||||
vk.num_non_zero.next_power_of_two()
|
||||
};
|
||||
vk.degree_bounds_and_shift_powers.as_ref().unwrap().iter().filter(|(b, _)| *b == k_domain_size - 2).next().unwrap().1.to_string()
|
||||
vk.degree_bounds_and_shift_powers
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter(|(b, _)| *b == k_domain_size - 2)
|
||||
.next()
|
||||
.unwrap()
|
||||
.1
|
||||
.to_string()
|
||||
})
|
||||
.replace("<%fs_init_seed_len%>", &(vk.fs_seed.len() / 32).to_string())
|
||||
.replace("<%fs_init_seed_overflow_len%>", &{
|
||||
let seed_len_in_32_byte_words = vk.fs_seed.len() / 32;
|
||||
let seed_len_overflow_in_bytes = vk.fs_seed.len() - (seed_len_in_32_byte_words * 32);
|
||||
let seed_len_overflow_in_bytes =
|
||||
vk.fs_seed.len() - (seed_len_in_32_byte_words * 32);
|
||||
seed_len_overflow_in_bytes.to_string()
|
||||
})
|
||||
.replace("<%fs_populate_init_seed%>", &{
|
||||
let mut populate_init_seed = String::new();
|
||||
for i in 0..vk.fs_seed.len() / 32 {
|
||||
let word_32_bytes = hex::encode(&vk.fs_seed[i*32..i*32 + 32]);
|
||||
populate_init_seed.push_str(&format!("init_seed[{}] = 0x{};", i, &word_32_bytes));
|
||||
let word_32_bytes = hex::encode(&vk.fs_seed[i * 32..i * 32 + 32]);
|
||||
populate_init_seed
|
||||
.push_str(&format!("init_seed[{}] = 0x{};", i, &word_32_bytes));
|
||||
if i < vk.fs_seed.len() / 32 - 1 {
|
||||
populate_init_seed.push_str("\n ");
|
||||
}
|
||||
|
@ -112,7 +146,10 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
|
|||
})
|
||||
.replace("<%fs_init_seed_overflow%>", &{
|
||||
let seed_len_in_32_byte_words = vk.fs_seed.len() / 32;
|
||||
format!("0x{}", hex::encode(&vk.fs_seed[seed_len_in_32_byte_words * 32..]))
|
||||
format!(
|
||||
"0x{}",
|
||||
hex::encode(&vk.fs_seed[seed_len_in_32_byte_words * 32..])
|
||||
)
|
||||
})
|
||||
.replace("<%h_domain_size%>", &{
|
||||
let size = if vk.num_constraints.is_power_of_two() {
|
||||
|
@ -140,15 +177,17 @@ impl<T: SolidityCompatibleField + NotBw6_761Field> SolidityCompatibleScheme<T> f
|
|||
size.to_string()
|
||||
})
|
||||
.replace("<%x_root%>", &vk.x_root_of_unity.to_string())
|
||||
.replace("<%f_mod%>", "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001")
|
||||
.replace("<%f_r%>", "0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb")
|
||||
.replace(
|
||||
"<%f_mod%>",
|
||||
"0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
|
||||
)
|
||||
.replace(
|
||||
"<%f_r%>",
|
||||
"0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb",
|
||||
)
|
||||
.replace("<%f_inv%>", "0xc2e1f593efffffff");
|
||||
|
||||
|
||||
format!(
|
||||
"{}{}",
|
||||
solidity_pairing_lib, src
|
||||
)
|
||||
format!("{}{}", solidity_pairing_lib, src)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,28 +630,26 @@ contract Verifier {
|
|||
mod tests {
|
||||
use crate::flat_absy::{FlatParameter, FlatVariable};
|
||||
use crate::ir::{Interpreter, Prog, QuadComb, Statement};
|
||||
use crate::proof_system::{UniversalBackend, Backend, Proof, Fr};
|
||||
use crate::proof_system::ark::{Ark, parse_fr};
|
||||
use crate::proof_system::ark::{parse_fr, Ark};
|
||||
use crate::proof_system::{Backend, Fr, Proof, UniversalBackend};
|
||||
use zokrates_field::ArkFieldExtensions;
|
||||
|
||||
use super::*;
|
||||
use zokrates_field::{Bn128Field};
|
||||
use zokrates_solidity_test::{
|
||||
contract::Contract,
|
||||
evm::Evm,
|
||||
address::Address,
|
||||
to_be_bytes,
|
||||
};
|
||||
use rand_0_8::{rngs::StdRng, SeedableRng};
|
||||
use ethabi::{Token};
|
||||
use ethabi::Token;
|
||||
use primitive_types::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};
|
||||
|
||||
/// Helper methods for parsing group structure
|
||||
pub fn encode_g1_element(g: &G1Affine) -> Token {
|
||||
Token::Tuple(vec![
|
||||
Token::Uint(U256::from(&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..])),
|
||||
Token::Uint(U256::from(&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..])),
|
||||
Token::Uint(U256::from(
|
||||
&hex::decode(&g.0.trim_start_matches("0x")).unwrap()[..],
|
||||
)),
|
||||
Token::Uint(U256::from(
|
||||
&hex::decode(&g.1.trim_start_matches("0x")).unwrap()[..],
|
||||
)),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -630,38 +667,66 @@ mod tests {
|
|||
//}
|
||||
|
||||
pub fn encode_fr_element(f: &Fr) -> Token {
|
||||
Token::Uint(U256::from(&hex::decode(&f.trim_start_matches("0x")).unwrap()[..]))
|
||||
Token::Uint(U256::from(
|
||||
&hex::decode(&f.trim_start_matches("0x")).unwrap()[..],
|
||||
))
|
||||
}
|
||||
|
||||
fn encode_verify_input(proof: Proof<<Marlin as Scheme<Bn128Field>>::ProofPoints>,) -> Vec<Token> {
|
||||
let input = Token::Array(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<_>>());
|
||||
fn encode_verify_input(
|
||||
proof: Proof<<Marlin as Scheme<Bn128Field>>::ProofPoints>,
|
||||
) -> Vec<Token> {
|
||||
let input = Token::Array(
|
||||
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 comms_1_token = Token::Array(proof.proof.commitments[0].iter().map(|(c, _)|{
|
||||
encode_g1_element(c)
|
||||
}).collect::<Vec<_>>());
|
||||
let comms_1_token = Token::Array(
|
||||
proof.proof.commitments[0]
|
||||
.iter()
|
||||
.map(|(c, _)| encode_g1_element(c))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let comms_2_token = Token::Array(proof.proof.commitments[1].iter().map(|(c, _)|{
|
||||
encode_g1_element(c)
|
||||
}).collect::<Vec<_>>());
|
||||
let comms_2_token = Token::Array(
|
||||
proof.proof.commitments[1]
|
||||
.iter()
|
||||
.map(|(c, _)| encode_g1_element(c))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_2_g1_token = encode_g1_element(proof.proof.commitments[1][1].1.as_ref().unwrap());
|
||||
let degree_bound_comms_2_g1_token =
|
||||
encode_g1_element(proof.proof.commitments[1][1].1.as_ref().unwrap());
|
||||
|
||||
let comms_3_token = Token::Array(proof.proof.commitments[2].iter().map(|(c, _)|{
|
||||
encode_g1_element(c)
|
||||
}).collect::<Vec<_>>());
|
||||
let comms_3_token = Token::Array(
|
||||
proof.proof.commitments[2]
|
||||
.iter()
|
||||
.map(|(c, _)| encode_g1_element(c))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let degree_bound_comms_3_g2_token = encode_g1_element(proof.proof.commitments[2][0].1.as_ref().unwrap());
|
||||
let degree_bound_comms_3_g2_token =
|
||||
encode_g1_element(proof.proof.commitments[2][0].1.as_ref().unwrap());
|
||||
|
||||
let evals_token = Token::Array(proof.proof.evaluations.into_iter().map(|f| {
|
||||
encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(f)))
|
||||
}).collect::<Vec<_>>());
|
||||
let evals_token = Token::Array(
|
||||
proof
|
||||
.proof
|
||||
.evaluations
|
||||
.into_iter()
|
||||
.map(|f| encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(f))))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let pc_lc_opening_1_token = encode_g1_element(&proof.proof.pc_proof_proof[0].0);
|
||||
let degree_bound_pc_lc_opening_1_token = encode_fr_element(&parse_fr::<Bn128Field>(&Bn128Field::into_ark(proof.proof.pc_proof_proof[0].1.clone().unwrap())));
|
||||
let degree_bound_pc_lc_opening_1_token = encode_fr_element(&parse_fr::<Bn128Field>(
|
||||
&Bn128Field::into_ark(proof.proof.pc_proof_proof[0].1.clone().unwrap()),
|
||||
));
|
||||
let pc_lc_opening_2_token = encode_g1_element(&proof.proof.pc_proof_proof[1].0);
|
||||
|
||||
let proof_tokens = vec![
|
||||
|
@ -715,7 +780,8 @@ mod tests {
|
|||
//let ans = <Ark as Backend<Bn128Field, Marlin>>::verify(keypair.vk, proof);
|
||||
//assert!(ans);
|
||||
|
||||
let mut src = <Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
|
||||
let mut src =
|
||||
<Marlin as SolidityCompatibleScheme<Bn128Field>>::export_solidity_verifier(keypair.vk);
|
||||
src = src.replace("\"", "\\\"");
|
||||
|
||||
let solc_config = r#"
|
||||
|
@ -734,8 +800,8 @@ mod tests {
|
|||
"": [ "*" ] } }
|
||||
}
|
||||
}"#
|
||||
.replace("<%opt%>", &true.to_string())
|
||||
.replace("<%src%>", &src);
|
||||
.replace("<%opt%>", &true.to_string())
|
||||
.replace("<%src%>", &src);
|
||||
|
||||
let contract = Contract::compile_from_config(&solc_config, "Verifier").unwrap();
|
||||
|
||||
|
@ -746,14 +812,26 @@ mod tests {
|
|||
evm.create_account(&deployer, 0);
|
||||
|
||||
// Deploy contract
|
||||
let create_result = evm.deploy(contract.encode_create_contract_bytes(&[]).unwrap(), &deployer).unwrap();
|
||||
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);
|
||||
|
||||
// Call verify function on contract
|
||||
let result = evm.call(contract.encode_call_contract_bytes("verify", &encode_verify_input(proof)).unwrap(), &contract_addr, &deployer).unwrap();
|
||||
let result = evm
|
||||
.call(
|
||||
contract
|
||||
.encode_call_contract_bytes("verify", &encode_verify_input(proof))
|
||||
.unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(&result.out, &to_be_bytes(&U256::from(1)));
|
||||
//println!("{:?}", result);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,10 +61,7 @@ impl Contract {
|
|||
Self::compile_from_config(&solc_config, contract_name)
|
||||
}
|
||||
|
||||
pub fn compile_from_config(
|
||||
config: &String,
|
||||
contract_name: &str,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn compile_from_config(config: &String, contract_name: &str) -> Result<Self, Error> {
|
||||
// Compile source file using solc
|
||||
// Configuration: https://docs.soliditylang.org/en/v0.8.10/using-the-compiler.html
|
||||
let out = from_str::<serde_json::Value>(&compile(config))
|
||||
|
@ -104,7 +101,7 @@ impl Contract {
|
|||
.to_string()
|
||||
.as_bytes(),
|
||||
)
|
||||
.map_err(|_| Box::new(EvmTestError("ethabi failed loading abi".to_string())))?;
|
||||
.map_err(|_| Box::new(EvmTestError("ethabi failed loading abi".to_string())))?;
|
||||
abi
|
||||
};
|
||||
|
||||
|
@ -122,26 +119,30 @@ impl Contract {
|
|||
))
|
||||
})?;
|
||||
Ok(binary.to_vec())
|
||||
},
|
||||
}
|
||||
None => Ok(self.binary.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_call_contract_bytes(&self, fn_name: &str, input: &[Token]) -> Result<Vec<u8>, Error> {
|
||||
pub fn encode_call_contract_bytes(
|
||||
&self,
|
||||
fn_name: &str,
|
||||
input: &[Token],
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
match self.abi.functions.get(fn_name) {
|
||||
Some(f) => {
|
||||
//let c = f[0].inputs.iter().map(|p| p.kind.clone()).collect::<Vec<_>>();
|
||||
//println!("{:?}", c);
|
||||
let call_binary = f[0].encode_input(input)
|
||||
.map_err(|_| {
|
||||
Box::new(EvmTestError(
|
||||
"abi function failed to encode inputs".to_string(),
|
||||
))
|
||||
})?;
|
||||
let call_binary = f[0].encode_input(input).map_err(|_| {
|
||||
Box::new(EvmTestError(
|
||||
"abi function failed to encode inputs".to_string(),
|
||||
))
|
||||
})?;
|
||||
Ok(call_binary.to_vec())
|
||||
},
|
||||
None => Err(Box::new(EvmTestError("abi does not include function".to_string()))),
|
||||
}
|
||||
None => Err(Box::new(EvmTestError(
|
||||
"abi does not include function".to_string(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,14 +28,21 @@ impl Evm {
|
|||
Self { vm }
|
||||
}
|
||||
|
||||
pub fn call(&mut self, input: Vec<u8>, addr: &Address, caller: &Address) -> Result<CallResult, Error> {
|
||||
pub fn call(
|
||||
&mut self,
|
||||
input: Vec<u8>,
|
||||
addr: &Address,
|
||||
caller: &Address,
|
||||
) -> Result<CallResult, Error> {
|
||||
self.vm.env.tx.caller = caller.as_ref().clone();
|
||||
self.vm.env.tx.transact_to = TransactTo::Call(addr.as_ref().clone());
|
||||
self.vm.env.tx.data = input.into();
|
||||
let (op_out, tx_out, gas, log_out) = self.vm.transact_commit();
|
||||
let out = match tx_out {
|
||||
TransactOut::Call(out) => Ok(out.to_vec()),
|
||||
_ => Err(Box::new(EvmTestError("call contract function failed".to_string()))),
|
||||
_ => Err(Box::new(EvmTestError(
|
||||
"call contract function failed".to_string(),
|
||||
))),
|
||||
}?;
|
||||
Ok(CallResult {
|
||||
op_out,
|
||||
|
|
|
@ -35,13 +35,9 @@ pub fn to_be_bytes(n: &U256) -> [u8; 32] {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
address::Address,
|
||||
contract::Contract,
|
||||
evm::{Evm},
|
||||
};
|
||||
use rand::{rngs::StdRng, SeedableRng};
|
||||
use crate::{address::Address, contract::Contract, evm::Evm};
|
||||
use ethabi::Token;
|
||||
use rand::{rngs::StdRng, SeedableRng};
|
||||
|
||||
#[test]
|
||||
fn simple_storage_contract_test() {
|
||||
|
@ -61,21 +57,49 @@ mod tests {
|
|||
evm.create_account(&deployer, 0);
|
||||
|
||||
// Deploy contract
|
||||
let create_result = evm.deploy(contract.encode_create_contract_bytes(&[]).unwrap(), &deployer).unwrap();
|
||||
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);
|
||||
|
||||
// Call get function on contract
|
||||
let get_result = evm.call(contract.encode_call_contract_bytes("get", &[]).unwrap(), &contract_addr, &deployer).unwrap();
|
||||
let get_result = evm
|
||||
.call(
|
||||
contract.encode_call_contract_bytes("get", &[]).unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(&get_result.out, &to_be_bytes(&U256::from(0)));
|
||||
println!("{:?}", get_result);
|
||||
|
||||
// Call set function on contract
|
||||
let set_result = evm.call(contract.encode_call_contract_bytes("set", &[Token::Tuple(vec![Token::Uint(U256::from(40))])]).unwrap(), &contract_addr, &deployer).unwrap();
|
||||
let set_result = evm
|
||||
.call(
|
||||
contract
|
||||
.encode_call_contract_bytes(
|
||||
"set",
|
||||
&[Token::Tuple(vec![Token::Uint(U256::from(40))])],
|
||||
)
|
||||
.unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
println!("{:?}", set_result);
|
||||
|
||||
// Call get function on contract
|
||||
let get_result = evm.call(contract.encode_call_contract_bytes("get", &[]).unwrap(), &contract_addr, &deployer).unwrap();
|
||||
let get_result = evm
|
||||
.call(
|
||||
contract.encode_call_contract_bytes("get", &[]).unwrap(),
|
||||
&contract_addr,
|
||||
&deployer,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(&get_result.out, &to_be_bytes(&U256::from(40)));
|
||||
println!("{:?}", get_result);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue