mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
contract/deployooor: Remove redundant ZK proof creation and verification
This commit is contained in:
@@ -16,13 +16,6 @@ PKGNAME = $(shell grep '^name = ' Cargo.toml | cut -d' ' -f3 | tr -d '"')
|
||||
# wasm contract binary
|
||||
WASM_BIN = $(PKGNAME:=.wasm)
|
||||
|
||||
# zkas compiler binary
|
||||
ZKAS = ../../../zkas
|
||||
|
||||
# zkas circuits
|
||||
PROOFS_SRC = $(shell find proof -type f -name '*.zk')
|
||||
PROOFS_BIN = $(PROOFS_SRC:=.bin)
|
||||
|
||||
# wasm source files
|
||||
WASM_SRC = \
|
||||
Cargo.toml \
|
||||
@@ -35,10 +28,7 @@ WASM_SRC = \
|
||||
|
||||
all: $(WASM_BIN)
|
||||
|
||||
$(PROOFS_BIN): $(ZKAS) $(PROOFS_SRC)
|
||||
$(ZKAS) $(basename $@) -o $@
|
||||
|
||||
$(WASM_BIN): $(WASM_SRC) $(PROOFS_BIN)
|
||||
$(WASM_BIN): $(WASM_SRC)
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --target=$(WASM_TARGET) \
|
||||
--release --package $(PKGNAME)
|
||||
cp -f ../../../target/$(WASM_TARGET)/release/$@ $@
|
||||
@@ -64,6 +54,6 @@ clean:
|
||||
--release --package $(PKGNAME)
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) \
|
||||
--release --package $(PKGNAME)
|
||||
rm -f $(PROOFS_BIN) $(WASM_BIN)
|
||||
rm -f $(WASM_BIN)
|
||||
|
||||
.PHONY: all test-integration test clippy clean
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
k = 13;
|
||||
field = "pallas";
|
||||
|
||||
constant "DeriveContractID" {
|
||||
EcFixedPointBase NULLIFIER_K,
|
||||
}
|
||||
|
||||
witness "DeriveContractID" {
|
||||
# Deploy key used for signing and contract ID derivation
|
||||
Base deploy_key,
|
||||
}
|
||||
|
||||
circuit "DeriveContractID" {
|
||||
# ContractID derivation path (See darkfi_sdk::crypto::ContractId)
|
||||
derivation_path = witness_base(42);
|
||||
|
||||
# Derive the public key used for the signature
|
||||
signature_public = ec_mul_base(deploy_key, NULLIFIER_K);
|
||||
signature_x = ec_get_x(signature_public);
|
||||
signature_y = ec_get_y(signature_public);
|
||||
constrain_instance(signature_x);
|
||||
constrain_instance(signature_y);
|
||||
|
||||
# Derive the Contract ID
|
||||
contract_id = poseidon_hash(derivation_path, signature_x, signature_y);
|
||||
constrain_instance(contract_id);
|
||||
}
|
||||
@@ -16,19 +16,12 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use darkfi::{
|
||||
zk::{Proof, ProvingKey},
|
||||
zkas::ZkBinary,
|
||||
Result,
|
||||
};
|
||||
use darkfi::Result;
|
||||
use darkfi_sdk::{crypto::Keypair, deploy::DeployParamsV1};
|
||||
use log::{debug, info};
|
||||
|
||||
use super::create_derive_contractid_proof;
|
||||
use log::info;
|
||||
|
||||
pub struct DeployCallDebris {
|
||||
pub params: DeployParamsV1,
|
||||
pub proofs: Vec<Proof>,
|
||||
}
|
||||
|
||||
/// Struct holding necessary information to build a `Deployooor::DeployV1` contract call.
|
||||
@@ -39,10 +32,6 @@ pub struct DeployCallBuilder {
|
||||
pub wasm_bincode: Vec<u8>,
|
||||
/// Serialized deployment payload instruction
|
||||
pub deploy_ix: Vec<u8>,
|
||||
/// `DeriveContractID` zkas circuit ZkBinary
|
||||
pub derivecid_zkbin: ZkBinary,
|
||||
/// Proving key for the `DeriveContractID` zk circuit
|
||||
pub derivecid_pk: ProvingKey,
|
||||
}
|
||||
|
||||
impl DeployCallBuilder {
|
||||
@@ -50,20 +39,13 @@ impl DeployCallBuilder {
|
||||
info!("Building Deployooor::DeployV1 contract call");
|
||||
assert!(!self.wasm_bincode.is_empty());
|
||||
|
||||
debug!("Creating DeriveContractID ZK proof");
|
||||
let (proof, _public_inputs) = create_derive_contractid_proof(
|
||||
&self.derivecid_zkbin,
|
||||
&self.derivecid_pk,
|
||||
&self.deploy_keypair,
|
||||
)?;
|
||||
|
||||
let params = DeployParamsV1 {
|
||||
wasm_bincode: self.wasm_bincode.clone(),
|
||||
public_key: self.deploy_keypair.public,
|
||||
ix: self.deploy_ix.clone(),
|
||||
};
|
||||
|
||||
let debris = DeployCallDebris { params, proofs: vec![proof] };
|
||||
let debris = DeployCallDebris { params };
|
||||
|
||||
Ok(debris)
|
||||
}
|
||||
|
||||
@@ -16,45 +16,28 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use darkfi::{
|
||||
zk::{Proof, ProvingKey},
|
||||
zkas::ZkBinary,
|
||||
Result,
|
||||
};
|
||||
use darkfi::Result;
|
||||
use darkfi_sdk::crypto::Keypair;
|
||||
use log::{debug, info};
|
||||
use log::info;
|
||||
|
||||
use super::create_derive_contractid_proof;
|
||||
use crate::model::LockParamsV1;
|
||||
|
||||
pub struct LockCallDebris {
|
||||
pub params: LockParamsV1,
|
||||
pub proofs: Vec<Proof>,
|
||||
}
|
||||
|
||||
/// Struct holding necessary information to build a `Deployooor::LockV1` contract call.
|
||||
pub struct LockCallBuilder {
|
||||
/// Contract deploy keypair
|
||||
pub deploy_keypair: Keypair,
|
||||
/// `DeriveContractID` zkas circuit ZkBinary,
|
||||
pub derivecid_zkbin: ZkBinary,
|
||||
/// Proving key for the `DeriveContractId` zk circuit
|
||||
pub derivecid_pk: ProvingKey,
|
||||
}
|
||||
|
||||
impl LockCallBuilder {
|
||||
pub fn build(&self) -> Result<LockCallDebris> {
|
||||
info!("Building Deployooor::LockV1 contract call");
|
||||
|
||||
debug!("Creating DeriveContractID ZK proof");
|
||||
let (proof, _public_inputs) = create_derive_contractid_proof(
|
||||
&self.derivecid_zkbin,
|
||||
&self.derivecid_pk,
|
||||
&self.deploy_keypair,
|
||||
)?;
|
||||
|
||||
let params = LockParamsV1 { public_key: self.deploy_keypair.public };
|
||||
let debris = LockCallDebris { params, proofs: vec![proof] };
|
||||
let debris = LockCallDebris { params };
|
||||
|
||||
Ok(debris)
|
||||
}
|
||||
|
||||
@@ -19,45 +19,8 @@
|
||||
//! This module implements the client-side API for deploying arbitrary contracts
|
||||
//! on the DarkFi network.
|
||||
|
||||
use darkfi::{
|
||||
zk::{halo2::Value, Proof, ProvingKey, Witness, ZkCircuit},
|
||||
zkas::ZkBinary,
|
||||
Result,
|
||||
};
|
||||
use darkfi_sdk::{
|
||||
crypto::{ContractId, Keypair, PublicKey},
|
||||
pasta::pallas,
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
/// `Deployooor::DeployV1` API
|
||||
pub mod deploy_v1;
|
||||
|
||||
/// `Deployooor::LockV1` API
|
||||
pub mod lock_v1;
|
||||
|
||||
pub struct DeriveContractIdRevealed {
|
||||
pub public_key: PublicKey,
|
||||
pub contract_id: ContractId,
|
||||
}
|
||||
|
||||
impl DeriveContractIdRevealed {
|
||||
pub fn to_vec(&self) -> Vec<pallas::Base> {
|
||||
let (pub_x, pub_y) = self.public_key.xy();
|
||||
vec![pub_x, pub_y, self.contract_id.inner()]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_derive_contractid_proof(
|
||||
zkbin: &ZkBinary,
|
||||
pk: &ProvingKey,
|
||||
deploy_key: &Keypair,
|
||||
) -> Result<(Proof, DeriveContractIdRevealed)> {
|
||||
let contract_id = ContractId::derive(deploy_key.secret);
|
||||
let public_inputs = DeriveContractIdRevealed { public_key: deploy_key.public, contract_id };
|
||||
let prover_witnesses = vec![Witness::Base(Value::known(deploy_key.secret.inner()))];
|
||||
let circuit = ZkCircuit::new(prover_witnesses, zkbin);
|
||||
let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?;
|
||||
|
||||
Ok((proof, public_inputs))
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use darkfi_sdk::{
|
||||
crypto::ContractId,
|
||||
dark_tree::DarkLeaf,
|
||||
db::{db_init, db_lookup, db_set, zkas_db_set},
|
||||
db::{db_init, db_lookup, db_set},
|
||||
error::ContractResult,
|
||||
util::set_return_data,
|
||||
ContractCall,
|
||||
@@ -51,10 +51,6 @@ darkfi_sdk::define_contract!(
|
||||
/// We use this function to initialize all the necessary databases and prepare them
|
||||
/// with initial data if necessary.
|
||||
fn init_contract(cid: ContractId, _ix: &[u8]) -> ContractResult {
|
||||
// Set up the zkas circuit tree
|
||||
let derive_cid_bincode = include_bytes!("../proof/derive_contract_id.zk.bin");
|
||||
zkas_db_set(&derive_cid_bincode[..])?;
|
||||
|
||||
// Set up a database tree for arbitrary data
|
||||
let info_db = match db_lookup(cid, DEPLOY_CONTRACT_INFO_TREE) {
|
||||
Ok(v) => v,
|
||||
|
||||
@@ -32,10 +32,7 @@ use wasmparser::{
|
||||
Payload::ExportSection,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
error::DeployError, model::DeployUpdateV1, DeployFunction, DEPLOY_CONTRACT_LOCK_TREE,
|
||||
DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1,
|
||||
};
|
||||
use crate::{error::DeployError, model::DeployUpdateV1, DeployFunction, DEPLOY_CONTRACT_LOCK_TREE};
|
||||
|
||||
/// `get_metadata` function for `Deploy::DeployV1`
|
||||
pub(crate) fn deploy_get_metadata_v1(
|
||||
@@ -47,20 +44,10 @@ pub(crate) fn deploy_get_metadata_v1(
|
||||
let params: DeployParamsV1 = deserialize(&self_.data.data[1..])?;
|
||||
|
||||
// Public inputs for the ZK proofs we have to verify
|
||||
let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
||||
let zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
||||
// Public keys for the transaction signatures we have to verify
|
||||
let signature_pubkeys: Vec<PublicKey> = vec![params.public_key];
|
||||
|
||||
// Derive the ContractID from the public key
|
||||
let (sig_x, sig_y) = params.public_key.xy();
|
||||
let contract_id = ContractId::derive_public(params.public_key);
|
||||
|
||||
// Append the ZK public inputs
|
||||
zk_public_inputs.push((
|
||||
DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1.to_string(),
|
||||
vec![sig_x, sig_y, contract_id.inner()],
|
||||
));
|
||||
|
||||
// Serialize everything gathered and return it
|
||||
let mut metadata = vec![];
|
||||
zk_public_inputs.encode(&mut metadata)?;
|
||||
|
||||
@@ -30,7 +30,7 @@ use darkfi_serial::{deserialize, serialize, Encodable, WriteExt};
|
||||
use crate::{
|
||||
error::DeployError,
|
||||
model::{LockParamsV1, LockUpdateV1},
|
||||
DeployFunction, DEPLOY_CONTRACT_LOCK_TREE, DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1,
|
||||
DeployFunction, DEPLOY_CONTRACT_LOCK_TREE,
|
||||
};
|
||||
|
||||
/// `get_metadata` function for `Deploy::LockV1`
|
||||
@@ -43,20 +43,10 @@ pub(crate) fn lock_get_metadata_v1(
|
||||
let params: LockParamsV1 = deserialize(&self_.data.data[1..])?;
|
||||
|
||||
// Public inputs for the ZK proofs we have to verify
|
||||
let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
||||
let zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
||||
// Public keys for the transaction signatures we have to verify
|
||||
let signature_pubkeys: Vec<PublicKey> = vec![params.public_key];
|
||||
|
||||
// Derive the ContractID from the public key
|
||||
let (sig_x, sig_y) = params.public_key.xy();
|
||||
let contract_id = ContractId::derive_public(params.public_key);
|
||||
|
||||
// Append the ZK public inputs
|
||||
zk_public_inputs.push((
|
||||
DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1.to_string(),
|
||||
vec![sig_x, sig_y, contract_id.inner()],
|
||||
));
|
||||
|
||||
// Serialize everything gathered and return it
|
||||
let mut metadata = vec![];
|
||||
zk_public_inputs.encode(&mut metadata)?;
|
||||
|
||||
@@ -59,6 +59,3 @@ pub const DEPLOY_CONTRACT_LOCK_TREE: &str = "lock";
|
||||
|
||||
// These are keys inside the info tree
|
||||
pub const DEPLOY_CONTRACT_DB_VERSION: &[u8] = b"db_version";
|
||||
|
||||
/// zkas derive circuit namespace
|
||||
pub const DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1: &str = "DeriveContractID";
|
||||
|
||||
@@ -20,9 +20,7 @@ use darkfi::{
|
||||
tx::{ContractCallLeaf, Transaction, TransactionBuilder},
|
||||
Result,
|
||||
};
|
||||
use darkfi_deployooor_contract::{
|
||||
client::deploy_v1::DeployCallBuilder, DeployFunction, DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1,
|
||||
};
|
||||
use darkfi_deployooor_contract::{client::deploy_v1::DeployCallBuilder, DeployFunction};
|
||||
use darkfi_money_contract::{
|
||||
client::{MoneyNote, OwnCoin},
|
||||
model::MoneyFeeParamsV1,
|
||||
@@ -50,17 +48,8 @@ impl TestHarness {
|
||||
let wallet = self.holders.get(holder).unwrap();
|
||||
let deploy_keypair = wallet.contract_deploy_authority;
|
||||
|
||||
let (derivecid_pk, derivecid_zkbin) =
|
||||
self.proving_keys.get(&DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1.to_string()).unwrap();
|
||||
|
||||
// Build the contract call
|
||||
let builder = DeployCallBuilder {
|
||||
deploy_keypair,
|
||||
wasm_bincode,
|
||||
deploy_ix: vec![],
|
||||
derivecid_zkbin: derivecid_zkbin.clone(),
|
||||
derivecid_pk: derivecid_pk.clone(),
|
||||
};
|
||||
let builder = DeployCallBuilder { deploy_keypair, wasm_bincode, deploy_ix: vec![] };
|
||||
let debris = builder.build()?;
|
||||
|
||||
// Encode the call
|
||||
@@ -68,7 +57,7 @@ impl TestHarness {
|
||||
debris.params.encode_async(&mut data).await?;
|
||||
let call = ContractCall { contract_id: *DEPLOYOOOR_CONTRACT_ID, data };
|
||||
let mut tx_builder =
|
||||
TransactionBuilder::new(ContractCallLeaf { call, proofs: debris.proofs }, vec![])?;
|
||||
TransactionBuilder::new(ContractCallLeaf { call, proofs: vec![] }, vec![])?;
|
||||
|
||||
// If we have tx fees enabled, make an offering
|
||||
let mut fee_params = None;
|
||||
|
||||
@@ -36,21 +36,20 @@ use darkfi_dao_contract::{
|
||||
DAO_CONTRACT_ZKAS_DAO_PROPOSE_MAIN_NS, DAO_CONTRACT_ZKAS_DAO_VOTE_INPUT_NS,
|
||||
DAO_CONTRACT_ZKAS_DAO_VOTE_MAIN_NS,
|
||||
};
|
||||
use darkfi_deployooor_contract::DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1;
|
||||
use darkfi_money_contract::{
|
||||
MONEY_CONTRACT_ZKAS_AUTH_TOKEN_MINT_NS_V1, MONEY_CONTRACT_ZKAS_BURN_NS_V1,
|
||||
MONEY_CONTRACT_ZKAS_FEE_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
|
||||
MONEY_CONTRACT_ZKAS_TOKEN_FRZ_NS_V1, MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1,
|
||||
};
|
||||
use darkfi_sdk::crypto::{contract_id::DEPLOYOOOR_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID};
|
||||
use darkfi_sdk::crypto::{DAO_CONTRACT_ID, MONEY_CONTRACT_ID};
|
||||
use darkfi_serial::{deserialize, serialize};
|
||||
|
||||
use log::debug;
|
||||
|
||||
/// Update these if any circuits are changed.
|
||||
/// Delete the existing cachefiles, and enable debug logging, you will see the new hashes.
|
||||
const VKS_HASH: &str = "605a72d885e6194ac346a328482504ca37f0c990c2d636ad1b548a8bfb05542b";
|
||||
const PKS_HASH: &str = "277228a59ed3cc1df8a9d9e61b3230b4417512d649b4aca1fb3e5f02514a2e96";
|
||||
const PKS_HASH: &str = "b19792d5c813eebe339af055fc3459cdad8e97e766a35a79f3e42964a2d6e610";
|
||||
const VKS_HASH: &str = "9a92231ef4edfc20c2043d5255b558de5c07a9a4efda07718b689c299ac9440e";
|
||||
|
||||
/// Build a `PathBuf` to a cachefile
|
||||
fn cache_path(typ: &str) -> Result<PathBuf> {
|
||||
@@ -137,8 +136,6 @@ pub fn get_cached_pks_and_vks() -> Result<(Pks, Vks)> {
|
||||
&include_bytes!("../../dao/proof/exec.zk.bin")[..],
|
||||
&include_bytes!("../../dao/proof/auth-money-transfer.zk.bin")[..],
|
||||
&include_bytes!("../../dao/proof/auth-money-transfer-enc-coin.zk.bin")[..],
|
||||
// Deployooor
|
||||
&include_bytes!("../../deployooor/proof/derive_contract_id.zk.bin")[..],
|
||||
];
|
||||
|
||||
let mut pks = vec![];
|
||||
@@ -184,12 +181,10 @@ pub fn inject(sled_db: &sled::Db, vks: &Vks) -> Result<()> {
|
||||
// Derive the database names for the specific contracts
|
||||
let money_db_name = MONEY_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
|
||||
let dao_db_name = DAO_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
|
||||
let deployooor_db_name = DEPLOYOOOR_CONTRACT_ID.hash_state_id(SMART_CONTRACT_ZKAS_DB_NAME);
|
||||
|
||||
// Create the db trees
|
||||
let money_tree = sled_db.open_tree(money_db_name)?;
|
||||
let dao_tree = sled_db.open_tree(dao_db_name)?;
|
||||
let deployooor_tree = sled_db.open_tree(deployooor_db_name)?;
|
||||
|
||||
for (bincode, namespace, vk) in vks.iter() {
|
||||
match namespace.as_str() {
|
||||
@@ -219,13 +214,6 @@ pub fn inject(sled_db: &sled::Db, vks: &Vks) -> Result<()> {
|
||||
dao_tree.insert(key, value)?;
|
||||
}
|
||||
|
||||
// Deployooor contract circuits
|
||||
DEPLOY_CONTRACT_ZKAS_DERIVE_NS_V1 => {
|
||||
let key = serialize(&namespace.as_str());
|
||||
let value = serialize(&(bincode.clone(), vk.clone()));
|
||||
deployooor_tree.insert(key, value)?;
|
||||
}
|
||||
|
||||
x => panic!("Found unhandled zkas namespace {}", x),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user