Procházet zdrojové kódy

initial mint contract

narodnik před 5 roky
rodič
revize
fbd0653c5d
6 změnil soubory, kde provedl 246 přidání a 8 odebrání
  1. 4 0
      Cargo.toml
  2. 23 0
      proofs/mint.aux
  3. 43 0
      proofs/mint.pism
  4. 6 0
      proofs/simple.aux
  5. 162 0
      src/mint.rs
  6. 8 8
      src/simple.rs

+ 4 - 0
Cargo.toml

@@ -47,3 +47,7 @@ path = "src/zec.rs"
 name = "simple"
 path = "src/simple.rs"
 
+[[bin]]
+name = "mint"
+path = "src/mint.rs"
+

+ 23 - 0
proofs/mint.aux

@@ -0,0 +1,23 @@
+{
+    "constants": {
+        "G_SPEND": {
+            "maps_to": "zcash_proofs::constants::SPENDING_KEY_GENERATOR"
+        },
+        "CRH_IVK": {
+            "maps_to": "zcash_primitives::constants::CRH_IVK_PERSONALIZATION"
+        },
+        "G_VCV": {
+            "maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR"
+        },
+        "G_VCR": {
+            "maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR"
+        },
+        "JUBJUB_FR_CAPACITY": {
+            "maps_to": "jubjub::Fr::CAPACITY as usize"
+        },
+        "NOTE_COMMIT": {
+            "maps_to": "pedersen_hash::Personalization::NoteCommitment"
+        }
+    }
+}
+

+ 43 - 0
proofs/mint.pism

@@ -0,0 +1,43 @@
+# :set syntax=pism
+# :source ../scripts/pism.vim
+constant G_VCV FixedGenerator
+constant G_VCR FixedGenerator
+constant CRH_IVK BlakePersonalization
+#constant JUBJUB_FR_CAPACITY BinarySize
+#constant NOTE_COMMIT PedersenPersonalization
+
+contract mint_contract
+    # Value commitment
+    param value U64
+    param randomness_value Fr
+
+    param serial Fr
+    param randomness_coin Fr
+
+    param public Point
+start
+    u64_as_binary_le value param:value
+    fr_as_binary_le randomness_value param:randomness_value
+    fr_as_binary_le serial param:serial
+    fr_as_binary_le randomness_coin param:randomness_coin
+
+    witness public param:public
+    assert_not_small_order public
+
+    ec_mul_const vcv value G_VCV
+    ec_mul_const rcv randomness_value G_VCR
+    ec_add cv vcv rcv
+    # emit cv
+    emit_ec cv
+
+    alloc_binary preimage
+    ec_repr repr_public public
+    binary_extend preimage repr_public
+    #binary_extend preimage value
+    #binary_extend preimage serial
+    #binary_extend preimage randomness_coin
+    #static_assert_binary_size preimage 824
+    blake2s coin preimage CRH_IVK
+    emit_binary coin
+end
+

+ 6 - 0
proofs/simple.aux

@@ -3,6 +3,12 @@
         "G_SPEND": {
             "maps_to": "zcash_proofs::constants::SPENDING_KEY_GENERATOR"
         },
+        "G_VCV": {
+            "maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR"
+        },
+        "G_VCR": {
+            "maps_to": "zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR"
+        },
         "CRH_IVK": {
             "maps_to": "zcash_primitives::constants::CRH_IVK_PERSONALIZATION"
         },

+ 162 - 0
src/mint.rs

