From b813bd1b0e98e65f28019fa07d960402d73f2d92 Mon Sep 17 00:00:00 2001 From: narodnik Date: Thu, 29 Apr 2021 13:46:07 +0200 Subject: [PATCH] spend_contract --- Cargo.toml | 4 + src/{old/spend.rs => bin/spend-classic.rs} | 3 +- src/circuit/mod.rs | 1 + src/circuit/spend_contract.rs | 440 +++++++++++++++++++++ 4 files changed, 446 insertions(+), 2 deletions(-) rename src/{old/spend.rs => bin/spend-classic.rs} (99%) create mode 100644 src/circuit/spend_contract.rs diff --git a/Cargo.toml b/Cargo.toml index 8a39f292b..9e012172f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,6 +96,10 @@ path = "src/old/mimc.rs" name = "mint-classic" path = "src/bin/mint-classic.rs" +[[bin]] +name = "spend-classic" +path = "src/bin/spend-classic.rs" + [[bin]] name = "dfg" path = "src/bin/dfg.rs" diff --git a/src/old/spend.rs b/src/bin/spend-classic.rs similarity index 99% rename from src/old/spend.rs rename to src/bin/spend-classic.rs index 7a417a6e4..dad16d4d4 100644 --- a/src/old/spend.rs +++ b/src/bin/spend-classic.rs @@ -6,8 +6,7 @@ use bls12_381::Bls12; use ff::{Field, PrimeField}; use group::{Curve, GroupEncoding}; -mod spend_contract; -use spend_contract::SpendContract; +use sapvi::circuit::spend_contract::SpendContract; // This thing is nasty lol pub fn merkle_hash( diff --git a/src/circuit/mod.rs b/src/circuit/mod.rs index aa7ed0afd..17a8b15c3 100644 --- a/src/circuit/mod.rs +++ b/src/circuit/mod.rs @@ -1,2 +1,3 @@ pub mod mint_contract; +pub mod spend_contract; diff --git a/src/circuit/spend_contract.rs b/src/circuit/spend_contract.rs new file mode 100644 index 000000000..a010319ed --- /dev/null +++ b/src/circuit/spend_contract.rs @@ -0,0 +1,440 @@ +#![allow(unused_imports)] +#![allow(unused_mut)] +use bellman::{ + gadgets::{ + blake2s, boolean, + boolean::{AllocatedBit, Boolean}, + multipack, num, Assignment, + }, + groth16, Circuit, ConstraintSystem, SynthesisError, +}; +use bls12_381::Bls12; +use ff::{Field, PrimeField}; +use group::Curve; +use zcash_proofs::circuit::{ecc, pedersen_hash}; + +pub struct SpendContract { + pub value: Option, + pub randomness_value: Option, + pub serial: Option, + pub randomness_coin: Option, + pub secret: Option, + pub branch_0: Option, + pub is_right_0: Option, + pub branch_1: Option, + pub is_right_1: Option, + pub branch_2: Option, + pub is_right_2: Option, + pub branch_3: Option, + pub is_right_3: Option, +} +impl Circuit for SpendContract { + fn synthesize>( + self, + cs: &mut CS, + ) -> Result<(), SynthesisError> { + // Line 40: u64_as_binary_le value param:value + let value = boolean::u64_into_boolean_vec_le( + cs.namespace(|| "Line 40: u64_as_binary_le value param:value"), + self.value, + )?; + + // Line 41: fr_as_binary_le randomness_value param:randomness_value + let randomness_value = boolean::field_into_boolean_vec_le( + cs.namespace(|| "Line 41: fr_as_binary_le randomness_value param:randomness_value"), + self.randomness_value, + )?; + + // Line 46: ec_mul_const vcv value G_VCV + let vcv = ecc::fixed_base_multiplication( + cs.namespace(|| "Line 46: ec_mul_const vcv value G_VCV"), + &zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR, + &value, + )?; + + // Line 47: ec_mul_const rcv randomness_value G_VCR + let rcv = ecc::fixed_base_multiplication( + cs.namespace(|| "Line 47: ec_mul_const rcv randomness_value G_VCR"), + &zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR, + &randomness_value, + )?; + + // Line 48: ec_add cv vcv rcv + let cv = vcv.add(cs.namespace(|| "Line 48: ec_add cv vcv rcv"), &rcv)?; + + // Line 50: emit_ec cv + cv.inputize(cs.namespace(|| "Line 50: emit_ec cv"))?; + + // Line 54: fr_as_binary_le serial param:serial + let serial = boolean::field_into_boolean_vec_le( + cs.namespace(|| "Line 54: fr_as_binary_le serial param:serial"), + self.serial, + )?; + + // Line 55: fr_as_binary_le secret param:secret + let secret = boolean::field_into_boolean_vec_le( + cs.namespace(|| "Line 55: fr_as_binary_le secret param:secret"), + self.secret, + )?; + + // Line 57: alloc_binary nf_preimage + let mut nf_preimage = vec![]; + + // Line 64: binary_clone secret2 secret + let mut secret2: Vec<_> = secret.iter().cloned().collect(); + + // Line 65: binary_extend nf_preimage secret2 + nf_preimage.extend(secret2); + + // Line 67: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 68: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 70: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 71: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 73: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 74: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 76: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 77: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 81: binary_clone serial2 serial + let mut serial2: Vec<_> = serial.iter().cloned().collect(); + + // Line 82: binary_extend nf_preimage serial2 + nf_preimage.extend(serial2); + + // Line 84: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 85: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 87: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 88: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 90: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 91: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 93: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 94: binary_push nf_preimage zero_bit + nf_preimage.push(zero_bit); + + // Line 100: static_assert_binary_size nf_preimage 512 + assert_eq!(nf_preimage.len(), 512); + + // Line 101: blake2s nf nf_preimage PRF_NF + let mut nf = blake2s::blake2s( + cs.namespace(|| "Line 101: blake2s nf nf_preimage PRF_NF"), + &nf_preimage, + zcash_primitives::constants::PRF_NF_PERSONALIZATION, + )?; + + // Line 102: emit_binary nf + multipack::pack_into_inputs(cs.namespace(|| "Line 102: emit_binary nf"), &nf)?; + + // Line 106: ec_mul_const public secret G_SPEND + let public = ecc::fixed_base_multiplication( + cs.namespace(|| "Line 106: ec_mul_const public secret G_SPEND"), + &zcash_proofs::constants::SPENDING_KEY_GENERATOR, + &secret, + )?; + + // Line 110: fr_as_binary_le randomness_coin param:randomness_coin + let randomness_coin = boolean::field_into_boolean_vec_le( + cs.namespace(|| "Line 110: fr_as_binary_le randomness_coin param:randomness_coin"), + self.randomness_coin, + )?; + + // Line 113: alloc_binary preimage + let mut preimage = vec![]; + + // Line 116: ec_repr repr_public public + let repr_public = public.repr(cs.namespace(|| "Line 116: ec_repr repr_public public"))?; + + // Line 117: binary_extend preimage repr_public + preimage.extend(repr_public); + + // Line 120: binary_extend preimage value + preimage.extend(value); + + // Line 123: binary_extend preimage serial + preimage.extend(serial); + + // Line 125: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 126: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 128: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 129: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 131: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 132: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 134: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 135: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 139: binary_extend preimage randomness_coin + preimage.extend(randomness_coin); + + // Line 141: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 142: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 144: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 145: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 147: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 148: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 150: alloc_const_bit zero_bit false + let zero_bit = Boolean::constant(false); + + // Line 151: binary_push preimage zero_bit + preimage.push(zero_bit); + + // Line 159: static_assert_binary_size preimage 832 + assert_eq!(preimage.len(), 832); + + // Line 160: blake2s coin preimage CRH_IVK + let mut coin = blake2s::blake2s( + cs.namespace(|| "Line 160: blake2s coin preimage CRH_IVK"), + &preimage, + zcash_primitives::constants::CRH_IVK_PERSONALIZATION, + )?; + + // Line 166: pedersen_hash cm coin NOTE_COMMIT + let mut cm = pedersen_hash::pedersen_hash( + cs.namespace(|| "Line 166: pedersen_hash cm coin NOTE_COMMIT"), + pedersen_hash::Personalization::NoteCommitment, + &coin, + )?; + + // Line 168: ec_get_u current cm + let mut current = cm.get_u().clone(); + + // Line 174: alloc_scalar branch param:branch_0 + let branch = num::AllocatedNum::alloc( + cs.namespace(|| "Line 174: alloc_scalar branch param:branch_0"), + || Ok(*self.branch_0.get()?), + )?; + + // Line 177: alloc_bit is_right param:is_right_0 + let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc( + cs.namespace(|| "Line 177: alloc_bit is_right param:is_right_0"), + self.is_right_0, + )?); + + // Line 180: conditionally_reverse left right current branch is_right + let (left, right) = num::AllocatedNum::conditionally_reverse( + cs.namespace(|| "Line 180: conditionally_reverse left right current branch is_right"), + ¤t, + &branch, + &is_right, + )?; + + // Line 183: scalar_as_binary left left + let left = left.to_bits_le(cs.namespace(|| "Line 183: scalar_as_binary left left"))?; + + // Line 184: scalar_as_binary right right + let right = right.to_bits_le(cs.namespace(|| "Line 184: scalar_as_binary right right"))?; + + // Line 185: alloc_binary preimage + let mut preimage = vec![]; + + // Line 186: binary_extend preimage left + preimage.extend(left); + + // Line 187: binary_extend preimage right + preimage.extend(right); + + // Line 188: pedersen_hash cm preimage MERKLE_0 + let mut cm = pedersen_hash::pedersen_hash( + cs.namespace(|| "Line 188: pedersen_hash cm preimage MERKLE_0"), + pedersen_hash::Personalization::MerkleTree(0), + &preimage, + )?; + + // Line 190: ec_get_u current cm + let mut current = cm.get_u().clone(); + + // Line 194: alloc_scalar branch param:branch_1 + let branch = num::AllocatedNum::alloc( + cs.namespace(|| "Line 194: alloc_scalar branch param:branch_1"), + || Ok(*self.branch_1.get()?), + )?; + + // Line 197: alloc_bit is_right param:is_right_1 + let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc( + cs.namespace(|| "Line 197: alloc_bit is_right param:is_right_1"), + self.is_right_1, + )?); + + // Line 200: conditionally_reverse left right current branch is_right + let (left, right) = num::AllocatedNum::conditionally_reverse( + cs.namespace(|| "Line 200: conditionally_reverse left right current branch is_right"), + ¤t, + &branch, + &is_right, + )?; + + // Line 203: scalar_as_binary left left + let left = left.to_bits_le(cs.namespace(|| "Line 203: scalar_as_binary left left"))?; + + // Line 204: scalar_as_binary right right + let right = right.to_bits_le(cs.namespace(|| "Line 204: scalar_as_binary right right"))?; + + // Line 205: alloc_binary preimage + let mut preimage = vec![]; + + // Line 206: binary_extend preimage left + preimage.extend(left); + + // Line 207: binary_extend preimage right + preimage.extend(right); + + // Line 208: pedersen_hash cm preimage MERKLE_1 + let mut cm = pedersen_hash::pedersen_hash( + cs.namespace(|| "Line 208: pedersen_hash cm preimage MERKLE_1"), + pedersen_hash::Personalization::MerkleTree(1), + &preimage, + )?; + + // Line 210: ec_get_u current cm + let mut current = cm.get_u().clone(); + + // Line 214: alloc_scalar branch param:branch_2 + let branch = num::AllocatedNum::alloc( + cs.namespace(|| "Line 214: alloc_scalar branch param:branch_2"), + || Ok(*self.branch_2.get()?), + )?; + + // Line 217: alloc_bit is_right param:is_right_2 + let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc( + cs.namespace(|| "Line 217: alloc_bit is_right param:is_right_2"), + self.is_right_2, + )?); + + // Line 220: conditionally_reverse left right current branch is_right + let (left, right) = num::AllocatedNum::conditionally_reverse( + cs.namespace(|| "Line 220: conditionally_reverse left right current branch is_right"), + ¤t, + &branch, + &is_right, + )?; + + // Line 223: scalar_as_binary left left + let left = left.to_bits_le(cs.namespace(|| "Line 223: scalar_as_binary left left"))?; + + // Line 224: scalar_as_binary right right + let right = right.to_bits_le(cs.namespace(|| "Line 224: scalar_as_binary right right"))?; + + // Line 225: alloc_binary preimage + let mut preimage = vec![]; + + // Line 226: binary_extend preimage left + preimage.extend(left); + + // Line 227: binary_extend preimage right + preimage.extend(right); + + // Line 228: pedersen_hash cm preimage MERKLE_2 + let mut cm = pedersen_hash::pedersen_hash( + cs.namespace(|| "Line 228: pedersen_hash cm preimage MERKLE_2"), + pedersen_hash::Personalization::MerkleTree(2), + &preimage, + )?; + + // Line 230: ec_get_u current cm + let mut current = cm.get_u().clone(); + + // Line 234: alloc_scalar branch param:branch_3 + let branch = num::AllocatedNum::alloc( + cs.namespace(|| "Line 234: alloc_scalar branch param:branch_3"), + || Ok(*self.branch_3.get()?), + )?; + + // Line 237: alloc_bit is_right param:is_right_3 + let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc( + cs.namespace(|| "Line 237: alloc_bit is_right param:is_right_3"), + self.is_right_3, + )?); + + // Line 240: conditionally_reverse left right current branch is_right + let (left, right) = num::AllocatedNum::conditionally_reverse( + cs.namespace(|| "Line 240: conditionally_reverse left right current branch is_right"), + ¤t, + &branch, + &is_right, + )?; + + // Line 243: scalar_as_binary left left + let left = left.to_bits_le(cs.namespace(|| "Line 243: scalar_as_binary left left"))?; + + // Line 244: scalar_as_binary right right + let right = right.to_bits_le(cs.namespace(|| "Line 244: scalar_as_binary right right"))?; + + // Line 245: alloc_binary preimage + let mut preimage = vec![]; + + // Line 246: binary_extend preimage left + preimage.extend(left); + + // Line 247: binary_extend preimage right + preimage.extend(right); + + // Line 248: pedersen_hash cm preimage MERKLE_3 + let mut cm = pedersen_hash::pedersen_hash( + cs.namespace(|| "Line 248: pedersen_hash cm preimage MERKLE_3"), + pedersen_hash::Personalization::MerkleTree(3), + &preimage, + )?; + + // Line 250: ec_get_u current cm + let mut current = cm.get_u().clone(); + + // Line 253: emit_scalar current + current.inputize(cs.namespace(|| "Line 253: emit_scalar current"))?; + + Ok(()) + } +}