mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
switch DAO auth enc to use ElGamalEncryptedNote from SDK
This commit is contained in:
@@ -455,10 +455,6 @@ This provides verifiable note encryption for all output coins in the sibling `Mo
|
||||
{{#include ../../../../../src/contract/dao/src/model.rs:dao-auth_xfer-params}}
|
||||
```
|
||||
|
||||
```rust
|
||||
{{#include ../../../../../src/contract/dao/src/model.rs:dao-auth_coinattrs-params}}
|
||||
```
|
||||
|
||||
### Contract Statement
|
||||
|
||||
Denote the DAO contract ID by $\t{CID}_\t{DAO} ∈ 𝔽ₚ$.
|
||||
|
||||
@@ -56,29 +56,31 @@ circuit "DaoAuthMoneyTransferEncCoin" {
|
||||
const_2 = witness_base(2);
|
||||
const_3 = witness_base(3);
|
||||
const_4 = witness_base(4);
|
||||
const_5 = witness_base(5);
|
||||
|
||||
# Each blinding value must be used only once otherwise they
|
||||
# could be calculated.
|
||||
|
||||
# We can skip the public_key since it's inferred by the receiver
|
||||
|
||||
enc_value = base_add(value, shared_secret);
|
||||
shared_secret_1 = poseidon_hash(shared_secret, const_1);
|
||||
enc_value = base_add(value, shared_secret_1);
|
||||
constrain_instance(enc_value);
|
||||
|
||||
shared_secret_1 = poseidon_hash(shared_secret, const_1);
|
||||
enc_token_id = base_add(token_id, shared_secret_1);
|
||||
shared_secret_2 = poseidon_hash(shared_secret, const_2);
|
||||
enc_token_id = base_add(token_id, shared_secret_2);
|
||||
constrain_instance(enc_token_id);
|
||||
|
||||
shared_secret_2 = poseidon_hash(shared_secret, const_2);
|
||||
enc_serial = base_add(serial, shared_secret_2);
|
||||
shared_secret_3 = poseidon_hash(shared_secret, const_3);
|
||||
enc_serial = base_add(serial, shared_secret_3);
|
||||
constrain_instance(enc_serial);
|
||||
|
||||
shared_secret_3 = poseidon_hash(shared_secret, const_3);
|
||||
enc_spend_hook = base_add(spend_hook, shared_secret_3);
|
||||
shared_secret_4 = poseidon_hash(shared_secret, const_4);
|
||||
enc_spend_hook = base_add(spend_hook, shared_secret_4);
|
||||
constrain_instance(enc_spend_hook);
|
||||
|
||||
shared_secret_4 = poseidon_hash(shared_secret, const_4);
|
||||
enc_user_data = base_add(user_data, shared_secret_4);
|
||||
shared_secret_5 = poseidon_hash(shared_secret, const_5);
|
||||
enc_user_data = base_add(user_data, shared_secret_5);
|
||||
constrain_instance(enc_user_data);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,19 +112,21 @@ circuit "DaoAuthMoneyTransfer" {
|
||||
|
||||
const_1 = witness_base(1);
|
||||
const_2 = witness_base(2);
|
||||
const_3 = witness_base(3);
|
||||
|
||||
# Value
|
||||
enc_value = base_add(dao_value, shared_secret);
|
||||
shared_secret_1 = poseidon_hash(shared_secret, const_1);
|
||||
enc_value = base_add(dao_value, shared_secret_1);
|
||||
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);
|
||||
shared_secret_2 = poseidon_hash(shared_secret, const_2);
|
||||
enc_token_id = base_add(dao_token_id, shared_secret_2);
|
||||
constrain_instance(enc_token_id);
|
||||
|
||||
# Serial
|
||||
shared_secret_2 = poseidon_hash(shared_secret, const_2);
|
||||
enc_serial = base_add(dao_serial, shared_secret_2);
|
||||
shared_secret_3 = poseidon_hash(shared_secret, const_3);
|
||||
enc_serial = base_add(dao_serial, shared_secret_3);
|
||||
constrain_instance(enc_serial);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
use darkfi_money_contract::model::CoinAttributes;
|
||||
use darkfi_sdk::{
|
||||
crypto::{pasta_prelude::*, poseidon_hash, util::mod_r_p, PublicKey, DAO_CONTRACT_ID},
|
||||
crypto::{note::ElGamalEncryptedNote, poseidon_hash, PublicKey, SecretKey, DAO_CONTRACT_ID},
|
||||
pasta::pallas,
|
||||
};
|
||||
|
||||
@@ -30,9 +30,7 @@ use darkfi::{
|
||||
Result,
|
||||
};
|
||||
|
||||
use crate::model::{
|
||||
Dao, DaoAuthCoinAttrs, DaoAuthMoneyTransferParams, DaoProposal, VecAuthCallCommit,
|
||||
};
|
||||
use crate::model::{Dao, DaoAuthMoneyTransferParams, DaoProposal, VecAuthCallCommit};
|
||||
|
||||
pub struct DaoAuthMoneyTransferCall {
|
||||
pub proposal: DaoProposal,
|
||||
@@ -60,48 +58,41 @@ impl DaoAuthMoneyTransferCall {
|
||||
for coin_attrs in proposal_coinattrs {
|
||||
let coin = coin_attrs.to_coin();
|
||||
|
||||
let ephem_secret = pallas::Base::random(&mut OsRng);
|
||||
let ephem_pubkey = PublicKey::from_secret(ephem_secret.into());
|
||||
let ephem_secret = SecretKey::random(&mut OsRng);
|
||||
let ephem_pubkey = PublicKey::from_secret(ephem_secret);
|
||||
let (ephem_x, ephem_y) = ephem_pubkey.xy();
|
||||
|
||||
let public_key = coin_attrs.public_key.inner();
|
||||
let value_base = pallas::Base::from(coin_attrs.value);
|
||||
|
||||
let shared_point = 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 enc_value = value_base + shared_secret;
|
||||
|
||||
let enc_token_id =
|
||||
coin_attrs.token_id.inner() + poseidon_hash([shared_secret, pallas::Base::from(1)]);
|
||||
let enc_serial =
|
||||
coin_attrs.serial + poseidon_hash([shared_secret, pallas::Base::from(2)]);
|
||||
let enc_spend_hook =
|
||||
coin_attrs.spend_hook + poseidon_hash([shared_secret, pallas::Base::from(3)]);
|
||||
let enc_user_data =
|
||||
coin_attrs.user_data + poseidon_hash([shared_secret, pallas::Base::from(4)]);
|
||||
let note = [
|
||||
value_base,
|
||||
coin_attrs.token_id.inner(),
|
||||
coin_attrs.serial,
|
||||
coin_attrs.spend_hook,
|
||||
coin_attrs.user_data,
|
||||
];
|
||||
let enc_note =
|
||||
ElGamalEncryptedNote::encrypt(note, &ephem_secret, &coin_attrs.public_key);
|
||||
|
||||
let prover_witnesses = vec![
|
||||
Witness::EcNiPoint(Value::known(public_key)),
|
||||
Witness::EcNiPoint(Value::known(coin_attrs.public_key.inner())),
|
||||
Witness::Base(Value::known(value_base)),
|
||||
Witness::Base(Value::known(coin_attrs.token_id.inner())),
|
||||
Witness::Base(Value::known(coin_attrs.serial)),
|
||||
Witness::Base(Value::known(coin_attrs.spend_hook)),
|
||||
Witness::Base(Value::known(coin_attrs.user_data)),
|
||||
Witness::Base(Value::known(ephem_secret)),
|
||||
Witness::Base(Value::known(ephem_secret.inner())),
|
||||
];
|
||||
|
||||
let public_inputs = vec![
|
||||
coin.inner(),
|
||||
ephem_x,
|
||||
ephem_y,
|
||||
enc_value,
|
||||
enc_token_id,
|
||||
enc_serial,
|
||||
enc_spend_hook,
|
||||
enc_user_data,
|
||||
enc_note.encrypted_values[0],
|
||||
enc_note.encrypted_values[1],
|
||||
enc_note.encrypted_values[2],
|
||||
enc_note.encrypted_values[3],
|
||||
enc_note.encrypted_values[4],
|
||||
];
|
||||
|
||||
let circuit = ZkCircuit::new(prover_witnesses, auth_xfer_enc_coin_zkbin);
|
||||
@@ -110,43 +101,24 @@ impl DaoAuthMoneyTransferCall {
|
||||
.expect("DAO::exec() proving error!)");
|
||||
proofs.push(proof);
|
||||
|
||||
enc_attrs.push(DaoAuthCoinAttrs {
|
||||
value: enc_value,
|
||||
token_id: enc_token_id,
|
||||
serial: enc_serial,
|
||||
spend_hook: enc_spend_hook,
|
||||
user_data: enc_user_data,
|
||||
ephem_pubkey,
|
||||
});
|
||||
enc_attrs.push(enc_note);
|
||||
}
|
||||
|
||||
// Build the main proof
|
||||
|
||||
let ephem_secret = pallas::Base::random(&mut OsRng);
|
||||
let change_ephem_pubkey = PublicKey::from_secret(ephem_secret.into());
|
||||
let ephem_secret = SecretKey::random(&mut OsRng);
|
||||
let change_ephem_pubkey = PublicKey::from_secret(ephem_secret);
|
||||
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 note =
|
||||
[dao_change_value, self.dao_coin_attrs.token_id.inner(), self.dao_coin_attrs.serial];
|
||||
let dao_change_attrs =
|
||||
ElGamalEncryptedNote::encrypt(note, &ephem_secret, &self.dao.public_key);
|
||||
|
||||
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 params = DaoAuthMoneyTransferParams { enc_attrs, dao_change_attrs };
|
||||
|
||||
let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit);
|
||||
let dao_quorum = pallas::Base::from(self.dao.quorum);
|
||||
@@ -180,7 +152,7 @@ impl DaoAuthMoneyTransferCall {
|
||||
// DAO_CONTRACT_ID
|
||||
Witness::Base(Value::known(DAO_CONTRACT_ID.inner())),
|
||||
// Encrypted change DAO output
|
||||
Witness::Base(Value::known(ephem_secret)),
|
||||
Witness::Base(Value::known(ephem_secret.inner())),
|
||||
];
|
||||
|
||||
let public_inputs = vec![
|
||||
@@ -191,9 +163,9 @@ impl DaoAuthMoneyTransferCall {
|
||||
self.proposal.auth_calls.commit(),
|
||||
ephem_x,
|
||||
ephem_y,
|
||||
change_enc_value,
|
||||
change_enc_token_id,
|
||||
change_enc_serial,
|
||||
dao_change_attrs.encrypted_values[0],
|
||||
dao_change_attrs.encrypted_values[1],
|
||||
dao_change_attrs.encrypted_values[2],
|
||||
];
|
||||
|
||||
let circuit = ZkCircuit::new(prover_witnesses, auth_xfer_zkbin);
|
||||
|
||||
@@ -60,20 +60,20 @@ pub(crate) fn dao_authxfer_get_metadata(
|
||||
let mut zk_public_inputs: Vec<(String, Vec<pallas::Base>)> = vec![];
|
||||
let signature_pubkeys: Vec<PublicKey> = vec![];
|
||||
|
||||
for (output, attrs) in xfer_params.outputs.iter().zip(self_params.enc_attrs.iter()) {
|
||||
for (output, enc_attrs) in xfer_params.outputs.iter().zip(self_params.enc_attrs.iter()) {
|
||||
let coin = output.coin;
|
||||
let (ephem_x, ephem_y) = attrs.ephem_pubkey.xy();
|
||||
let (ephem_x, ephem_y) = enc_attrs.ephem_public.xy();
|
||||
zk_public_inputs.push((
|
||||
DAO_CONTRACT_ZKAS_DAO_AUTH_MONEY_TRANSFER_ENC_COIN_NS.to_string(),
|
||||
vec![
|
||||
coin.inner(),
|
||||
ephem_x,
|
||||
ephem_y,
|
||||
attrs.value,
|
||||
attrs.token_id,
|
||||
attrs.serial,
|
||||
attrs.spend_hook,
|
||||
attrs.user_data,
|
||||
enc_attrs.encrypted_values[0],
|
||||
enc_attrs.encrypted_values[1],
|
||||
enc_attrs.encrypted_values[2],
|
||||
enc_attrs.encrypted_values[3],
|
||||
enc_attrs.encrypted_values[4],
|
||||
],
|
||||
));
|
||||
}
|
||||
@@ -84,7 +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();
|
||||
let (ephem_x, ephem_y) = self_params.dao_change_attrs.ephem_public.xy();
|
||||
zk_public_inputs.push((
|
||||
DAO_CONTRACT_ZKAS_DAO_AUTH_MONEY_TRANSFER_NS.to_string(),
|
||||
vec![
|
||||
@@ -95,9 +95,9 @@ pub(crate) fn dao_authxfer_get_metadata(
|
||||
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,
|
||||
self_params.dao_change_attrs.encrypted_values[0],
|
||||
self_params.dao_change_attrs.encrypted_values[1],
|
||||
self_params.dao_change_attrs.encrypted_values[2],
|
||||
],
|
||||
));
|
||||
|
||||
|
||||
@@ -364,24 +364,7 @@ pub struct DaoExecUpdate {
|
||||
// ANCHOR: dao-auth_xfer-params
|
||||
/// 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,
|
||||
pub enc_attrs: Vec<ElGamalEncryptedNote<5>>,
|
||||
pub dao_change_attrs: ElGamalEncryptedNote<3>,
|
||||
}
|
||||
// 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,
|
||||
}
|
||||
// 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 = "81036e85adea1b407698b0a3f58020f69ed6ac6c7843243b8b7b026d165f237f";
|
||||
const PKS_HASH: &str = "40c0c448274dfe66ec4249a38e69b1c2f7fd971cc3d35fbb2129f4ee8ee8aea5";
|
||||
const VKS_HASH: &str = "191e742f12fe776f76f9cda4e72ac3a4f92cd3873f2ea04e3887ac54d7ca5340";
|
||||
const PKS_HASH: &str = "da22afe484b762c6308241c91fe4d399f11b15f62e493c5fef4dea53f72976c1";
|
||||
|
||||
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