소스 검색

zk: Handle invalid witnesses gracefully in empty_witnesses().

parazyd 3 년 전
부모
커밋
60595e3002

+ 8 - 8
bin/drk/src/rpc_dao.rs

@@ -74,7 +74,7 @@ impl Drk {
         };
 
         let dao_mint_zkbin = ZkBinary::decode(&dao_mint_zkbin.1)?;
-        let dao_mint_circuit = ZkCircuit::new(empty_witnesses(&dao_mint_zkbin), &dao_mint_zkbin);
+        let dao_mint_circuit = ZkCircuit::new(empty_witnesses(&dao_mint_zkbin)?, &dao_mint_zkbin);
         eprintln!("Creating DAO Mint proving key");
         let dao_mint_pk = ProvingKey::build(dao_mint_zkbin.k, &dao_mint_circuit);
 
@@ -163,9 +163,9 @@ impl Drk {
         let propose_main_zkbin = ZkBinary::decode(&propose_main_zkbin.1)?;
 
         let propose_burn_circuit =
-            ZkCircuit::new(empty_witnesses(&propose_burn_zkbin), &propose_burn_zkbin);
+            ZkCircuit::new(empty_witnesses(&propose_burn_zkbin)?, &propose_burn_zkbin);
         let propose_main_circuit =
-            ZkCircuit::new(empty_witnesses(&propose_main_zkbin), &propose_main_zkbin);
+            ZkCircuit::new(empty_witnesses(&propose_main_zkbin)?, &propose_main_zkbin);
 
         eprintln!("Creating Propose Burn circuit proving key");
         let propose_burn_pk = ProvingKey::build(propose_burn_zkbin.k, &propose_burn_circuit);
@@ -347,9 +347,9 @@ impl Drk {
         let dao_vote_main_zkbin = ZkBinary::decode(&dao_vote_main_zkbin.1)?;
 
         let dao_vote_burn_circuit =
-            ZkCircuit::new(empty_witnesses(&dao_vote_burn_zkbin), &dao_vote_burn_zkbin);
+            ZkCircuit::new(empty_witnesses(&dao_vote_burn_zkbin)?, &dao_vote_burn_zkbin);
         let dao_vote_main_circuit =
-            ZkCircuit::new(empty_witnesses(&dao_vote_main_zkbin), &dao_vote_main_zkbin);
+            ZkCircuit::new(empty_witnesses(&dao_vote_main_zkbin)?, &dao_vote_main_zkbin);
 
         eprintln!("Creating DAO Vote Burn proving key");
         let dao_vote_burn_pk = ProvingKey::build(dao_vote_burn_zkbin.k, &dao_vote_burn_circuit);
@@ -414,8 +414,8 @@ impl Drk {
         };
         let mint_zkbin = ZkBinary::decode(&mint_zkbin.1)?;
         let burn_zkbin = ZkBinary::decode(&burn_zkbin.1)?;
-        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin), &mint_zkbin);
-        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin), &burn_zkbin);
+        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin);
+        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin);
         eprintln!("Creating Money Mint circuit proving key");
         let mint_pk = ProvingKey::build(mint_zkbin.k, &mint_circuit);
         eprintln!("Creating Money Burn circuit proving key");
@@ -453,7 +453,7 @@ impl Drk {
             return Err(anyhow!("DAO Exec circuit not found"))
         };
         let exec_zkbin = ZkBinary::decode(&exec_zkbin.1)?;
-        let exec_circuit = ZkCircuit::new(empty_witnesses(&exec_zkbin), &exec_zkbin);
+        let exec_circuit = ZkCircuit::new(empty_witnesses(&exec_zkbin)?, &exec_zkbin);
         eprintln!("Creating DAO Exec circuit proving key");
         let exec_pk = ProvingKey::build(exec_zkbin.k, &exec_circuit);
 

+ 4 - 4
bin/drk/src/rpc_swap.rs

@@ -122,8 +122,8 @@ impl Drk {
         let mint_zkbin = ZkBinary::decode(&mint_zkbin.1)?;
         let burn_zkbin = ZkBinary::decode(&burn_zkbin.1)?;
 
-        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin), &mint_zkbin);
-        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin), &burn_zkbin);
+        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin);
+        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin);
 
         // Since we're creating the first half, we generate the blinds.
         let value_blinds = [pallas::Scalar::random(&mut OsRng), pallas::Scalar::random(&mut OsRng)];
