diff --git a/proof/tx.zk b/proof/tx.zk index 7ced75a0a..7e30893a4 100644 --- a/proof/tx.zk +++ b/proof/tx.zk @@ -39,7 +39,7 @@ circuit "tx" { PREFIX_SN = witness_base(6); # coin (1) pk/public key c1_pk = poseidon_hash(PREFIX_PK, c1_root_sk); - constrain_instance(c1_pk); + #constrain_instance(c1_pk); # coin (1) cm/commitment c1_cm_msg = poseidon_hash(PREFIX_CM, c1_pk, c1_value, c1_rho); c1_cm_v = ec_mul_base(c1_cm_msg, NULLIFIER_K); diff --git a/src/consensus/leadcoin.rs b/src/consensus/leadcoin.rs index b58bf571e..7ab893ff9 100644 --- a/src/consensus/leadcoin.rs +++ b/src/consensus/leadcoin.rs @@ -32,11 +32,11 @@ use rand::rngs::OsRng; use super::constants::{EPOCH_LENGTH}; use crate::{ - consensus::{TxRcpt,EncryptedTxRcpt}, + consensus::{TxRcpt,EncryptedTxRcpt,TransferStx}, crypto::{proof::ProvingKey, Proof}, zk::{vm::ZkCircuit, vm_stack::Witness}, zkas::ZkBinary, - Result, + Result, Error, }; use darkfi_serial::{Encodable, Decodable, SerialDecodable, SerialEncodable}; @@ -50,21 +50,7 @@ pub const PREFIX_CM: u64 = 4; pub const PREFIX_PK: u64 = 5; pub const PREFIX_SN: u64 = 6; -#[derive(Debug, Clone, SerialDecodable, SerialEncodable)] -pub struct TransferStx { - /// coin3_commitment in zk - pub change_coin_commitment: pallas::Point, - /// coin4_commitment in zk - pub transfered_coin_commitment: pallas::Point, - /// nullifiers coin1_nullifier - pub nullifier: pallas::Base, - /// sk coin pos - pub tau: pallas::Base, - /// root to coin's commitments - pub root: MerkleNode, - /// transfer proof - pub proof: Proof, -} + // TODO: Unify item names with the names in the ZK proof (those are more descriptive) /// Structure representing the consensus leader coin @@ -438,6 +424,9 @@ impl LeadCoin { let cm4_msg = poseidon_hash(cm4_msg_in); let cm4 = pedersen_commitment_base(cm4_msg, transfered_coin.opening); let tx = TransferStx { + coin_commitment: self.coin1_commitment, + coin_pk: self.pk(), + coin_root_sk: self.coin1_sk_root, change_coin_commitment: cm3, transfered_coin_commitment: cm4, nullifier: self.sn, diff --git a/src/consensus/mod.rs b/src/consensus/mod.rs index aa68f0261..3620bb5f2 100644 --- a/src/consensus/mod.rs +++ b/src/consensus/mod.rs @@ -54,9 +54,14 @@ pub mod utils; /// Wallet functions pub mod wallet; -/// received transaction. +/// transfered tx proof with public inputs. +pub mod stx; +pub use stx::TransferStx; + +/// encrypted receipient coin info pub mod rcpt; pub use rcpt::{TxRcpt,EncryptedTxRcpt}; +/// transfer transaction pub mod tx; pub use tx::Tx; diff --git a/src/consensus/rcpt.rs b/src/consensus/rcpt.rs index 3262ee3ac..0b41f90f7 100644 --- a/src/consensus/rcpt.rs +++ b/src/consensus/rcpt.rs @@ -1,3 +1,22 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2022 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + + use darkfi_sdk::{ crypto::{ keypair::{PublicKey}, diff --git a/src/consensus/stx.rs b/src/consensus/stx.rs new file mode 100644 index 000000000..9f3650b13 --- /dev/null +++ b/src/consensus/stx.rs @@ -0,0 +1,80 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2022 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +use darkfi_sdk::{ + pasta::{arithmetic::CurveAffine, group::Curve, pallas}, + crypto::MerkleNode, +}; + +use crate::{ + crypto::{proof::VerifyingKey, Proof}, + Result, Error, +}; +use darkfi_serial::{Encodable, Decodable, SerialDecodable, SerialEncodable}; + +#[derive(Debug, Clone, SerialDecodable, SerialEncodable)] +pub struct TransferStx { + /// sender's coin, or coin1_commitment in zk + pub coin_commitment: pallas::Point, + /// sender's coin pk + pub coin_pk: pallas::Base, + /// sender's coin sk's root + pub coin_root_sk: MerkleNode, + /// coin3_commitment in zk + pub change_coin_commitment: pallas::Point, + /// coin4_commitment in zk + pub transfered_coin_commitment: pallas::Point, + /// nullifiers coin1_nullifier + pub nullifier: pallas::Base, + /// sk coin pos + pub tau: pallas::Base, + /// root to coin's commitments + pub root: MerkleNode, + /// transfer proof + pub proof: Proof, +} + +impl TransferStx { + + /// verify the transfer proof. + pub fn verify(&self, vk: VerifyingKey) -> Result<()> { + if let Err(e) = self.proof.verify(&vk, &self.public_inputs()) { + return Err(Error::TransferTxVerification) + } + Ok(()) + } + + /// arrange public inputs from Stxfer + pub fn public_inputs(&self) -> Vec { + let cm1 = self.coin_commitment.to_affine().coordinates().unwrap(); + let cm3 = self.change_coin_commitment.to_affine().coordinates().unwrap(); + let cm4 = self.transfered_coin_commitment.to_affine().coordinates().unwrap(); + vec![ + self.coin_pk, + *cm1.x(), + *cm1.y(), + *cm3.x(), + *cm3.y(), + *cm4.x(), + *cm4.y(), + self.root.inner(), + self.coin_root_sk.inner(), + self.nullifier, + ] + } +} diff --git a/src/consensus/tx.rs b/src/consensus/tx.rs index cd1e2dc37..85c59ad7b 100644 --- a/src/consensus/tx.rs +++ b/src/consensus/tx.rs @@ -1,6 +1,6 @@ use darkfi_serial::{Encodable, Decodable, SerialDecodable, SerialEncodable}; use crate::{ - consensus::{EncryptedTxRcpt, leadcoin::TransferStx}, + consensus::{EncryptedTxRcpt, TransferStx}, }; /// transfer transaction diff --git a/src/error.rs b/src/error.rs index 89574fa1b..cd1ef99a5 100644 --- a/src/error.rs +++ b/src/error.rs @@ -241,6 +241,9 @@ pub enum Error { #[error("Proposal contains missmatched headers")] ProposalHeadersMissmatchError, + #[error("unable to verify transfer transaction")] + TransferTxVerification, + // =============== // Database errors // ===============