rename lcX_add_one_coeff to lcX_add_constant, and add mimc example

This commit is contained in:
narodnik
2020-10-12 22:27:12 +02:00
parent f55ba1569f
commit 15dffe950d
8 changed files with 145 additions and 24 deletions

View File

@@ -44,7 +44,7 @@ name = "pedersen_hash"
path = "src/pedersen_hash.rs"
[[bin]]
name = "mimc"
name = "oldmimc"
path = "src/mimc.rs"
[[bin]]
@@ -88,8 +88,8 @@ name = "bits"
path = "src/bits.rs"
[[bin]]
name = "zkmimc"
path = "src/zkmimc.rs"
name = "mimc"
path = "src/bin/mimc.rs"
[[bin]]
name = "mint2"

View File

@@ -20,9 +20,9 @@ contract mimc
square tmp_{{i}}
lc0_add left_{{i}}
lc0_add_one_coeff mimc_constant_{{i}}
lc0_add_constant mimc_constant_{{i}}
lc1_add left_{{i}}
lc1_add_one_coeff mimc_constant_{{i}}
lc1_add_constant mimc_constant_{{i}}
lc2_add tmp_{{i}}
enforce
@@ -37,7 +37,7 @@ contract mimc
lc0_add tmp_{{i}}
lc1_add left_{{i}}
lc1_add_one_coeff mimc_constant_{{i}}
lc1_add_constant mimc_constant_{{i}}
lc2_add left_{{i+1}}
lc2_sub {{ns.right}}
enforce

View File