@@ -215,8 +215,8 @@ impl Drk {
         let mint_zkbin = ZkBinary::decode(&mint_zkbin.1)?;
         let burn_zkbin = ZkBinary::decode(&burn_zkbin.1)?;
 
-        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin), &mint_zkbin);
-        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin), &burn_zkbin);
+        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin);
+        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin);
 
         // TODO: Maybe some kind of verification at this point
 

+ 2 - 2
bin/drk/src/rpc_token.rs

@@ -76,7 +76,7 @@ impl Drk {
 
         let token_mint_zkbin = ZkBinary::decode(&token_mint_zkbin.1)?;
         let token_mint_circuit =
-            ZkCircuit::new(empty_witnesses(&token_mint_zkbin), &token_mint_zkbin);
+            ZkCircuit::new(empty_witnesses(&token_mint_zkbin)?, &token_mint_zkbin);
 
         eprintln!("Creating token mint circuit proving keys");
         let token_mint_pk = ProvingKey::build(token_mint_zkbin.k, &token_mint_circuit);
@@ -129,7 +129,7 @@ impl Drk {
 
         let token_freeze_zkbin = ZkBinary::decode(&token_freeze_zkbin.1)?;
         let token_freeze_circuit =
-            ZkCircuit::new(empty_witnesses(&token_freeze_zkbin), &token_freeze_zkbin);
+            ZkCircuit::new(empty_witnesses(&token_freeze_zkbin)?, &token_freeze_zkbin);
 
         eprintln!("Creating token freeze circuit proving keys");
         let token_freeze_pk = ProvingKey::build(token_freeze_zkbin.k, &token_freeze_circuit);

+ 2 - 2
bin/drk/src/rpc_transfer.rs

@@ -123,8 +123,8 @@ impl Drk {
         let mint_zkbin = ZkBinary::decode(&mint_zkbin.1)?;
         let burn_zkbin = ZkBinary::decode(&burn_zkbin.1)?;
 
-        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin), &mint_zkbin);
-        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin), &burn_zkbin);
+        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin);
+        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin);
 
         eprintln!("Creating Mint and Burn circuit proving keys");
         let mint_pk = ProvingKey::build(mint_zkbin.k, &mint_circuit);

+ 2 - 2
bin/faucetd/src/main.rs

@@ -239,10 +239,10 @@ impl Faucetd {
         let (burn_zkbin, _): (Vec<u8>, Vec<u8>) = deserialize(&burn_zkbytes)?;
 
         let mint_zkbin = ZkBinary::decode(&mint_zkbin)?;
-        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin), &mint_zkbin);
+        let mint_circuit = ZkCircuit::new(empty_witnesses(&mint_zkbin)?, &mint_zkbin);
 
         let burn_zkbin = ZkBinary::decode(&burn_zkbin)?;
-        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin), &burn_zkbin);
+        let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin);
 
         info!("Creating mint circuit proving key");
         let mint_provingkey = ProvingKey::build(mint_zkbin.k, &mint_circuit);

+ 2 - 2
src/blockchain/contract_store.rs

