Parcourir la source

migrate to new API

narodnik il y a 5 ans
Parent
commit
2f4983f97a
9 fichiers modifiés avec 95 ajouts et 48 suppressions
  1. 1 0
      Cargo.toml
  2. 5 0
      run_jubjub.sh
  3. 14 0
      scripts/compile_export_supervisor.py
  4. 9 13
      src/bin/jubjub.rs
  5. 1 1
      src/bin/mint.rs
  6. 14 0
      src/error.rs
  7. 46 31
      src/lib.rs
  8. 2 2
      src/vm.rs
  9. 3 1
      src/vm_serial.rs

+ 1 - 0
Cargo.toml

@@ -26,6 +26,7 @@ sha2 = "0.9.1"
 rand_xorshift = "0.2"
 blake2s_simd = "0.5"
 bitvec = "0.18"
+bimap = "0.5.2"
 
 hex = "0.4.2"
 

+ 5 - 0
run_jubjub.sh

@@ -0,0 +1,5 @@
+#!/bin/bash -x
+python scripts/preprocess.py proofs/jubjub.psm > /tmp/jubjub.psm || exit $?
+python scripts/compile.py --supervisor /tmp/jubjub.psm --output jubjub.zcd || exit $?
+cargo run --release --bin jubjub
+

+ 14 - 0
scripts/compile_export_supervisor.py

@@ -175,3 +175,17 @@ def export(output, contract_name, contract):
         output.write(symbol)
         output.write(struct.pack("<I", variable.index))
 
+    # Public Map
+    public_alloc = [(symbol, variable) for (symbol, variable)
+                    in contract.alloc.items()
+                    if variable.type.name == VariableType.PUBLIC.name]
+    output.write(varuint(len(public_alloc)))
+    for symbol, variable in public_alloc:
+        assert not variable.is_param
+        assert variable.type.name == VariableType.PUBLIC.name
+        print("Public '%s' = %s" % (symbol, variable.index))
+        symbol = symbol.encode()
+        output.write(varuint(len(symbol)))
+        output.write(symbol)
+        output.write(struct.pack("<I", variable.index))
+

+ 9 - 13
src/bin/jubjub.rs

@@ -15,7 +15,7 @@ fn main() -> Result<()> {
     let mut visor = ZKSupervisor::decode(file)?;
     println!("{}", visor.name);
     //ZKSupervisor::load_contract(bytes);
-    println!("Finished: [{:?}]", start.elapsed());
+    println!("Loaded contract: [{:?}]", start.elapsed());
 
     println!("Stats:");
     println!("    Constants: {}", visor.vm.constants.len());
@@ -26,7 +26,7 @@ fn main() -> Result<()> {
         visor.vm.constraints.len()
     );
 
-    visor.vm.setup();
+    visor.setup();
 
     visor.set_param(
         "x1",
@@ -45,27 +45,23 @@ fn main() -> Result<()> {
         Scalar::from_string("015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"),
     )?;
 
-    visor.vm.initialize(&visor.params.into_iter().collect());
+    let proof = visor.prove()?;
 
-    let proof = visor.vm.prove();
-
-    let public = visor.vm.public();
-
-    assert_eq!(public.len(), 2);
+    assert_eq!(proof.public.len(), 2);
     // 0x66ced46f14e5616d12b993f60a6e66558d6b6afe4c321ed212e0b9cfbd81061a
     assert_eq!(
-        public[0],
+        *proof.public.get("x3").unwrap(),
         Scalar::from_string("66ced46f14e5616d12b993f60a6e66558d6b6afe4c321ed212e0b9cfbd81061a")
     );
     // 0x4731570fdd57cf280eadc8946fa00df81112502e44e497e794ab9a221f1bcca
     assert_eq!(
-        public[1],
+        *proof.public.get("y3").unwrap(),
         Scalar::from_string("04731570fdd57cf280eadc8946fa00df81112502e44e497e794ab9a221f1bcca")
     );
-    println!("u = {:?}", public[0]);
-    println!("v = {:?}", public[1]);
+    println!("u = {:?}", proof.public.get("x3").unwrap());
+    println!("v = {:?}", proof.public.get("y3").unwrap());
 
-    assert!(visor.vm.verify(&proof, &public));
+    assert!(visor.verify(&proof));
 
     Ok(())
 }

+ 1 - 1
src/bin/mint.rs

@@ -45,7 +45,7 @@ fn main() -> Result<()> {
     let mut visor = ZKSupervisor::decode(file)?;
     println!("{}", visor.name);
     //ZKSupervisor::load_contract(bytes);
-    println!("Finished: [{:?}]", start.elapsed());
+    println!("Loaded contract: [{:?}]", start.elapsed());
 
     println!("Stats:");
     println!("    Constants: {}", visor.vm.constants.len());

+ 14 - 0
src/error.rs

@@ -1,5 +1,7 @@
 use std::fmt;
 
+use crate::vm::ZKVMError;
+
 pub type Result<T> = std::result::Result<T, Error>;
 
 #[derive(Debug)]
@@ -25,6 +27,9 @@ pub enum Error {
     BadOperationType,
     BadConstraintType,
     InvalidParamName,
+    MissingParams,
+    VMError(ZKVMError),
+    BadContract,
 }
 
 impl std::error::Error for Error {}
@@ -55,6 +60,9 @@ impl fmt::Display for Error {
             Error::BadOperationType => f.write_str("Bad operation type byte"),
             Error::BadConstraintType => f.write_str("Bad constraint type byte"),
             Error::InvalidParamName => f.write_str("Invalid param name"),
+            Error::MissingParams => f.write_str("Missing params"),
+            Error::VMError(_) => f.write_str("VM error"),
+            Error::BadContract => f.write_str("Contract is poorly defined"),
         }
     }
 }