@@ -0,0 +1,162 @@
+use bellman::gadgets::multipack;
+use bellman::groth16;
+use blake2s_simd::Params as Blake2sParams;
+use bls12_381::Bls12;
+use ff::Field;
+use group::{Curve, Group, GroupEncoding};
+
+mod mint_contract;
+use mint_contract::MintContract;
+
+struct MintRevealedValues {
+    value_commit: jubjub::SubgroupPoint,
+    coin: [u8; 32]
+}
+
+impl MintRevealedValues {
+    fn compute(
+        value: u64,
+        randomness_value: &jubjub::Fr,
+        serial: &jubjub::Fr,
+        randomness_coin: &jubjub::Fr,
+        public: &jubjub::SubgroupPoint,
+    ) -> Self {
+        let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
+            * jubjub::Fr::from(value))
+            + (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR
+                * randomness_value);
+
+        let mut coin = [0; 32];
+        coin.copy_from_slice(
+            Blake2sParams::new()
+                .hash_length(32)
+                .personal(zcash_primitives::constants::CRH_IVK_PERSONALIZATION)
+                .to_state()
+                .update(&public.to_bytes())
+                //.update(&value.to_bytes())
+                //.update(&serial.to_bytes())
+                //.update(&randomness_coin.to_bytes())
+                .finalize()
+                .as_bytes(),
+        );
+
+        MintRevealedValues { value_commit, coin }
+    }
+
+    fn make_outputs(&self) -> [bls12_381::Scalar; 4] {
+        let mut public_input = [bls12_381::Scalar::zero(); 4];
+
+        {
+            let result = jubjub::ExtendedPoint::from(self.value_commit);
+            let affine = result.to_affine();
+            //let (u, v) = (affine.get_u(), affine.get_v());
+            let u = affine.get_u();
+            let v = affine.get_v();
+            public_input[0] = u;
+            public_input[1] = v;
+        }
+
+        {
+            // Pack the hash as inputs for proof verification.
+            let hash = multipack::bytes_to_bits_le(&self.coin);
+            let hash = multipack::compute_multipacking(&hash);
+
+            // There are 2 chunks for a blake hash
+            assert_eq!(hash.len(), 2);
+
+            public_input[2] = hash[0];
+            public_input[3] = hash[1];
+        }
+
+        public_input
+    }
+}
+
+fn main() {
+    use std::time::Instant;
+    use rand::rngs::OsRng;
+
+    let public = jubjub::SubgroupPoint::random(&mut OsRng);
+
+    let value = 110;
+    let randomness_value: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+
+    let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+    let randomness_coin: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+
+    let revealed =
+        MintRevealedValues::compute(value, &randomness_value, &serial, &randomness_coin, &public);
+
+    let start = Instant::now();
+    let params = {
+        let c = MintContract {
+            value: None,
+            randomness_value: None,
+            serial: None,
+            randomness_coin: None,
+            public: None,
+        };
+        groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
+    };
+    let pvk = groth16::prepare_verifying_key(&params.vk);
+    println!("Setup: [{:?}]", start.elapsed());
+
+    let c = MintContract {
+        value: Some(value),
+        randomness_value: Some(randomness_value),
+        serial: Some(serial),
+        randomness_coin: Some(randomness_coin),
+        public: Some(public),
+    };
+
+    let start = Instant::now();
+    let proof = groth16::create_random_proof(c, &params, &mut OsRng).unwrap();
+    println!("Prove: [{:?}]", start.elapsed());
+
+    /*
+    let mut public_input = [bls12_381::Scalar::zero(); 4];
+    {
+        let result = jubjub::ExtendedPoint::from(public);
+        let affine = result.to_affine();
+        //let (u, v) = (affine.get_u(), affine.get_v());
+        let u = affine.get_u();
+        let v = affine.get_v();
+        public_input[0] = u;
+        public_input[1] = v;
+    }
+
+    {
+        const CRH_IVK_PERSONALIZATION: &[u8; 8] = b"Zcashivk";
+        let preimage = [42; 80];
+        let hash_result = {
+            let mut hash = [0; 32];
+            hash.copy_from_slice(
+                Blake2sParams::new()
+                .hash_length(32)
+                .personal(CRH_IVK_PERSONALIZATION)
+                .to_state()
+                .update(&ak.to_bytes())
+                .finalize()
+                .as_bytes()
+            );
+            hash
+        };
+
+        // Pack the hash as inputs for proof verification.
+        let hash = multipack::bytes_to_bits_le(&hash_result);
+        let hash = multipack::compute_multipacking(&hash);
+
+        // There are 2 chunks for a blake hash
+        assert_eq!(hash.len(), 2);
+
+        public_input[2] = hash[0];
+        public_input[3] = hash[1];
+    }
+    */
+
+    let public_input = revealed.make_outputs();
+
+    let start = Instant::now();
+    assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
+    println!("Verify: [{:?}]", start.elapsed());
+}

+ 8 - 8
src/simple.rs

@@ -1,9 +1,9 @@
-use bellman::groth16;
 use bellman::gadgets::multipack;
+use bellman::groth16;
+use blake2s_simd::Params as Blake2sParams;
 use bls12_381::Bls12;
 use ff::Field;
 use group::{Curve, Group, GroupEncoding};
-use blake2s_simd::Params as Blake2sParams;
 
 mod simple_circuit;
 use simple_circuit::InputSpend;
@@ -56,12 +56,12 @@ fn main() {
             let mut hash = [0; 32];
             hash.copy_from_slice(
                 Blake2sParams::new()
-                .hash_length(32)
-                .personal(CRH_IVK_PERSONALIZATION)
-                .to_state()
-                .update(&ak.to_bytes())
-                .finalize()
-                .as_bytes()
+                    .hash_length(32)
+                    .personal(CRH_IVK_PERSONALIZATION)
+                    .to_state()
+                    .update(&ak.to_bytes())
+                    .finalize()
+                    .as_bytes(),
             );
             hash
         };