Migrate more crypto API to sdk

This commit is contained in:
parazyd
2022-11-07 22:27:24 +01:00
parent aa49a4c650
commit e6455facb7
43 changed files with 294 additions and 213 deletions

View File

@@ -22,7 +22,7 @@ use darkfi_sdk::{
crypto::PublicKey,
pasta::{
arithmetic::CurveAffine,
group::{Curve, Group},
group::{ff::PrimeField, Curve, Group},
pallas,
},
};
@@ -35,7 +35,7 @@ use darkfi::{
use crate::{
contract::{dao, dao::CONTRACT_ID, money},
util::{CallDataBase, HashableBase, StateRegistry, Transaction, UpdateBase},
util::{CallDataBase, StateRegistry, Transaction, UpdateBase},
};
type Result<T> = std::result::Result<T, Error>;
@@ -191,7 +191,7 @@ pub fn state_transition(
// 3. get the ProposalVote from DAO::State
let state =
states.lookup::<dao::State>(*CONTRACT_ID).expect("Return type is not of type State");
let proposal_votes = state.proposal_votes.get(&HashableBase(call_data.proposal)).unwrap();
let proposal_votes = state.proposal_votes.get(&call_data.proposal.to_repr()).unwrap();
// 4. check yes_votes_commit is the same as in ProposalVote
if proposal_votes.yes_votes_commit != call_data.yes_votes_commit {
@@ -215,6 +215,6 @@ impl UpdateBase for Update {
let state = states
.lookup_mut::<dao::State>(*CONTRACT_ID)
.expect("Return type is not of type State");
state.proposal_votes.remove(&HashableBase(self.proposal)).unwrap();
state.proposal_votes.remove(&self.proposal.to_repr()).unwrap();
}
}

View File

@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, SecretKey};
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, poseidon_hash, SecretKey};
use halo2_proofs::circuit::Value;
use log::debug;
use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{PublicKey, SecretKey};
use darkfi_sdk::crypto::{poseidon_hash, PublicKey, SecretKey};
use halo2_proofs::circuit::Value;
use pasta_curves::pallas;
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, MerkleNode, PublicKey, SecretKey};
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
use incrementalmerkletree::Hashable;
@@ -28,7 +30,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -21,9 +21,10 @@ use std::{any::Any, collections::HashMap};
use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode, Nullifier};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use pasta_curves::{group::Group, pallas};
use crate::util::HashableBase;
use pasta_curves::{
group::{ff::PrimeField, Group},
pallas,
};
#[derive(Clone, SerialEncodable, SerialDecodable)]
pub struct DaoBulla(pub pallas::Base);
@@ -55,7 +56,7 @@ pub struct State {
//proposal_bullas: Vec<pallas::Base>,
pub proposal_tree: MerkleTree,
pub proposal_roots: Vec<MerkleNode>,
pub proposal_votes: HashMap<HashableBase, ProposalVotes>,
pub proposal_votes: HashMap<[u8; 32], ProposalVotes>,
}
impl State {
@@ -84,7 +85,7 @@ impl State {
self.proposal_tree.append(&node);
self.proposal_roots.push(self.proposal_tree.root(0).unwrap());
self.proposal_votes.insert(
HashableBase(bulla),
bulla.to_repr(),
ProposalVotes {
yes_votes_commit: pallas::Point::identity(),
all_votes_commit: pallas::Point::identity(),
@@ -94,13 +95,13 @@ impl State {
}
pub fn lookup_proposal_votes(&self, proposal_bulla: pallas::Base) -> Option<&ProposalVotes> {
self.proposal_votes.get(&HashableBase(proposal_bulla))
self.proposal_votes.get(&proposal_bulla.to_repr())
}
pub fn lookup_proposal_votes_mut(
&mut self,
proposal_bulla: pallas::Base,
) -> Option<&mut ProposalVotes> {
self.proposal_votes.get_mut(&HashableBase(proposal_bulla))
self.proposal_votes.get_mut(&proposal_bulla.to_repr())
}
pub fn is_valid_dao_merkle(&self, root: &MerkleNode) -> bool {

View File

@@ -17,7 +17,8 @@
*/
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey,
pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode, Nullifier, PublicKey,
SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
@@ -31,7 +32,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -22,7 +22,6 @@ use darkfi::{
crypto::{
proof::{ProvingKey, VerifyingKey},
types::{DrkSpendHook, DrkUserData, DrkValue},
util::poseidon_hash,
},
rpc::server::listen_and_serve,
zk::circuit::{BurnContract, MintContract},
@@ -30,7 +29,7 @@ use darkfi::{
Error, Result,
};
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, Keypair, MerkleNode, PublicKey, SecretKey,
pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode, PublicKey, SecretKey,
};
use fxhash::FxHashMap;
use group::ff::PrimeField;
@@ -166,7 +165,7 @@ use crate::{
pub struct Client {
dao_wallet: DaoWallet,
money_wallets: FxHashMap<PublicKey, MoneyWallet>,
money_wallets: FxHashMap<[u8; 32], MoneyWallet>,
cashier_wallet: CashierWallet,
states: StateRegistry,
zk_bins: ZkContractTable,
@@ -426,7 +425,7 @@ impl Client {
debug!("DAO received a coin worth {} xDRK", note.value);
}
for (_key, wallet) in &mut self.money_wallets {
for wallet in self.money_wallets.values_mut() {
let coins = state.wallet_cache.get_received(&wallet.keypair.secret);
for coin in coins {
let note = coin.note.clone();
@@ -465,7 +464,7 @@ impl Client {
// To be able to make a proposal, we must prove we have ownership
// of governance tokens, and that the quantity of governance
// tokens is within the accepted proposer limit.
let sender_wallet = self.money_wallets.get_mut(&sender);
let sender_wallet = self.money_wallets.get_mut(&sender.to_bytes());
if sender_wallet.is_none() {
return Err(DaoError::NoWalletFound)
}
@@ -502,7 +501,7 @@ impl Client {
let dao_params = self.dao_wallet.params[0].clone();
let dao_keypair = self.dao_wallet.keypair;
let voter_wallet = self.money_wallets.get_mut(&pubkey);
let voter_wallet = self.money_wallets.get_mut(&pubkey.to_bytes());
if voter_wallet.is_none() {
return Err(DaoError::NoWalletFound)
}
@@ -641,7 +640,8 @@ impl DaoWallet {
let state =
states.lookup_mut::<dao::State>(*dao::CONTRACT_ID).ok_or(DaoError::StateNotFound)?;
let path = state.dao_tree.witness().ok_or(Error::Custom("Tree is empty".to_owned()))?;
let path =
state.dao_tree.witness().ok_or_else(|| Error::Custom("Tree is empty".to_owned()))?;
self.leaf_position = path;
Ok(())
}
@@ -719,13 +719,15 @@ impl DaoWallet {
let tree = &state.tree;
let leaf_position = own_coin.leaf_position;
let root = tree.root(0).ok_or(Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
))?;
let root = tree.root(0).ok_or_else(|| {
Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
)
})?;
let merkle_path = tree
.authentication_path(leaf_position, &root)
.ok_or(Error::Custom("No available authentication path to that position or if the root does not correspond to a checkpointed root of the tree".to_owned()))?;
.ok_or_else(|| Error::Custom("No available authentication path to that position or if the root does not correspond to a checkpointed root of the tree".to_owned()))?;
(leaf_position, merkle_path)
};
@@ -957,12 +959,14 @@ impl MoneyWallet {
let state =
states.lookup::<dao::State>(*dao::CONTRACT_ID).ok_or(DaoError::StateNotFound)?;
let tree = &state.dao_tree;
let root = tree.root(0).ok_or(Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
))?;
let root = tree.root(0).ok_or_else(|| {
Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
)
})?;
let merkle_path = tree.authentication_path(dao_leaf_position, &root)
.ok_or(Error::Custom(
.ok_or_else(|| Error::Custom(
"No available authentication path to that position or if the root does not correspond to a checkpointed root of the tree"
.to_owned()
))?;
@@ -1012,11 +1016,13 @@ impl MoneyWallet {
let tree = &state.tree;
let leaf_position = own_coin.leaf_position;
let root = tree.root(0).ok_or(Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
))?;
let merkle_path = tree.authentication_path(leaf_position, &root).ok_or(Error::Custom(
let root = tree.root(0).ok_or_else(|| {
Error::Custom(
"Not enough checkpoints available to reach the requested checkpoint depth."
.to_owned(),
)
})?;
let merkle_path = tree.authentication_path(leaf_position, &root).ok_or_else(|| Error::Custom(
"No available authentication path to that position or the root does not correspond to a checkpointed root of the tree"
.to_owned()
))?;

View File

@@ -199,7 +199,7 @@ impl JsonRpcInterface {
let nym = nym.unwrap();
match PublicKey::from_str(nym) {
Ok(key) => match client.money_wallets.get(&key) {
Ok(key) => match client.money_wallets.get(&key.to_bytes()) {
Some(wallet) => {
let balance = wallet.balances().unwrap();
JsonResponse::new(json!(balance), id).into()
@@ -260,7 +260,7 @@ impl JsonRpcInterface {
match money_wallet.track(&mut client.states) {
Ok(_) => {
client.money_wallets.insert(keypair.public, money_wallet);
client.money_wallets.insert(keypair.public.to_bytes(), money_wallet);
//let addr: String = bs58::encode(keypair.public.to_bytes()).into_string();
let addr: String = keypair.public.to_string();
JsonResponse::new(json!(addr), id).into()
@@ -368,7 +368,7 @@ impl JsonRpcInterface {
let addr = addr.unwrap();
let balance = match PublicKey::from_str(addr) {
Ok(key) => match client.money_wallets.get(&key) {
Ok(key) => match client.money_wallets.get(&key.to_bytes()) {
Some(wallet) => {
let balance = wallet.balances().unwrap();
let token_id = bs58::encode((*GOV_ID).to_repr()).into_string();

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{any::Any, collections::HashMap, hash::Hasher};
use std::{any::Any, collections::HashMap};
use darkfi_sdk::crypto::{
schnorr::{SchnorrPublic, SchnorrSecret, Signature},
@@ -69,16 +69,6 @@ lazy_static! {
pub static ref GOV_ID: pallas::Base = pallas::Base::random(&mut OsRng);
}
#[derive(Eq, PartialEq, Debug)]
pub struct HashableBase(pub pallas::Base);
impl std::hash::Hash for HashableBase {
fn hash<H: Hasher>(&self, state: &mut H) {
let bytes = self.0.to_repr();
bytes.hash(state);
}
}
#[derive(Clone)]
pub struct ZkBinaryContractInfo {
pub k_param: u32,
@@ -263,7 +253,7 @@ pub trait CallDataBase {
type GenericContractState = Box<dyn Any + Send>;
pub struct StateRegistry {
pub states: HashMap<HashableBase, GenericContractState>,
pub states: HashMap<[u8; 32], GenericContractState>,
}
impl StateRegistry {
@@ -273,15 +263,15 @@ impl StateRegistry {
pub fn register(&mut self, contract_id: ContractId, state: GenericContractState) {
debug!(target: "StateRegistry::register()", "contract_id: {:?}", contract_id);
self.states.insert(HashableBase(contract_id), state);
self.states.insert(contract_id.to_repr(), state);
}
pub fn lookup_mut<'a, S: 'static>(&'a mut self, contract_id: ContractId) -> Option<&'a mut S> {
self.states.get_mut(&HashableBase(contract_id)).and_then(|state| state.downcast_mut())
self.states.get_mut(&contract_id.to_repr()).and_then(|state| state.downcast_mut())
}
pub fn lookup<'a, S: 'static>(&'a self, contract_id: ContractId) -> Option<&'a S> {
self.states.get(&HashableBase(contract_id)).and_then(|state| state.downcast_ref())
self.states.get(&contract_id.to_repr()).and_then(|state| state.downcast_ref())
}
}

View File

@@ -551,7 +551,7 @@ async fn sign_tx(endpoint: Url, data: &str) -> Result<Transaction> {
exit(1);
}
tx.inputs[idx_to_sign].signature = signature.clone();
tx.inputs[idx_to_sign].signature = signature;
Ok(tx)
}

View File

@@ -22,7 +22,7 @@ use darkfi_sdk::crypto::PublicKey;
use darkfi_serial::{Encodable, SerialDecodable, SerialEncodable};
use pasta_curves::{
arithmetic::CurveAffine,
group::{Curve, Group},
group::{ff::PrimeField, Curve, Group},
pallas,
};
@@ -33,7 +33,7 @@ use darkfi::{
use crate::{
contract::{dao, dao::CONTRACT_ID, money},
util::{CallDataBase, HashableBase, StateRegistry, Transaction, UpdateBase},
util::{CallDataBase, StateRegistry, Transaction, UpdateBase},
};
type Result<T> = std::result::Result<T, Error>;
@@ -189,7 +189,7 @@ pub fn state_transition(
// 3. get the ProposalVote from DAO::State
let state =
states.lookup::<dao::State>(*CONTRACT_ID).expect("Return type is not of type State");
let proposal_votes = state.proposal_votes.get(&HashableBase(call_data.proposal)).unwrap();
let proposal_votes = state.proposal_votes.get(&call_data.proposal.to_repr()).unwrap();
// 4. check yes_votes_commit is the same as in ProposalVote
if proposal_votes.yes_votes_commit != call_data.yes_votes_commit {
@@ -213,6 +213,6 @@ impl UpdateBase for Update {
let state = states
.lookup_mut::<dao::State>(*CONTRACT_ID)
.expect("Return type is not of type State");
state.proposal_votes.remove(&HashableBase(self.proposal)).unwrap();
state.proposal_votes.remove(&self.proposal.to_repr()).unwrap();
}
}

View File

@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, SecretKey};
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, poseidon_hash, SecretKey};
use halo2_proofs::circuit::Value;
use log::debug;
use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{PublicKey, SecretKey};
use darkfi_sdk::crypto::{poseidon_hash, PublicKey, SecretKey};
use halo2_proofs::circuit::Value;
use pasta_curves::pallas;
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, MerkleNode, PublicKey, SecretKey};
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
use incrementalmerkletree::Hashable;
@@ -28,7 +30,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -21,9 +21,10 @@ use std::{any::Any, collections::HashMap};
use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode, Nullifier};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use pasta_curves::{group::Group, pallas};
use crate::util::HashableBase;
use pasta_curves::{
group::{ff::PrimeField, Group},
pallas,
};
#[derive(Clone, SerialEncodable, SerialDecodable)]
pub struct DaoBulla(pub pallas::Base);
@@ -55,7 +56,7 @@ pub struct State {
//proposal_bullas: Vec<pallas::Base>,
pub proposal_tree: MerkleTree,
pub proposal_roots: Vec<MerkleNode>,
pub proposal_votes: HashMap<HashableBase, ProposalVotes>,
pub proposal_votes: HashMap<[u8; 32], ProposalVotes>,
}
impl State {
@@ -84,7 +85,7 @@ impl State {
self.proposal_tree.append(&node);
self.proposal_roots.push(self.proposal_tree.root(0).unwrap());
self.proposal_votes.insert(
HashableBase(bulla),
bulla.to_repr(),
ProposalVotes {
yes_votes_commit: pallas::Point::identity(),
all_votes_commit: pallas::Point::identity(),
@@ -94,13 +95,13 @@ impl State {
}
pub fn lookup_proposal_votes(&self, proposal_bulla: pallas::Base) -> Option<&ProposalVotes> {
self.proposal_votes.get(&HashableBase(proposal_bulla))
self.proposal_votes.get(&proposal_bulla.to_repr())
}
pub fn lookup_proposal_votes_mut(
&mut self,
proposal_bulla: pallas::Base,
) -> Option<&mut ProposalVotes> {
self.proposal_votes.get_mut(&HashableBase(proposal_bulla))
self.proposal_votes.get_mut(&proposal_bulla.to_repr())
}
pub fn is_valid_dao_merkle(&self, root: &MerkleNode) -> bool {

View File

@@ -17,7 +17,8 @@
*/
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey,
pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode, Nullifier, PublicKey,
SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
@@ -31,7 +32,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -22,8 +22,8 @@ use std::{
};
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, Keypair, MerkleNode, PublicKey,
SecretKey,
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode,
PublicKey, SecretKey,
};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use log::debug;
@@ -38,7 +38,6 @@ use darkfi::{
coin::Coin,
proof::{ProvingKey, VerifyingKey},
types::{DrkSpendHook, DrkUserData, DrkValue},
util::poseidon_hash,
},
zk::circuit::{BurnContract, MintContract},
zkas::decoder::ZkBinary,
@@ -71,6 +70,12 @@ pub struct WalletCache {
tree: MerkleTree,
}
impl Default for WalletCache {
fn default() -> Self {
Self { cache: Vec::new(), tree: MerkleTree::new(100) }
}
}
impl WalletCache {
pub fn new() -> Self {
Self { cache: Vec::new(), tree: MerkleTree::new(100) }

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{any::Any, collections::HashMap, hash::Hasher};
use std::{any::Any, collections::HashMap};
use darkfi_sdk::crypto::{
schnorr::{SchnorrPublic, SchnorrSecret, Signature},
@@ -68,16 +68,6 @@ lazy_static! {
pub static ref GOV_ID: pallas::Base = pallas::Base::random(&mut OsRng);
}
#[derive(Eq, PartialEq, Debug)]
pub struct HashableBase(pub pallas::Base);
impl std::hash::Hash for HashableBase {
fn hash<H: Hasher>(&self, state: &mut H) {
let bytes = self.0.to_repr();
bytes.hash(state);
}
}
#[derive(Clone)]
pub struct ZkBinaryContractInfo {
pub k_param: u32,
@@ -255,7 +245,7 @@ pub trait CallDataBase {
type GenericContractState = Box<dyn Any + Send>;
pub struct StateRegistry {
pub states: HashMap<HashableBase, GenericContractState>,
pub states: HashMap<[u8; 32], GenericContractState>,
}
impl StateRegistry {
@@ -265,15 +255,15 @@ impl StateRegistry {
pub fn register(&mut self, contract_id: ContractId, state: GenericContractState) {
debug!(target: "StateRegistry::register()", "contract_id: {:?}", contract_id);
self.states.insert(HashableBase(contract_id), state);
self.states.insert(contract_id.to_repr(), state);
}
pub fn lookup_mut<'a, S: 'static>(&'a mut self, contract_id: ContractId) -> Option<&'a mut S> {
self.states.get_mut(&HashableBase(contract_id)).and_then(|state| state.downcast_mut())
self.states.get_mut(&contract_id.to_repr()).and_then(|state| state.downcast_mut())
}
pub fn lookup<'a, S: 'static>(&'a self, contract_id: ContractId) -> Option<&'a S> {
self.states.get(&HashableBase(contract_id)).and_then(|state| state.downcast_ref())
self.states.get(&contract_id.to_repr()).and_then(|state| state.downcast_ref())
}
}

View File

@@ -16,14 +16,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, SecretKey};
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, poseidon_hash, SecretKey};
use halo2_proofs::circuit::Value;
use log::debug;
use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,13 +16,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{PublicKey, SecretKey};
use darkfi_sdk::crypto::{poseidon_hash, PublicKey, SecretKey};
use halo2_proofs::circuit::Value;
use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{pedersen::pedersen_commitment_u64, MerkleNode, PublicKey, SecretKey};
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, poseidon_hash, MerkleNode, PublicKey, SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
use incrementalmerkletree::Hashable;
@@ -28,7 +30,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -17,7 +17,8 @@
*/
use darkfi_sdk::crypto::{
pedersen::pedersen_commitment_u64, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey,
pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode, Nullifier, PublicKey,
SecretKey,
};
use darkfi_serial::{SerialDecodable, SerialEncodable};
use halo2_proofs::circuit::Value;
@@ -31,7 +32,7 @@ use pasta_curves::{
use rand::rngs::OsRng;
use darkfi::{
crypto::{util::poseidon_hash, Proof},
crypto::Proof,
zk::vm::{Witness, ZkCircuit},
};

View File

@@ -5,7 +5,6 @@ use darkfi::{
coin::Coin,
proof::{ProvingKey, VerifyingKey},
types::{DrkSpendHook, DrkUserData, DrkValue},
util::poseidon_hash,
},
runtime::vm_runtime::Runtime,
zk::circuit::{BurnContract, MintContract},
@@ -14,8 +13,8 @@ use darkfi::{
};
use darkfi_sdk::{
crypto::{
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, ContractId, Keypair,
MerkleNode, MerkleTree, PublicKey, SecretKey,
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, poseidon_hash, ContractId,
Keypair, MerkleNode, MerkleTree, PublicKey, SecretKey,
},
tx::ContractCall,
};

View File

@@ -22,8 +22,8 @@ use std::{
};
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, Keypair, MerkleNode, PublicKey,
SecretKey,
constants::MERKLE_DEPTH, pedersen::pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode,
PublicKey, SecretKey,
};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use log::debug;
@@ -35,7 +35,6 @@ use darkfi::{
coin::Coin,
proof::{ProvingKey, VerifyingKey},
types::{DrkSpendHook, DrkUserData, DrkValue},
util::poseidon_hash,
},
zk::circuit::{BurnContract, MintContract},
zkas::decoder::ZkBinary,

View File

@@ -18,7 +18,7 @@
// Example transaction flow
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey,
constants::MERKLE_DEPTH, poseidon_hash, Keypair, MerkleNode, Nullifier, PublicKey, SecretKey,
};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use pasta_curves::{group::ff::Field, pallas};
@@ -29,7 +29,6 @@ use darkfi::{
coin::OwnCoin,
note::{EncryptedNote, Note},
proof::{ProvingKey, VerifyingKey},
util::poseidon_hash,
},
node::state::{state_transition, ProgramState, StateUpdate},
tx::builder::{

View File

@@ -20,6 +20,7 @@ use darkfi_sdk::{
crypto::{
constants::MERKLE_DEPTH_ORCHARD,
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
poseidon_hash,
util::mod_r_p,
Keypair, MerkleNode, Nullifier, SecretKey,
},
@@ -45,7 +46,6 @@ use crate::{
leadcoin::LeadCoin,
note::Note,
types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValueBlind},
util::poseidon_hash,
},
wallet::walletdb::WalletDb,
Result,

View File

@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode, Nullifier, PublicKey, SecretKey};
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH, poseidon_hash, MerkleNode, Nullifier, PublicKey, SecretKey,
};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use crate::{
@@ -24,7 +26,6 @@ use crate::{
coin::OwnCoin,
note::{EncryptedNote, Note},
proof::VerifyingKey,
util::poseidon_hash,
},
node::state::{ProgramState, StateUpdate},
};

View File

@@ -21,7 +21,7 @@ use std::time::Instant;
use darkfi_sdk::{
crypto::{
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
MerkleNode, Nullifier, PublicKey, SecretKey,
poseidon_hash, MerkleNode, Nullifier, PublicKey, SecretKey,
},
incrementalmerkletree::Hashable,
pasta::{arithmetic::CurveAffine, group::Curve},
@@ -33,12 +33,9 @@ use rand::rngs::OsRng;
use super::proof::{Proof, ProvingKey, VerifyingKey};
use crate::{
crypto::{
types::{
DrkCircuitField, DrkCoinBlind, DrkSerial, DrkSpendHook, DrkTokenId, DrkUserData,
DrkUserDataBlind, DrkUserDataEnc, DrkValue, DrkValueBlind, DrkValueCommit,
},
util::poseidon_hash,
crypto::types::{
DrkCircuitField, DrkCoinBlind, DrkSerial, DrkSpendHook, DrkTokenId, DrkUserData,
DrkUserDataBlind, DrkUserDataEnc, DrkValue, DrkValueBlind, DrkValueCommit,
},
zk::circuit::burn_contract::BurnContract,
Result,

View File

@@ -22,11 +22,11 @@ use num_bigint::BigUint;
use num_traits::Num;
/// Modulus of prime field 2^256 - 2^32 * 351 + 1
pub const MODULUS: &str =
const MODULUS: &str =
"115792089237316195423570985008687907853269984665640564039457584006405596119041";
/// An exponent to perform inverse of x^3 on prime field based on Fermat's Little Theorem
pub const L_FERMAT_EXPONENT: &str =
const L_FERMAT_EXPONENT: &str =
"77194726158210796949047323339125271902179989777093709359638389337603730746027";
/// Calculates set of round constants to perform MiMC-calculation on.

View File

@@ -21,7 +21,7 @@ use std::time::Instant;
use darkfi_sdk::{
crypto::{
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
PublicKey,
poseidon_hash, PublicKey,
},
pasta::{arithmetic::CurveAffine, group::Curve},
};
@@ -38,7 +38,6 @@ use crate::{
DrkCircuitField, DrkCoinBlind, DrkSerial, DrkSpendHook, DrkTokenId, DrkUserData,
DrkValue, DrkValueBlind, DrkValueCommit,
},
util::poseidon_hash,
},
zk::circuit::mint_contract::MintContract,
Result,

View File

@@ -25,7 +25,6 @@ pub mod proof;
pub mod token_id;
pub mod token_list;
pub mod types;
pub mod util;
/// VDF (Verifiable Delay Function) using MiMC
pub mod mimc_vdf;

View File

@@ -1,47 +0,0 @@
/* 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 <https://www.gnu.org/licenses/>.
*/
use blake2b_simd::Params;
use darkfi_sdk::crypto::constants::util::gen_const_array;
use halo2_gadgets::poseidon::primitives as poseidon;
use pasta_curves::{arithmetic::FieldExt, pallas};
pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar {
let mut hasher = Params::new().hash_length(64).personal(persona).to_state();
hasher.update(a);
hasher.update(b);
let ret = hasher.finalize();
pallas::Scalar::from_bytes_wide(ret.as_array())
}
/// Simplified wrapper for poseidon hash function.
pub fn poseidon_hash<const N: usize>(messages: [pallas::Base; N]) -> pallas::Base {
poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<N>, 3, 2>::init()
.hash(messages)
}
/// The sequence of bits representing a u64 in little-endian order.
///
/// # Panics
///
/// Panics if the expected length of the sequence `NUM_BITS` exceeds
/// 64.
pub fn i2lebsp<const NUM_BITS: usize>(int: u64) -> [bool; NUM_BITS] {
assert!(NUM_BITS <= 64);
gen_const_array(|mask: usize| (int & (1 << mask)) != 0)
}

View File

@@ -16,7 +16,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use darkfi_sdk::crypto::{constants::MERKLE_DEPTH, MerkleNode, Nullifier, PublicKey, SecretKey};
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH, poseidon_hash, MerkleNode, Nullifier, PublicKey, SecretKey,
};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
use lazy_init::Lazy;
use log::{debug, error};
@@ -28,7 +30,6 @@ use crate::{
coin::{Coin, OwnCoin},
note::{EncryptedNote, Note},
proof::VerifyingKey,
util::poseidon_hash,
},
tx::Transaction,
wallet::walletdb::WalletPtr,

View File

@@ -20,9 +20,9 @@ use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
use pasta_curves::{group::ff::PrimeField, pallas};
use super::{poseidon_hash, PublicKey, SecretKey};
use crate::error::ContractError;
/// ContractId represents an on-chain identifier for a certain
/// smart contract.
/// ContractId represents an on-chain identifier for a certain smart contract.
#[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
pub struct ContractId(pallas::Base);
@@ -41,9 +41,13 @@ impl ContractId {
}
/// Create a `ContractId` object from given bytes.
pub fn from_bytes(x: [u8; 32]) -> Self {
// FIXME: Handle Option
Self(pallas::Base::from_repr(x).unwrap())
pub fn from_bytes(x: [u8; 32]) -> Result<Self, ContractError> {
match pallas::Base::from_repr(x).into() {
Some(v) => Ok(Self(v)),
None => Err(ContractError::IoError(
"Failed to instantiate ContractId from bytes".to_string(),
)),
}
}
/// `blake3(self || tree_name)` is used in datbases to have a
@@ -63,10 +67,41 @@ impl From<pallas::Base> for ContractId {
}
}
impl std::fmt::Display for ContractId {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
// base58 encoding
impl core::fmt::Display for ContractId {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
// Base58 encoding
let contractid: String = bs58::encode(self.0.to_repr()).into_string();
write!(f, "{}", contractid)
}
}
impl TryFrom<&str> for ContractId {
type Error = ContractError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let bytes: [u8; 32] = match bs58::decode(s).into_vec() {
Ok(v) => {
if v.len() != 32 {
return Err(ContractError::IoError(
"Decoded bs58 string for ContractId is not 32 bytes long".to_string(),
))
}
v.try_into().unwrap()
}
Err(e) => {
return Err(ContractError::IoError(format!(
"Failed to decode bs58 for ContractId: {}",
e
)))
}
};
match pallas::Base::from_repr(bytes).into() {
Some(v) => Ok(Self(v)),
None => {
Err(ContractError::IoError("Bytes for ContractId are noncanonical".to_string()))
}
}
}
}

View File

@@ -119,7 +119,7 @@ impl PublicKey {
/// Derive a new `PublicKey` object given a `SecretKey`
pub fn from_secret(s: SecretKey) -> Self {
let p = NullifierK.generator() * mod_r_p(s.inner());
Self(pallas::Point::from(p))
Self(p)
}
/// Instantiate a `PublicKey` given 32 bytes. Returns an error
@@ -131,6 +131,11 @@ impl PublicKey {
}
}
/// Downcast the `PublicKey` to 32 bytes of `pallas::Point`
pub fn to_bytes(&self) -> [u8; 32] {
self.0.to_bytes()
}
/// Fetch the `x` coordinate of this `PublicKey`
pub fn x(&self) -> pallas::Base {
*self.0.to_affine().coordinates().unwrap().x()
@@ -154,13 +159,6 @@ impl From<pallas::Point> for PublicKey {
}
}
impl core::hash::Hash for PublicKey {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
let bytes = self.0.to_affine().to_bytes();
bytes.hash(state);
}
}
impl FromStr for PublicKey {
type Err = ContractError;

View File

@@ -46,6 +46,10 @@ pub use address::Address;
pub mod contract_id;
pub use contract_id::ContractId;
/// Token ID definitions and methods
pub mod token_id;
pub use token_id::TokenId;
/// Merkle node definitions
pub mod merkle_node;
pub use merkle_node::{MerkleNode, MerkleTree};

View File

@@ -0,0 +1,96 @@
/* 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 <https://www.gnu.org/licenses/>.
*/
use darkfi_serial::{SerialDecodable, SerialEncodable};
use pasta_curves::{group::ff::PrimeField, pallas};
use super::{poseidon_hash, PublicKey, SecretKey};
use crate::error::ContractError;
/// TokenId represents an on-chain identifier for a certain token.
#[derive(Copy, Clone, Debug, Eq, PartialEq, SerialEncodable, SerialDecodable)]
pub struct TokenId(pallas::Base);
impl TokenId {
/// Derives a `TokenId` given a `SecretKey` (mint authority)
pub fn derive(mint_authority: SecretKey) -> Self {
let public_key = PublicKey::from_secret(mint_authority);
let (x, y) = public_key.xy();
let hash = poseidon_hash::<2>([x, y]);
Self(hash)
}
/// Get the inner `pallas::Base` element.
pub fn inner(&self) -> pallas::Base {
self.0
}
/// Create a `TokenId` object from given bytes, erroring if the input
/// bytes are noncanonical.
pub fn from_bytes(x: [u8; 32]) -> Result<Self, ContractError> {
match pallas::Base::from_repr(x).into() {
Some(v) => Ok(Self(v)),
None => {
Err(ContractError::IoError("Failed to instantiate TokenId from bytes".to_string()))
}
}
}
}
impl From<pallas::Base> for TokenId {
fn from(x: pallas::Base) -> Self {
Self(x)
}
}
impl core::fmt::Display for TokenId {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
// Base58 encoding
let tokenid: String = bs58::encode(self.0.to_repr()).into_string();
write!(f, "{}", tokenid)
}
}
impl TryFrom<&str> for TokenId {
type Error = ContractError;
fn try_from(s: &str) -> Result<Self, Self::Error> {
let bytes: [u8; 32] = match bs58::decode(s).into_vec() {
Ok(v) => {
if v.len() != 32 {
return Err(ContractError::IoError(
"Decoded bs58 string for TokenId is not 32 bytes long".to_string(),
))
}
v.try_into().unwrap()
}
Err(e) => {
return Err(ContractError::IoError(format!(
"Failed to decode bs58 for TokenId: {}",
e
)))
}
};
match pallas::Base::from_repr(bytes).into() {
Some(v) => Ok(Self(v)),
None => Err(ContractError::IoError("Bytes for TokenId are noncanonical".to_string())),
}
}
}

View File

@@ -49,7 +49,7 @@ pub fn db_init(contract_id: ContractId, db_name: &str) -> GenericResult<DbHandle
}
}
return Ok(ret as u32)
Ok(ret as u32)
}
}
@@ -70,7 +70,7 @@ pub fn db_lookup(contract_id: ContractId, db_name: &str) -> GenericResult<DbHand
}
}
return Ok(ret as u32)
Ok(ret as u32)
}
}
@@ -118,7 +118,7 @@ pub fn db_set(db_handle: DbHandle, key: &[u8], value: &[u8]) -> GenericResult<()
len += key.to_vec().encode(&mut buf)?;
len += value.to_vec().encode(&mut buf)?;
return match db_set_(buf.as_ptr(), len as u32) {
match db_set_(buf.as_ptr(), len as u32) {
0 => Ok(()),
-1 => Err(ContractError::CallerAccessDenied),
-2 => Err(ContractError::DbSetFailed),

View File

@@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::{mem::size_of, slice::from_raw_parts};
use core::{mem::size_of, slice::from_raw_parts};
use crate::crypto::ContractId;
@@ -72,6 +72,7 @@ macro_rules! define_contract {
}
/// Deserialize a given payload in `entrypoint`
/// The return values from this are the input values for the above defined functions.
/// # Safety
pub unsafe fn deserialize<'a>(input: *mut u8) -> (ContractId, &'a [u8]) {
let mut offset: usize = 0;
@@ -84,8 +85,9 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (ContractId, &'a [u8]) {
offset += size_of::<u64>();
let instruction_data = { from_raw_parts(input.add(offset), instruction_data_len) };
// FIXME: ContractId recovery should use proper serialization, and also
// there should be a Result<>; we can match on it in the macros
// above and return errors if needed.
(ContractId::from_bytes(contract_id_slice.try_into().unwrap()), instruction_data)
let contract_id = ContractId::from_bytes(contract_id_slice.try_into().unwrap());
// We unwrap here because if this panics, something's wrong in the runtime:
let contract_id = contract_id.unwrap();
(contract_id, instruction_data)
}

View File

@@ -36,7 +36,8 @@ pub fn merkle_add(
len += db_roots.encode(&mut buf)?;
len += key.to_vec().encode(&mut buf)?;
len += coin.encode(&mut buf)?;
return match unsafe { merkle_add_(buf.as_ptr(), len as u32) } {
match unsafe { merkle_add_(buf.as_ptr(), len as u32) } {
0 => Ok(()),
-1 => Err(ContractError::CallerAccessDenied),
-2 => Err(ContractError::DbSetFailed),

View File

@@ -20,7 +20,7 @@ use super::error::ContractError;
pub fn set_return_data(data: &[u8]) -> Result<(), ContractError> {
unsafe {
return match set_return_data_(data.as_ptr(), data.len() as u32) {
match set_return_data_(data.as_ptr(), data.len() as u32) {
0 => Ok(()),
errcode => Err(ContractError::from(errcode)),
}
@@ -28,15 +28,15 @@ pub fn set_return_data(data: &[u8]) -> Result<(), ContractError> {
}
pub fn put_object_bytes(data: &[u8]) -> i64 {
unsafe { return put_object_bytes_(data.as_ptr(), data.len() as u32) }
unsafe { put_object_bytes_(data.as_ptr(), data.len() as u32) }
}
pub fn get_object_bytes(data: &mut [u8], object_index: u32) -> i64 {
unsafe { return get_object_bytes_(data.as_mut_ptr(), object_index as u32) }
unsafe { get_object_bytes_(data.as_mut_ptr(), object_index as u32) }
}
pub fn get_object_size(object_index: u32) -> i64 {
unsafe { return get_object_size_(object_index as u32) }
unsafe { get_object_size_(object_index as u32) }
}
extern "C" {

View File

@@ -534,11 +534,8 @@ impl WalletDb {
#[cfg(test)]
mod tests {
use super::*;
use crate::crypto::{
types::{DrkCoinBlind, DrkSerial, DrkValueBlind},
util::poseidon_hash,
};
use darkfi_sdk::crypto::MerkleNode;
use crate::crypto::types::{DrkCoinBlind, DrkSerial, DrkValueBlind};
use darkfi_sdk::crypto::{poseidon_hash, MerkleNode};
use incrementalmerkletree::Tree;
use pasta_curves::{group::ff::Field, pallas};
use rand::rngs::OsRng;

View File

@@ -19,7 +19,6 @@
use darkfi::{
crypto::{
proof::{ProvingKey, VerifyingKey},
util::poseidon_hash,
Proof,
},
zk::{
@@ -31,7 +30,7 @@ use darkfi::{
};
use darkfi_sdk::crypto::{
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
MerkleNode, Nullifier, PublicKey, SecretKey,
poseidon_hash, MerkleNode, Nullifier, PublicKey, SecretKey,
};
use halo2_gadgets::poseidon::primitives as poseidon;
use halo2_proofs::circuit::Value;