@@ -211,7 +211,7 @@ impl ContractStateStore {
         let zkbin = ZkBinary::decode(&zkbin).unwrap();
 
         // Construct the circuit to be able to read the VerifyingKey
-        let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+        let circuit = ZkCircuit::new(empty_witnesses(&zkbin).unwrap(), &zkbin);
 
         // The second one is the serialized VerifyingKey for it
         let mut vk_buf = Cursor::new(vkbin);
@@ -323,7 +323,7 @@ impl ContractStateStoreOverlay {
         let zkbin = ZkBinary::decode(&zkbin).unwrap();
 
         // Construct the circuit to be able to read the VerifyingKey
-        let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+        let circuit = ZkCircuit::new(empty_witnesses(&zkbin).unwrap(), &zkbin);
 
         // The second one is the serialized VerifyingKey for it
         let mut vk_buf = Cursor::new(vkbin);

+ 1 - 1
src/consensus/validator.rs

@@ -110,7 +110,7 @@ impl ValidatorState {
         debug!(target: "consensus::validator", "Generating leader proof keys with k: {}", constants::LEADER_PROOF_K);
         let bincode = include_bytes!("../../proof/lead.zk.bin");
         let zkbin = ZkBinary::decode(bincode)?;
-        let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+        let circuit = ZkCircuit::new(empty_witnesses(&zkbin)?, &zkbin);
 
         let lead_verifying_key = VerifyingKey::build(constants::LEADER_PROOF_K, &circuit);
         // We only need this proving key if we're going to participate in the consensus.

+ 1 - 1
src/contract/test-harness/src/lib.rs

@@ -217,7 +217,7 @@ impl TestHarness {
         for (bincode, namespace, pk) in pks {
             let mut reader = Cursor::new(pk);
             let zkbin = ZkBinary::decode(&bincode)?;
-            let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+            let circuit = ZkCircuit::new(empty_witnesses(&zkbin)?, &zkbin);
             let _pk = ProvingKey::read(&mut reader, circuit)?;
             proving_keys.insert(namespace, (_pk, zkbin));
         }

+ 1 - 1
src/contract/test-harness/src/vks.rs

@@ -141,7 +141,7 @@ pub fn read_or_gen_vks_and_pks() -> Result<(Pks, Vks)> {
     for bincode in bins.iter() {
         let zkbin = ZkBinary::decode(bincode)?;
         debug!("Building VK for {}", zkbin.namespace);
-        let witnesses = empty_witnesses(&zkbin);
+        let witnesses = empty_witnesses(&zkbin)?;
         let circuit = ZkCircuit::new(witnesses, &zkbin);
         let vk = VerifyingKey::build(zkbin.k, &circuit);
         let mut vk_buf = vec![];

+ 10 - 1
src/runtime/import/db.rs

@@ -598,7 +598,16 @@ pub(crate) fn zkas_db_set(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32)
 
     // We didn't find any existing bincode, so let's create a new VerifyingKey and write it all.
     info!(target: "runtime::db::zkas_db_set()", "Creating VerifyingKey for {} zkas circuit", zkbin.namespace);
-    let circuit = ZkCircuit::new(empty_witnesses(&zkbin), &zkbin);
+    let witnesses = match empty_witnesses(&zkbin) {
+        Ok(w) => w,
+        Err(e) => {
+            error!(target: "runtime::db::zkas_db_set()", "Failed to create empty witnesses: {}", e);
+            return DB_SET_FAILED
+        }
+    };
+
+    // Construct the circuit and build the VerifyingKey
+    let circuit = ZkCircuit::new(witnesses, &zkbin);
     let vk = VerifyingKey::build(zkbin.k, &circuit);
     let mut vk_buf = vec![];
     if let Err(e) = vk.write(&mut vk_buf) {

+ 1 - 1
src/sdk/python/src/zk_circuit.rs

@@ -46,7 +46,7 @@ impl ZkCircuit {
 
     fn verifier_build(&self, circuit_code: &PyCell<ZkBinary>) -> Self {
         let circuit_code = circuit_code.borrow().deref().0.clone();
-        let circuit = vm::ZkCircuit::new(empty_witnesses(&circuit_code), &circuit_code);
+        let circuit = vm::ZkCircuit::new(empty_witnesses(&circuit_code).unwrap(), &circuit_code);
         Self(circuit, self.1.clone())
     }
 

+ 8 - 4
src/zk/vm_heap.rs

@@ -26,7 +26,11 @@ use halo2_proofs::{
     pasta::pallas,
 };
 
-use crate::zkas::{decoder::ZkBinary, types::VarType};
+use crate::{
+    zkas::{decoder::ZkBinary, types::VarType},
+    Error::ZkasDecoderError,
+    Result,
+};
 
 /// These represent the witness types outside of the circuit
 #[allow(clippy::large_enum_variant)]
@@ -48,7 +52,7 @@ pub enum Literal {
 
 /// Helper function for verifiers to generate empty witnesses for
 /// a given decoded zkas binary
-pub fn empty_witnesses(zkbin: &ZkBinary) -> Vec<Witness> {
+pub fn empty_witnesses(zkbin: &ZkBinary) -> Result<Vec<Witness>> {
     let mut ret = Vec::with_capacity(zkbin.witnesses.len());
 
     for witness in &zkbin.witnesses {
@@ -61,11 +65,11 @@ pub fn empty_witnesses(zkbin: &ZkBinary) -> Vec<Witness> {
             VarType::MerklePath => ret.push(Witness::MerklePath(Value::unknown())),
             VarType::Uint32 => ret.push(Witness::Uint32(Value::unknown())),
             VarType::Uint64 => ret.push(Witness::Uint64(Value::unknown())),
-            _ => todo!("Handle this gracefully"),
+            x => return Err(ZkasDecoderError(format!("Unsupported witness type: {:?}", x))),
         }
     }
 
-    ret
+    Ok(ret)
 }
 
 /// These represent the witness types inside the circuit