@@ -64,3 +72,9 @@ impl From<std::io::Error> for Error {
         Error::Io(err)
     }
 }
+
+impl From<ZKVMError> for Error {
+    fn from(err: ZKVMError) -> Error {
+        Error::VMError(err)
+    }
+}

+ 46 - 31
src/lib.rs

@@ -1,5 +1,6 @@
-use bls12_381::Scalar;
-use std::collections::HashMap;
+use bellman::groth16;
+use bls12_381::{Bls12, Scalar};
+use std::collections::{HashMap, HashSet};
 
 pub mod bls_extensions;
 pub mod endian;
@@ -23,41 +24,22 @@ pub struct ZKSupervisor {
     pub vm: ZKVirtualMachine,
     params_map: HashMap<String, VariableIndex>,
     pub params: HashMap<VariableIndex, Scalar>,
-    public_map: HashMap<String, VariableIndex>,
+    public_map: bimap::BiMap<String, VariableIndex>,
 }
 
-struct ZKProof {
-    public_values: HashMap<String, Scalar>,
-    //proof:
+pub struct ZKProof {
+    pub public: HashMap<String, Scalar>,
+    pub proof: groth16::Proof<Bls12>
 }
 
 impl ZKSupervisor {
     // Just have a load() and save()
     // Load the contract, do the setup, save it...
 
-    pub fn load_contract(bytes: Bytes) -> Self {
-        Self {
-            name: "".to_string(),
-            vm: ZKVirtualMachine {
-                ops: Vec::new(),
-                aux: Vec::new(),
-                alloc: Vec::new(),
-                constraints: Vec::new(),
-                params: None,
-                verifying_key: None,
-                constants: Vec::new(),
-            },
-            params_map: HashMap::new(),
-            params: HashMap::new(),
-            public_map: HashMap::new(),
-        }
+    pub fn setup(&mut self) {
+        self.vm.setup();
     }
 
-    fn setup(&self) {}
-    fn save_setup(&self) {}
-
-    fn load_setup(&self) {}
-
     pub fn param_names(&self) -> Vec<String> {
         self.params_map.keys().cloned().collect()
     }
@@ -71,14 +53,47 @@ impl ZKSupervisor {
         }
     }
 
-    fn prove(&self) {
-        // error if params not all set
+    pub fn prove(&mut self) -> Result<ZKProof> {
+        // Error if params not all set
+        let user_params: HashSet<_> = self.params.keys().collect();
+        let req_params: HashSet<_> = self.params_map.values().collect();
+        if user_params != req_params {
+            return Err(Error::MissingParams);
+        }
 
         // execute
+        let params = std::mem::replace(&mut self.params, HashMap::default());
+        self.vm.initialize(&params.into_iter().collect())?;
+
         // prove
+        let proof = self.vm.prove();
+
+        let mut public = HashMap::new();
+        for (index, value) in self.vm.public() {
+            match self.public_map.get_by_right(&index) {
+                Some(name) => { public.insert(name.clone(), value); },
+                None => return Err(Error::BadContract)
+            }
+        }
+
         // return proof and public values (Hashmap string -> scalars)
+        Ok(ZKProof {
+            public,
+            proof
+        })
     }
-    fn verify(&self) {
-        // takes proof and public values
+    pub fn verify(&self, proof: &ZKProof) -> bool {
+        let mut public = vec![];
+        for (name, value) in &proof.public {
+            match self.public_map.get_by_left(name) {
+                Some(index) => { public.push((index, value.clone())); },
+                None => return false
+            }
+        }
+        public.sort_by(|a, b| a.0.partial_cmp(b.0).unwrap());
+        let (_, public): (Vec<VariableIndex>, Vec<Scalar>) = public.into_iter().unzip();
+
+        // Takes proof and public values
+        self.vm.verify(&proof.proof, &public)
     }
 }

+ 2 - 2
src/vm.rs

@@ -269,14 +269,14 @@ impl ZKVirtualMachine {
         Ok(())
     }
 
-    pub fn public(&self) -> Vec<Scalar> {
+    pub fn public(&self) -> Vec<(VariableIndex, Scalar)> {
         let mut publics = Vec::new();
         for (alloc_type, index) in &self.alloc {
             match alloc_type {
                 AllocType::Private => {}
                 AllocType::Public => {
                     let scalar = self.aux[*index].clone();
-                    publics.push(scalar);
+                    publics.push((*index, scalar));
                 }
             }
         }

+ 3 - 1
src/vm_serial.rs

@@ -34,7 +34,9 @@ impl Decodable for ZKSupervisor {
             params_map: Vec::<(String, VariableIndex)>::decode(&mut d)?
                 .into_iter()
                 .collect(),
-            public_map: HashMap::new(),
+            public_map: Vec::<(String, VariableIndex)>::decode(&mut d)?
+                .into_iter()
+                .collect(),
 
             params: HashMap::new(),
         })