@@ -41,9 +41,9 @@ constraint_commands = {
"lc0_add_coeff": 2,
"lc1_add_coeff": 2,
"lc2_add_coeff": 2,
"lc0_add_one_coeff": 1,
"lc1_add_one_coeff": 1,
"lc2_add_one_coeff": 1,
"lc0_add_constant": 1,
"lc1_add_constant": 1,
"lc2_add_constant": 1,
"enforce": 0,
"lc_coeff_reset": 0,
"lc_coeff_double": 0,

View File

@@ -63,9 +63,9 @@ constraint_ident_map = {
"lc0_add_coeff": 12,
"lc1_add_coeff": 13,
"lc2_add_coeff": 14,
"lc0_add_one_coeff": 15,
"lc1_add_one_coeff": 16,
"lc2_add_one_coeff": 17,
"lc0_add_constant": 15,
"lc1_add_constant": 16,
"lc2_add_constant": 17,
"enforce": 18,
"lc_coeff_reset": 19,
"lc_coeff_double": 20,
@@ -154,9 +154,9 @@ def export(output, contract_name, contract):
if (constraint.command == "lc0_add_coeff" or
constraint.command == "lc1_add_coeff" or
constraint.command == "lc2_add_coeff" or
constraint.command == "lc0_add_one_coeff" or
constraint.command == "lc1_add_one_coeff" or
constraint.command == "lc2_add_one_coeff"):
constraint.command == "lc0_add_constant" or
constraint.command == "lc1_add_constant" or
constraint.command == "lc2_add_constant"):
args[0] = args[0][0]
print("#", constraint.line)
print("Constraint", constraint.command, args if args else "")

121
src/bin/mimc.rs Normal file
View File

@@ -0,0 +1,121 @@
use bls12_381::Scalar;
use sapvi::{BlsStringConversion, Decodable, ZKContract};
use std::fs::File;
use std::time::Instant;
use ff::{Field, PrimeField};
use std::ops::{Add, AddAssign, MulAssign, Neg, SubAssign};
type Result<T> = std::result::Result<T, failure::Error>;
mod mimc_constants;
use mimc_constants::mimc_constants;
const MIMC_ROUNDS: usize = 322;
fn mimc(mut xl: Scalar, mut xr: Scalar, constants: &[Scalar]) -> Scalar {
assert_eq!(constants.len(), MIMC_ROUNDS);
for i in 0..MIMC_ROUNDS {
let mut tmp1 = xl;
tmp1.add_assign(&constants[i]);
let mut tmp2 = tmp1.square();
tmp2.mul_assign(&tmp1);
tmp2.add_assign(&xr);
xr = xl;
xl = tmp2;
}
xl
}
macro_rules! from_slice {
($data:expr, $len:literal) => {{
let mut array = [0; $len];
// panics if not enough data
let bytes = &$data[..array.len()];
assert_eq!(bytes.len(), array.len());
for (a, b) in array.iter_mut().rev().zip(bytes.iter()) {
*a = *b;
}
//array.copy_from_slice(bytes.iter().rev());
array
}};
}
fn main() -> Result<()> {
/////////////////////////////////
// Initialize our MiMC constants
let mut constants = Vec::new();
for const_str in mimc_constants() {
let bytes = from_slice!(&hex::decode(const_str).unwrap(), 32);
assert_eq!(bytes.len(), 32);
let constant = Scalar::from_bytes(&bytes).unwrap();
constants.push(constant);
}
/////////////////////////////////
// Load the contract from file
let start = Instant::now();
let file = File::open("mimc.zcd")?;
let mut contract = ZKContract::decode(file)?;
println!("Loaded contract '{}': [{:?}]", contract.name, start.elapsed());
println!("Stats:");
println!(" Constants: {}", contract.vm.constants.len());
println!(" Alloc: {}", contract.vm.alloc.len());
println!(" Operations: {}", contract.vm.ops.len());
println!(
" Constraint Instructions: {}",
contract.vm.constraints.len()
);
// Do the trusted setup
contract.setup();
// Put in our input parameters
let left =
Scalar::from_raw([
0xb981_9dc8_2d90_607e,
0xa361_ee3f_d48f_df77,
0x52a3_5a8c_1908_dd87,
0x15a3_6d1f_0f39_0d88,
]);
let right = Scalar::from_raw([
0x7b0d_c53c_4ebf_1891,
0x1f3a_beeb_98fa_d3e8,
0xf789_1142_c001_d925,
0x015d_8c7f_5b43_fe33,
]);
contract.set_param(
"left_0", left.clone()
)?;
contract.set_param(
"right", right.clone()
)?;
// Generate the ZK proof
let proof = contract.prove()?;
// Test and show our output values
let mimc_hash = mimc(left,right, &constants);
assert_eq!(proof.public.len(), 1);
// 0x66ced46f14e5616d12b993f60a6e66558d6b6afe4c321ed212e0b9cfbd81061a
assert_eq!(
*proof.public.get("hash_result").unwrap(),
mimc_hash
);
println!("hash result = {:?}", proof.public.get("hash_result").unwrap());
// Verify the proof
assert!(contract.verify(&proof));
Ok(())
}

View File

@@ -72,9 +72,9 @@ pub enum ConstraintInstruction {
Lc0AddCoeff(VariableIndex, VariableIndex),
Lc1AddCoeff(VariableIndex, VariableIndex),
Lc2AddCoeff(VariableIndex, VariableIndex),
Lc0AddOneCoeff(VariableIndex),
Lc1AddOneCoeff(VariableIndex),
Lc2AddOneCoeff(VariableIndex),
Lc0AddConstant(VariableIndex),
Lc1AddConstant(VariableIndex),
Lc2AddConstant(VariableIndex),
Enforce,
LcCoeffReset,
LcCoeffDouble,
@@ -412,13 +412,13 @@ impl Circuit<bls12_381::Scalar> for ZKVMCircuit {
ConstraintInstruction::Lc2AddCoeff(const_index, index) => {
lc2 = lc2 + (self.constants[const_index], variables[index]);
}
ConstraintInstruction::Lc0AddOneCoeff(const_index) => {
ConstraintInstruction::Lc0AddConstant(const_index) => {
lc0 = lc0 + (self.constants[const_index], CS::one());
}
ConstraintInstruction::Lc1AddOneCoeff(const_index) => {
ConstraintInstruction::Lc1AddConstant(const_index) => {
lc1 = lc1 + (self.constants[const_index], CS::one());
}
ConstraintInstruction::Lc2AddOneCoeff(const_index) => {
ConstraintInstruction::Lc2AddConstant(const_index) => {
lc2 = lc2 + (self.constants[const_index], CS::one());
}
ConstraintInstruction::Enforce => {

View File

@@ -190,9 +190,9 @@ impl Decodable for ConstraintInstruction {
Decodable::decode(&mut d)?,
Decodable::decode(&mut d)?,
)),
15 => Ok(Self::Lc0AddOneCoeff(Decodable::decode(&mut d)?)),
16 => Ok(Self::Lc1AddOneCoeff(Decodable::decode(&mut d)?)),
17 => Ok(Self::Lc2AddOneCoeff(Decodable::decode(&mut d)?)),
15 => Ok(Self::Lc0AddConstant(Decodable::decode(&mut d)?)),
16 => Ok(Self::Lc1AddConstant(Decodable::decode(&mut d)?)),
17 => Ok(Self::Lc2AddConstant(Decodable::decode(&mut d)?)),
18 => Ok(Self::Enforce),
19 => Ok(Self::LcCoeffReset),
20 => Ok(Self::LcCoeffDouble),