Explorar el Código

basic minimal ZK pure homegrown with tegridy

narodnik hace 5 años
padre
commit
9f3058fe21
Se han modificado 3 ficheros con 169 adiciones y 6 borrados
  1. 4 0
      Cargo.toml
  2. 160 0
      src/basic_minimal.rs
  3. 5 6
      src/eq.rs

+ 4 - 0
Cargo.toml

@@ -60,3 +60,7 @@ path = "src/spend.rs"
 name = "eq"
 path = "src/eq.rs"
 
+[[bin]]
+name = "basic"
+path = "src/basic_minimal.rs"
+

+ 160 - 0
src/basic_minimal.rs

@@ -0,0 +1,160 @@
+use bellman::{
+    gadgets::{
+        boolean::{AllocatedBit, Boolean},
+        multipack, num, Assignment,
+    },
+    groth16, Circuit, ConstraintSystem, SynthesisError,
+};
+use bls12_381::Bls12;
+use bls12_381::Scalar;
+use ff::{Field, PrimeField};
+use group::Curve;
+use rand::rngs::OsRng;
+use std::ops::{Neg, SubAssign, MulAssign};
+
+pub const CRH_IVK_PERSONALIZATION: &[u8; 8] = b"Zcashivk";
+
+struct MyCircuit {
+    aux: Vec<Option<bls12_381::Scalar>>,
+}
+
+impl Circuit<bls12_381::Scalar> for MyCircuit {
+    fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
+        self,
+        cs: &mut CS,
+    ) -> Result<(), SynthesisError> {
+        //let x = num::AllocatedNum::alloc(cs.namespace(|| "conditional anchor"), || {
+        //    Ok(*self.aux_values[0].get()?)
+        //})?;
+
+        //let x2 = x.mul(cs.namespace(|| "x2"), &x)?;
+        //let x3 = x.mul(cs.namespace(|| "x2"), &x2)?;
+        //x3.inputize(cs.namespace(|| "pubx2"))?;
+
+        // ------------------
+
+        // x
+        let x_var = cs.alloc(
+            || "num",
+            || {
+                Ok(*self.aux[0].get()?)
+            },
+        )?;
+
+        let coeff = bls12_381::Scalar::one();
+        let lc0 = bellman::LinearCombination::zero() + (coeff, x_var);
+        let lc1 = bellman::LinearCombination::zero() + (coeff, CS::one());
+        let lc2 = bellman::LinearCombination::zero() + (coeff, x_var);
+
+        cs.enforce(
+            || "multiplication constraint",
+            |_| lc0,
+            |_| lc1,
+            |_| lc2,
+        );
+
+        // x2 = x * x
+
+        let x2_var = cs.alloc(
+            || "product num",
+            || {
+                Ok(*self.aux[1].get()?)
+            },
+        )?;
+
+        let coeff = bls12_381::Scalar::one();
+        let lc0 = bellman::LinearCombination::zero() + (coeff, x_var);
+        let lc1 = bellman::LinearCombination::zero() + (coeff, x_var);
+        let lc2 = bellman::LinearCombination::zero() + (coeff, x2_var);
+
+        cs.enforce(
+            || "multiplication constraint",
+            |_| lc0,
+            |_| lc1,
+            |_| lc2,
+        );
+
+        // x3 = x2 * x
+
+        let x3_var = cs.alloc(
+            || "product num",
+            || {
+                Ok(*self.aux[2].get()?)
+            },
+        )?;
+
+        let coeff = bls12_381::Scalar::one();
+        let lc0 = bellman::LinearCombination::zero() + (coeff, x2_var);
+        let lc1 = bellman::LinearCombination::zero() + (coeff, x_var);
+        let lc2 = bellman::LinearCombination::zero() + (coeff, x3_var);
+
+        cs.enforce(
+            || "multiplication constraint",
+            |_| lc0,
+            |_| lc1,
+            |_| lc2,
+        );
+
+        // inputize values
+
+        let input = cs.alloc_input(|| "input variable", || Ok(*self.aux[2].get()?))?;
+
+        let coeff = bls12_381::Scalar::one();
+        let lc0 = bellman::LinearCombination::zero() + (coeff, input);
+        let lc1 = bellman::LinearCombination::zero() + (coeff, CS::one());
+        let lc2 = bellman::LinearCombination::zero() + (coeff, x3_var);
+
+        cs.enforce(
+            || "enforce input is correct",
+            |_| lc0,
+            |_| lc1,
+            |_| lc2,
+        );
+
+        Ok(())
+    }
+}
+
+fn main() {
+    use std::time::Instant;
+
+    let start = Instant::now();
+    // Create parameters for our circuit. In a production deployment these would
+    // be generated securely using a multiparty computation.
+    let params = {
+        let c = MyCircuit {
+            aux: vec![None],
+        };
+        groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
+    };
+    println!("Setup: [{:?}]", start.elapsed());
+
+    // Prepare the verification key (for proof verification).
+    let pvk = groth16::prepare_verifying_key(&params.vk);
+
+    // Pick a preimage and compute its hash.
+    let quantity = bls12_381::Scalar::from(3);
+
+    // Create an instance of our circuit (with the preimage as a witness).
+    let c = MyCircuit {
+        aux: vec![
+            Some(quantity),
+            Some(quantity * quantity),
+            Some(quantity * quantity * quantity)
+        ],
+    };
+
+    let start = Instant::now();
+    // Create a Groth16 proof with our parameters.
+    let proof = groth16::create_random_proof(c, &params, &mut OsRng).unwrap();
+    println!("Prove: [{:?}]", start.elapsed());
+
+    let start = Instant::now();
+
+    let public_input = vec![bls12_381::Scalar::from(27)];
+
+    let start = Instant::now();
+    // Check the proof!
+    assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
+    println!("Verify: [{:?}]", start.elapsed());
+}

+ 5 - 6
src/eq.rs

@@ -73,14 +73,13 @@ impl Circuit<bls12_381::Scalar> for MyCircuit {
         let ungained = ungained.mul(cs.namespace(|| "ungained 2"), &exit_price_inv)?;
 
         // pnl = initial_margin - ungained
-        let pnl =
-            num::AllocatedNum::alloc(cs.namespace(|| "exit price inverse"), || {
-                let mut tmp = *initial_margin.get_value().get()?;
+        let pnl = num::AllocatedNum::alloc(cs.namespace(|| "exit price inverse"), || {
+            let mut tmp = *initial_margin.get_value().get()?;
 
-                tmp.sub_assign(ungained.get_value().get()?);
+            tmp.sub_assign(ungained.get_value().get()?);
 
-                Ok(tmp)
-            })?;
+            Ok(tmp)
+        })?;
 
         cs.enforce(
             || "constraint pnl calc",