mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
dao: apply same verifiable encryption for other outputs, to the DAO change output as well.
This commit is contained in:
@@ -21,11 +21,10 @@ witness "DaoAuthMoneyTransferEncCoin" {
|
||||
}
|
||||
|
||||
circuit "DaoAuthMoneyTransferEncCoin" {
|
||||
# UGLY HACK -----------------
|
||||
# cast to EcPoint
|
||||
# (otherwise zkas refuses to compile)
|
||||
ONE = witness_base(1);
|
||||
pubkey = ec_mul_var_base(ONE, public_key);
|
||||
# ---------------------------
|
||||
|
||||
coin = poseidon_hash(
|
||||
ec_get_x(pubkey),
|
||||
|
||||
@@ -4,6 +4,7 @@ field = "pallas";
|
||||
constant "DaoAuthMoneyTransfer" {
|
||||
EcFixedPointShort VALUE_COMMIT_VALUE,
|
||||
EcFixedPoint VALUE_COMMIT_RANDOM,
|
||||
EcFixedPointBase NULLIFIER_K,
|
||||
}
|
||||
|
||||
witness "DaoAuthMoneyTransfer" {
|
||||
@@ -20,8 +21,7 @@ witness "DaoAuthMoneyTransfer" {
|
||||
Base dao_approval_ratio_quot,
|
||||
Base dao_approval_ratio_base,
|
||||
Base gov_token_id,
|
||||
Base dao_public_x,
|
||||
Base dao_public_y,
|
||||
EcNiPoint dao_public_key,
|
||||
Base dao_bulla_blind,
|
||||
|
||||
# Dao input(s) user data blind
|
||||
@@ -29,14 +29,24 @@ witness "DaoAuthMoneyTransfer" {
|
||||
|
||||
# Dao output coin attrs
|
||||
Base dao_value,
|
||||
Base dao_token,
|
||||
Base dao_token_id,
|
||||
Base dao_serial,
|
||||
|
||||
# Should be set to DAO_CONTRACT_ID
|
||||
Base dao_contract_id,
|
||||
|
||||
# Epehemeral secret used for diffie-hellman shared secret derivation
|
||||
Base ephem_secret,
|
||||
}
|
||||
|
||||
circuit "DaoAuthMoneyTransfer" {
|
||||
# cast to EcPoint
|
||||
# (otherwise zkas refuses to compile)
|
||||
ONE = witness_base(1);
|
||||
dao_pubkey = ec_mul_var_base(ONE, dao_public_key);
|
||||
dao_public_x = ec_get_x(dao_pubkey);
|
||||
dao_public_y = ec_get_y(dao_pubkey);
|
||||
|
||||
dao_bulla = poseidon_hash(
|
||||
dao_proposer_limit,
|
||||
dao_quorum,
|
||||
@@ -74,7 +84,7 @@ circuit "DaoAuthMoneyTransfer" {
|
||||
# which ensures it will be correct.
|
||||
dao_value,
|
||||
# Likewise the token_id must match the other output coins.
|
||||
dao_token,
|
||||
dao_token_id,
|
||||
dao_serial,
|
||||
dao_contract_id,
|
||||
dao_bulla,
|
||||
@@ -85,5 +95,36 @@ circuit "DaoAuthMoneyTransfer" {
|
||||
# Reveal content commit. This should contain the set of coins.
|
||||
# We check these are set in the runtime.
|
||||
constrain_instance(proposal_auth_calls_commit);
|
||||
|
||||
# Now do verifiable encryption for DAO change output
|
||||
|
||||
# Ephemeral public key
|
||||
ephem_public = ec_mul_base(ephem_secret, NULLIFIER_K);
|
||||
constrain_instance(ec_get_x(ephem_public));
|
||||
constrain_instance(ec_get_y(ephem_public));
|
||||
|
||||
# The shared_point C = eP = dE
|
||||
shared_point = ec_mul_var_base(ephem_secret, dao_public_key);
|
||||
shared_secret = poseidon_hash(
|
||||
ec_get_x(shared_point),
|
||||
ec_get_y(shared_point),
|
||||
);
|
||||
|
||||
const_1 = witness_base(1);
|
||||
const_2 = witness_base(2);
|
||||
|
||||
# Value
|
||||
enc_value = base_add(dao_value, shared_secret);
|
||||
constrain_instance(enc_value);
|
||||
|
||||
# Token ID
|
||||
shared_secret_1 = poseidon_hash(shared_secret, const_1);
|
||||
enc_token_id = base_add(dao_token_id, shared_secret_1);
|
||||
constrain_instance(enc_token_id);
|
||||
|
||||
# Serial
|
||||
shared_secret_2 = poseidon_hash(shared_secret, const_2);
|
||||
enc_serial = base_add(dao_serial, shared_secret_2);
|
||||
constrain_instance(enc_serial);
|
||||
}
|
||||
|
||||
|
||||
@@ -122,15 +122,37 @@ impl DaoAuthMoneyTransferCall {
|
||||
|
||||
// Build the main proof
|
||||
|
||||
let params = DaoAuthMoneyTransferParams { enc_attrs };
|
||||
let ephem_secret = pallas::Base::random(&mut OsRng);
|
||||
let change_ephem_pubkey = PublicKey::from_secret(ephem_secret.into());
|
||||
let (ephem_x, ephem_y) = change_ephem_pubkey.xy();
|
||||
|
||||
let dao_public_key = self.dao.public_key.inner();
|
||||
let dao_change_value = pallas::Base::from(self.dao_coin_attrs.value);
|
||||
|
||||
let shared_point = dao_public_key * mod_r_p(ephem_secret);
|
||||
let shared_point_coords = shared_point.to_affine().coordinates().unwrap();
|
||||
let (shared_point_x, shared_point_y) = (*shared_point_coords.x(), *shared_point_coords.y());
|
||||
let shared_secret = poseidon_hash([shared_point_x, shared_point_y]);
|
||||
let change_enc_value = dao_change_value + shared_secret;
|
||||
|
||||
let change_enc_token_id = self.dao_coin_attrs.token_id.inner() +
|
||||
poseidon_hash([shared_secret, pallas::Base::from(1)]);
|
||||
let change_enc_serial =
|
||||
self.dao_coin_attrs.serial + poseidon_hash([shared_secret, pallas::Base::from(2)]);
|
||||
|
||||
let params = DaoAuthMoneyTransferParams {
|
||||
enc_attrs,
|
||||
change_enc_value,
|
||||
change_enc_token_id,
|
||||
change_enc_serial,
|
||||
change_ephem_pubkey,
|
||||
};
|
||||
|
||||
let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
|
||||
let dao_quorum = pallas::Base::from(self.dao.quorum);
|
||||
let dao_approval_ratio_quot = pallas::Base::from(self.dao.approval_ratio_quot);
|
||||
let dao_approval_ratio_base = pallas::Base::from(self.dao.approval_ratio_base);
|
||||
|
||||
let (dao_pub_x, dao_pub_y) = self.dao.public_key.xy();
|
||||
|
||||
let input_user_data_enc =
|
||||
poseidon_hash([self.dao.to_bulla().inner(), self.input_user_data_blind]);
|
||||
|
||||
@@ -147,17 +169,18 @@ impl DaoAuthMoneyTransferCall {
|
||||
Witness::Base(Value::known(dao_approval_ratio_quot)),
|
||||
Witness::Base(Value::known(dao_approval_ratio_base)),
|
||||
Witness::Base(Value::known(self.dao.gov_token_id.inner())),
|
||||
Witness::Base(Value::known(dao_pub_x)),
|
||||
Witness::Base(Value::known(dao_pub_y)),
|
||||
Witness::EcNiPoint(Value::known(dao_public_key)),
|
||||
Witness::Base(Value::known(self.dao.bulla_blind)),
|
||||
// Dao input user data blind
|
||||
Witness::Base(Value::known(self.input_user_data_blind)),
|
||||
// Dao output coin attrs
|
||||
Witness::Base(Value::known(pallas::Base::from(self.dao_coin_attrs.value))),
|
||||
Witness::Base(Value::known(dao_change_value)),
|
||||
Witness::Base(Value::known(self.dao_coin_attrs.token_id.inner())),
|
||||
Witness::Base(Value::known(self.dao_coin_attrs.serial)),
|
||||
// DAO_CONTRACT_ID
|
||||
Witness::Base(Value::known(DAO_CONTRACT_ID.inner())),
|
||||
// Encrypted change DAO output
|
||||
Witness::Base(Value::known(ephem_secret)),
|
||||
];
|
||||
|
||||
let public_inputs = vec![
|
||||
@@ -166,6 +189,11 @@ impl DaoAuthMoneyTransferCall {
|
||||
self.dao_coin_attrs.to_coin().inner(),
|
||||
DAO_CONTRACT_ID.inner(),
|
||||
self.proposal.auth_calls.commit(),
|
||||
ephem_x,
|
||||
ephem_y,
|
||||
change_enc_value,
|
||||
change_enc_token_id,
|
||||
change_enc_serial,
|
||||
];
|
||||
|
||||
let circuit = ZkCircuit::new(prover_witnesses, auth_xfer_zkbin);
|
||||
|
||||
@@ -84,6 +84,7 @@ pub(crate) fn dao_authxfer_get_metadata(
|
||||
// Also check the coin in the change output
|
||||
let last_coin = xfer_params.outputs.last().unwrap().coin;
|
||||
|
||||
let (ephem_x, ephem_y) = self_params.change_ephem_pubkey.xy();
|
||||
zk_public_inputs.push((
|
||||
DAO_CONTRACT_ZKAS_DAO_AUTH_MONEY_TRANSFER_NS.to_string(),
|
||||
vec![
|
||||
@@ -92,6 +93,11 @@ pub(crate) fn dao_authxfer_get_metadata(
|
||||
last_coin.inner(),
|
||||
DAO_CONTRACT_ID.inner(),
|
||||
exec_params.proposal_auth_calls.commit(),
|
||||
ephem_x,
|
||||
ephem_y,
|
||||
self_params.change_enc_value,
|
||||
self_params.change_enc_token_id,
|
||||
self_params.change_enc_serial,
|
||||
],
|
||||
));
|
||||
|
||||
|
||||
@@ -365,18 +365,23 @@ pub struct DaoExecUpdate {
|
||||
/// Parameters for `Dao::AuthMoneyTransfer`
|
||||
pub struct DaoAuthMoneyTransferParams {
|
||||
pub enc_attrs: Vec<DaoAuthCoinAttrs>,
|
||||
|
||||
pub change_ephem_pubkey: PublicKey,
|
||||
pub change_enc_value: pallas::Base,
|
||||
pub change_enc_token_id: pallas::Base,
|
||||
pub change_enc_serial: pallas::Base,
|
||||
}
|
||||
// ANCHOR_END: dao-auth_xfer-params
|
||||
|
||||
#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
|
||||
// ANCHOR: dao-auth_coinattrs-params
|
||||
pub struct DaoAuthCoinAttrs {
|
||||
pub ephem_pubkey: PublicKey,
|
||||
|
||||
pub value: pallas::Base,
|
||||
pub token_id: pallas::Base,
|
||||
pub serial: pallas::Base,
|
||||
pub spend_hook: pallas::Base,
|
||||
pub user_data: pallas::Base,
|
||||
|
||||
pub ephem_pubkey: PublicKey,
|
||||
}
|
||||
// ANCHOR_END: dao-auth_coinattrs-params
|
||||
|
||||
@@ -50,8 +50,8 @@ use darkfi_serial::{deserialize, serialize};
|
||||
use log::debug;
|
||||
|
||||
/// Update this if any circuits are changed
|
||||
const VKS_HASH: &str = "9d99da4cc2fa2882e5529bb6b24a965a815a2a22dc699d5e58ad17182e9f92a7";
|
||||
const PKS_HASH: &str = "83f2577d4036bd92c2502d11b7af5c37bbe350bc17f2a2cd96bd4b7e16e4cebf";
|
||||
const VKS_HASH: &str = "81036e85adea1b407698b0a3f58020f69ed6ac6c7843243b8b7b026d165f237f";
|
||||
const PKS_HASH: &str = "40c0c448274dfe66ec4249a38e69b1c2f7fd971cc3d35fbb2129f4ee8ee8aea5";
|
||||
|
||||
fn pks_path(typ: &str) -> Result<PathBuf> {
|
||||
let output = Command::new("git").arg("rev-parse").arg("--show-toplevel").output()?.stdout;
|
||||
|
||||
Reference in New Issue
Block a user