mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-08 22:28:12 -05:00
cherry picked fullwidth pedersen
This commit is contained in:
2
Makefile
2
Makefile
@@ -10,7 +10,7 @@ CARGO = cargo
|
||||
#RUSTFLAGS = -C target-cpu=native
|
||||
|
||||
# Binaries to be built
|
||||
BINS = zkas drk darkfid tau taud ircd dnetview
|
||||
BINS = zkas drk darkfid tau taud ircd dnetview darkotc
|
||||
|
||||
# Common dependencies which should force the binaries to be rebuilt
|
||||
BINDEPS = \
|
||||
|
||||
514
bin/darkotc/src/main.rs
Normal file
514
bin/darkotc/src/main.rs
Normal file
@@ -0,0 +1,514 @@
|
||||
use std::{
|
||||
io::{stdin, Read},
|
||||
process::exit,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use darkfi::crypto::proof::VerifyingKey;
|
||||
use halo2_proofs::{arithmetic::Field, pasta::group::ff::PrimeField};
|
||||
use rand::rngs::OsRng;
|
||||
use serde_json::json;
|
||||
use termion::color;
|
||||
use url::Url;
|
||||
|
||||
use darkfi::{
|
||||
cli_desc,
|
||||
crypto::{
|
||||
address::Address,
|
||||
burn_proof::{create_burn_proof, verify_burn_proof},
|
||||
keypair::{PublicKey, SecretKey},
|
||||
merkle_node::MerkleNode,
|
||||
mint_proof::{create_mint_proof, verify_mint_proof},
|
||||
proof::ProvingKey,
|
||||
token_id,
|
||||
types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValueBlind},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
BurnRevealedValues, MintRevealedValues, OwnCoin, Proof,
|
||||
},
|
||||
rpc::{client::RpcClient, jsonrpc::JsonRequest},
|
||||
util::{
|
||||
cli::progress_bar,
|
||||
encode_base10,
|
||||
serial::{deserialize, serialize, SerialDecodable, SerialEncodable},
|
||||
},
|
||||
zk::circuit::{BurnContract, MintContract},
|
||||
Result,
|
||||
};
|
||||
|
||||
mod cli_util;
|
||||
use cli_util::{parse_token_pair, parse_value_pair};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(name = "darkotc", about = cli_desc!(), version)]
|
||||
#[clap(arg_required_else_help(true))]
|
||||
struct Args {
|
||||
#[clap(short, parse(from_occurrences))]
|
||||
/// Increase verbosity (-vvv supported)
|
||||
verbose: u8,
|
||||
|
||||
#[clap(short, long, default_value = "tcp://127.0.0.1:8340")]
|
||||
/// darkfid JSON-RPC endpoint
|
||||
endpoint: Url,
|
||||
|
||||
#[clap(subcommand)]
|
||||
command: Subcmd,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Subcmd {
|
||||
/// Initialize an atomic swap
|
||||
Init {
|
||||
#[clap(short, long)]
|
||||
/// Pair of token IDs to swap: e.g. token_to_send:token_to_recv
|
||||
token_pair: String,
|
||||
|
||||
#[clap(short, long)]
|
||||
/// Pair of values to swap: e.g. value_to_send:value_to_recv
|
||||
value_pair: String,
|
||||
},
|
||||
|
||||
/// Inspect swap data from stdin or file.
|
||||
Inspect,
|
||||
}
|
||||
|
||||
struct Rpc {
|
||||
pub rpc_client: RpcClient,
|
||||
}
|
||||
|
||||
impl Rpc {
|
||||
async fn balance_of(&self, token_id: &str) -> Result<u64> {
|
||||
let req = JsonRequest::new("wallet.get_balances", json!([]));
|
||||
let rep = self.rpc_client.request(req).await?;
|
||||
|
||||
if !rep.is_object() {
|
||||
eprintln!("Error: Invalid balance data received from darkfid RPC endpoint.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for i in rep.as_object().unwrap().keys() {
|
||||
if i == &token_id {
|
||||
if let Some(balance) = rep[i].as_u64() {
|
||||
return Ok(balance)
|
||||
}
|
||||
|
||||
eprintln!("Error: Invalid balance data received from darkfid RPC endpoint.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
async fn wallet_address(&self) -> Result<Address> {
|
||||
let req = JsonRequest::new("wallet.get_addrs", json!([0_i64]));
|
||||
let rep = self.rpc_client.request(req).await?;
|
||||
|
||||
if !rep.is_array() || !rep.as_array().unwrap()[0].is_string() {
|
||||
eprintln!("Error: Invalid wallet address received from darkfid RPC endpoint.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Address::from_str(rep[0].as_str().unwrap())
|
||||
}
|
||||
|
||||
async fn get_coins_valtok(&self, value: u64, token_id: &str) -> Result<Vec<OwnCoin>> {
|
||||
let req = JsonRequest::new("wallet.get_coins_valtok", json!([value, token_id, true]));
|
||||
let rep = self.rpc_client.request(req).await?;
|
||||
|
||||
if !rep.is_array() {
|
||||
eprintln!("Error: Invalid coin data received from darkfid RPC endpoint.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let mut ret = vec![];
|
||||
let rep = rep.as_array().unwrap();
|
||||
|
||||
for i in rep {
|
||||
if !i.is_string() {
|
||||
eprintln!("Error: Invalid base58 data for OwnCoin");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let data = match bs58::decode(i.as_str().unwrap()).into_vec() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Failed decoding base58 for OwnCoin: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let oc = match deserialize(&data) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Failed deserializing OwnCoin: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
ret.push(oc);
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
async fn get_merkle_path(&self, leaf_pos: usize) -> Result<Vec<MerkleNode>> {
|
||||
let req = JsonRequest::new("wallet.get_merkle_path", json!([leaf_pos as u64]));
|
||||
let rep = self.rpc_client.request(req).await?;
|
||||
|
||||
if !rep.is_array() {
|
||||
eprintln!("Error: Invalid merkle path data received from darkfid RPC endpoint.");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let mut ret = vec![];
|
||||
let rep = rep.as_array().unwrap();
|
||||
|
||||
for i in rep {
|
||||
if !i.is_string() {
|
||||
eprintln!("Error: Invalid base58 data for MerkleNode");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let n = i.as_str().unwrap();
|
||||
let n = match bs58::decode(n).into_vec() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Failed decoding base58 for MerkleNode: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
if n.len() != 32 {
|
||||
eprintln!("Error: MerkleNode byte length is not 32");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
let n = MerkleNode::from_bytes(&n.try_into().unwrap());
|
||||
if n.is_some().unwrap_u8() == 0 {
|
||||
eprintln!("Error: Noncanonical bytes of MerkleNode");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret.push(n.unwrap());
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
async fn init_swap(
|
||||
endpoint: Url,
|
||||
token_pair: (String, String),
|
||||
value_pair: (u64, u64),
|
||||
) -> Result<()> {
|
||||
let rpc_client = RpcClient::new(endpoint).await?;
|
||||
let rpc = Rpc { rpc_client };
|
||||
|
||||
// TODO: Think about decimals, there has to be some metadata to keep track.
|
||||
let tp = (token_id::parse_b58(&token_pair.0)?, token_id::parse_b58(&token_pair.1)?);
|
||||
let vp: (u64, u64) =
|
||||
(value_pair.0.clone().try_into().unwrap(), value_pair.1.clone().try_into().unwrap());
|
||||
|
||||
// Connect to darkfid and see if there's available funds.
|
||||
let balance = rpc.balance_of(&token_pair.0).await?;
|
||||
if balance < vp.0 {
|
||||
eprintln!(
|
||||
"Error: There is not enough balance for token \"{}\" in your wallet.",
|
||||
token_pair.0
|
||||
);
|
||||
eprintln!("Available balance is {} ({})", encode_base10(balance, 8), balance);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// If not enough funds in a single coin, mint a single new coin
|
||||
// with the funds. We do this to minimize the size of the swap
|
||||
// transaction, i.e. 2 inputs and 2 outputs.
|
||||
// TODO: Implement ^
|
||||
// TODO: Maybe this should be done by the user beforehand?
|
||||
|
||||
// Find a coin to spend
|
||||
let coins = rpc.get_coins_valtok(vp.0, &token_pair.0).await?;
|
||||
if coins.is_empty() {
|
||||
eprintln!("Error: Did not manage to find a coin with enough value to spend");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eprintln!("Initializing swap data for:");
|
||||
eprintln!("Send: {} {} tokens", encode_base10(value_pair.0, 8), token_pair.0);
|
||||
eprintln!("Recv: {} {} tokens", encode_base10(value_pair.1, 8), token_pair.1);
|
||||
|
||||
// Fetch our default address
|
||||
let our_address = rpc.wallet_address().await?;
|
||||
let our_publickey = match PublicKey::try_from(our_address) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error converting our address into PublicKey: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// Build proving keys
|
||||
let pb = progress_bar("Building proving key for the mint contract");
|
||||
let mint_pk = ProvingKey::build(8, &MintContract::default());
|
||||
pb.finish();
|
||||
|
||||
let pb = progress_bar("Building proving key for the burn contract");
|
||||
let burn_pk = ProvingKey::build(11, &BurnContract::default());
|
||||
pb.finish();
|
||||
|
||||
// The coin we want to receive.
|
||||
let recv_value_blind = DrkValueBlind::random(&mut OsRng);
|
||||
let recv_token_blind = DrkValueBlind::random(&mut OsRng);
|
||||
let recv_coin_blind = DrkCoinBlind::random(&mut OsRng);
|
||||
let recv_serial = DrkSerial::random(&mut OsRng);
|
||||
|
||||
let pb = progress_bar("Building mint proof for receiving coin");
|
||||
let (mint_proof, mint_revealed) = create_mint_proof(
|
||||
&mint_pk,
|
||||
vp.1,
|
||||
tp.1,
|
||||
recv_value_blind,
|
||||
recv_token_blind,
|
||||
recv_serial,
|
||||
recv_coin_blind,
|
||||
our_publickey,
|
||||
)?;
|
||||
pb.finish();
|
||||
|
||||
// The coin we are spending.
|
||||
// We'll spend the first one we've found.
|
||||
let coin = coins[0];
|
||||
|
||||
let pb = progress_bar("Building burn proof for spending coin");
|
||||
let signature_secret = SecretKey::random(&mut OsRng);
|
||||
let merkle_path = match rpc.get_merkle_path(usize::from(coin.leaf_position)).await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to get merkle path for our coin from darkfid RPC: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let (burn_proof, burn_revealed) = create_burn_proof(
|
||||
&burn_pk,
|
||||
vp.0,
|
||||
tp.0,
|
||||
coin.note.value_blind,
|
||||
coin.note.token_blind,
|
||||
coin.note.serial,
|
||||
coin.note.coin_blind,
|
||||
coin.secret,
|
||||
coin.leaf_position,
|
||||
merkle_path,
|
||||
signature_secret,
|
||||
)?;
|
||||
pb.finish();
|
||||
|
||||
// Pack proofs together with pedersen commitment openings so
|
||||
// counterparty can verify correctness.
|
||||
let swap_data = SwapData {
|
||||
mint_proof,
|
||||
mint_revealed,
|
||||
mint_value: vp.1,
|
||||
mint_token: tp.1,
|
||||
mint_value_blind: recv_value_blind,
|
||||
mint_token_blind: recv_token_blind,
|
||||
burn_proof,
|
||||
burn_value: vp.0,
|
||||
burn_token: tp.0,
|
||||
burn_revealed,
|
||||
burn_value_blind: coin.note.value_blind,
|
||||
burn_token_blind: coin.note.token_blind,
|
||||
};
|
||||
|
||||
// Print encoded data.
|
||||
println!("{}", bs58::encode(serialize(&swap_data)).into_string());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inspect(data: &str) -> Result<()> {
|
||||
let mut mint_valid = false;
|
||||
let mut burn_valid = false;
|
||||
let mut mint_value_valid = false;
|
||||
let mut mint_token_valid = false;
|
||||
let mut burn_value_valid = false;
|
||||
let mut burn_token_valid = false;
|
||||
|
||||
let bytes = match bs58::decode(data).into_vec() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error decoding base58 data from input: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let sd: SwapData = match deserialize(&bytes) {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!("Error: Failed to deserialize swap data into struct: {}", e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
eprintln!("Successfully decoded data into SwapData struct");
|
||||
|
||||
// Build verifying keys
|
||||
let pb = progress_bar("Building verifying key for the mint contract");
|
||||
let mint_vk = VerifyingKey::build(8, &MintContract::default());
|
||||
pb.finish();
|
||||
|
||||
let pb = progress_bar("Building verifying key for the burn contract");
|
||||
let burn_vk = VerifyingKey::build(11, &BurnContract::default());
|
||||
pb.finish();
|
||||
|
||||
let pb = progress_bar("Verifying burn proof");
|
||||
if verify_burn_proof(&burn_vk, &sd.burn_proof, &sd.burn_revealed).is_ok() {
|
||||
burn_valid = true;
|
||||
}
|
||||
pb.finish();
|
||||
|
||||
let pb = progress_bar("Verifying mint proof");
|
||||
if verify_mint_proof(&mint_vk, &sd.mint_proof, &sd.mint_revealed).is_ok() {
|
||||
mint_valid = true;
|
||||
}
|
||||
pb.finish();
|
||||
|
||||
eprintln!(" Verifying pedersen commitments");
|
||||
|
||||
if pedersen_commitment_u64(sd.burn_value, sd.burn_value_blind) == sd.burn_revealed.value_commit
|
||||
{
|
||||
burn_value_valid = true;
|
||||
}
|
||||
|
||||
if pedersen_commitment_base(sd.burn_token, sd.burn_token_blind) == sd.burn_revealed.token_commit
|
||||
{
|
||||
burn_token_valid = true;
|
||||
}
|
||||
|
||||
if pedersen_commitment_u64(sd.mint_value, sd.mint_value_blind) == sd.mint_revealed.value_commit
|
||||
{
|
||||
mint_value_valid = true;
|
||||
}
|
||||
|
||||
if pedersen_commitment_base(sd.mint_token, sd.mint_token_blind) == sd.mint_revealed.token_commit
|
||||
{
|
||||
mint_token_valid = true;
|
||||
}
|
||||
|
||||
let mut valid = true;
|
||||
eprintln!("Summary:");
|
||||
|
||||
eprint!(" Burn proof: ");
|
||||
if burn_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprint!(" Burn proof value commitment: ");
|
||||
if burn_value_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprint!(" Burn proof token commitment: ");
|
||||
if burn_token_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprint!(" Mint proof: ");
|
||||
if mint_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprint!(" Mint proof value commitment: ");
|
||||
if mint_value_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprint!(" Mint proof token commitment: ");
|
||||
if mint_token_valid {
|
||||
eprintln!("{}VALID{}", color::Fg(color::Green), color::Fg(color::Reset));
|
||||
} else {
|
||||
eprintln!("{}INVALID{}", color::Fg(color::Red), color::Fg(color::Reset));
|
||||
valid = false;
|
||||
}
|
||||
|
||||
eprintln!("========================================");
|
||||
|
||||
eprintln!(
|
||||
"Mint: {} {}",
|
||||
encode_base10(sd.mint_value, 8),
|
||||
bs58::encode(sd.mint_token.to_repr()).into_string()
|
||||
);
|
||||
eprintln!(
|
||||
"Burn: {} {}",
|
||||
encode_base10(sd.burn_value, 8),
|
||||
bs58::encode(sd.burn_token.to_repr()).into_string()
|
||||
);
|
||||
|
||||
if !valid {
|
||||
eprintln!(
|
||||
"\nThe ZK proofs and commitments inspected are {}NOT VALID{}",
|
||||
color::Fg(color::Red),
|
||||
color::Fg(color::Reset)
|
||||
);
|
||||
exit(1);
|
||||
} else {
|
||||
eprintln!(
|
||||
"\nThe ZK proofs and commitments inspected are {}VALID{}",
|
||||
color::Fg(color::Green),
|
||||
color::Fg(color::Reset)
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(SerialEncodable, SerialDecodable)]
|
||||
struct SwapData {
|
||||
mint_proof: Proof,
|
||||
mint_revealed: MintRevealedValues,
|
||||
mint_value: u64,
|
||||
mint_token: DrkTokenId,
|
||||
mint_value_blind: DrkValueBlind,
|
||||
mint_token_blind: DrkValueBlind,
|
||||
burn_proof: Proof,
|
||||
burn_revealed: BurnRevealedValues,
|
||||
burn_value: u64,
|
||||
burn_token: DrkTokenId,
|
||||
burn_value_blind: DrkValueBlind,
|
||||
burn_token_blind: DrkValueBlind,
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
match args.command {
|
||||
Subcmd::Init { token_pair, value_pair } => {
|
||||
let token_pair = parse_token_pair(&token_pair)?;
|
||||
let value_pair = parse_value_pair(&value_pair)?;
|
||||
init_swap(args.endpoint, token_pair, value_pair).await
|
||||
}
|
||||
Subcmd::Inspect => {
|
||||
let mut buf = String::new();
|
||||
stdin().read_to_string(&mut buf)?;
|
||||
inspect(&buf.trim())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
// Example transaction flow
|
||||
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
|
||||
use pasta_curves::{group::ff::Field, pallas};
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use darkfi::{
|
||||
@@ -10,7 +11,6 @@ use darkfi::{
|
||||
note::{EncryptedNote, Note},
|
||||
nullifier::Nullifier,
|
||||
proof::{ProvingKey, VerifyingKey},
|
||||
token_id::generate_id,
|
||||
OwnCoin, OwnCoins,
|
||||
},
|
||||
node::state::{state_transition, ProgramState, StateUpdate},
|
||||
@@ -18,7 +18,6 @@ use darkfi::{
|
||||
TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
|
||||
TransactionBuilderOutputInfo,
|
||||
},
|
||||
util::NetworkName,
|
||||
zk::circuit::{BurnContract, MintContract},
|
||||
Result,
|
||||
};
|
||||
@@ -129,7 +128,7 @@ fn main() -> Result<()> {
|
||||
|
||||
let keypair = Keypair::random(&mut OsRng);
|
||||
|
||||
let mint_vk = VerifyingKey::build(8, &MintContract::default());
|
||||
let mint_vk = VerifyingKey::build(11, &MintContract::default());
|
||||
let burn_vk = VerifyingKey::build(11, &BurnContract::default());
|
||||
|
||||
let mut state = MemoryState {
|
||||
@@ -144,8 +143,7 @@ fn main() -> Result<()> {
|
||||
secrets: vec![keypair.secret],
|
||||
};
|
||||
|
||||
let token_id =
|
||||
generate_id(&NetworkName::Solana, "So11111111111111111111111111111111111111112")?;
|
||||
let token_id = pallas::Base::random(&mut OsRng);
|
||||
|
||||
let builder = TransactionBuilder {
|
||||
clear_inputs: vec![TransactionBuilderClearInputInfo {
|
||||
@@ -161,7 +159,7 @@ fn main() -> Result<()> {
|
||||
}],
|
||||
};
|
||||
|
||||
let mint_pk = ProvingKey::build(8, &MintContract::default());
|
||||
let mint_pk = ProvingKey::build(11, &MintContract::default());
|
||||
let burn_pk = ProvingKey::build(11, &BurnContract::default());
|
||||
let tx = builder.build(&mint_pk, &burn_pk)?;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ circuit "Burn" {
|
||||
constrain_instance(value_commit_y);
|
||||
|
||||
# Pedersen commitment for coin's token ID
|
||||
tcv = ec_mul_short(token, VALUE_COMMIT_VALUE);
|
||||
tcv = ec_mul_base(token, NULLIFIER_K);
|
||||
tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
|
||||
token_commit = ec_add(tcv, tcr);
|
||||
# Since token_commit is also a curve point, we'll do the same
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
constant "Mint" {
|
||||
EcFixedPointShort VALUE_COMMIT_VALUE,
|
||||
EcFixedPoint VALUE_COMMIT_RANDOM,
|
||||
EcFixedPointBase NULLIFIER_K,
|
||||
}
|
||||
|
||||
contract "Mint" {
|
||||
@@ -31,7 +32,7 @@ circuit "Mint" {
|
||||
constrain_instance(value_commit_y);
|
||||
|
||||
# Pedersen commitment for coin's token ID
|
||||
tcv = ec_mul_short(token, VALUE_COMMIT_VALUE);
|
||||
tcv = ec_mul_base(token, NULLIFIER_K);
|
||||
tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
|
||||
token_commit = ec_add(tcv, tcr);
|
||||
# Since token_commit is also a curve point, we'll do the same
|
||||
|
||||
@@ -10,7 +10,7 @@ use rand::rngs::OsRng;
|
||||
use super::{
|
||||
nullifier::Nullifier,
|
||||
proof::{Proof, ProvingKey, VerifyingKey},
|
||||
util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
};
|
||||
use crate::{
|
||||
crypto::{
|
||||
@@ -76,7 +76,7 @@ impl BurnRevealedValues {
|
||||
};
|
||||
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
|
||||
BurnRevealedValues {
|
||||
value_commit,
|
||||
|
||||
@@ -263,7 +263,7 @@ impl<'de> serde::Deserialize<'de> for PublicKey {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
crypto::util::pedersen_commitment_scalar,
|
||||
crypto::util::pedersen_commitment_base,
|
||||
util::serial::{deserialize, serialize},
|
||||
};
|
||||
|
||||
@@ -291,15 +291,15 @@ mod tests {
|
||||
);
|
||||
assert_eq!(deserialize(&serialized).ok(), Some(fourtwenty));
|
||||
|
||||
let a = pallas::Scalar::from(420);
|
||||
let a = pallas::Base::from(420);
|
||||
let b = pallas::Scalar::from(69);
|
||||
let pc: pallas::Point = pedersen_commitment_scalar(a, b);
|
||||
let pc: pallas::Point = pedersen_commitment_base(a, b);
|
||||
let serialized = serialize(&pc);
|
||||
assert_eq!(
|
||||
serialized,
|
||||
vec![
|
||||
55, 48, 126, 42, 114, 27, 18, 55, 155, 141, 83, 75, 44, 50, 244, 223, 254, 216, 22,
|
||||
167, 208, 59, 212, 201, 150, 149, 96, 207, 216, 74, 60, 131
|
||||
57, 232, 32, 239, 229, 119, 41, 70, 218, 174, 237, 25, 122, 81, 81, 252, 54, 192,
|
||||
225, 207, 145, 124, 177, 46, 28, 37, 55, 70, 6, 33, 51, 42,
|
||||
]
|
||||
);
|
||||
assert_eq!(deserialize(&serialized).ok(), Some(pc));
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
keypair::PublicKey,
|
||||
proof::{Proof, ProvingKey, VerifyingKey},
|
||||
types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValue, DrkValueBlind, DrkValueCommit},
|
||||
util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
},
|
||||
util::serial::{SerialDecodable, SerialEncodable},
|
||||
zk::circuit::mint_contract::MintContract,
|
||||
@@ -37,7 +37,7 @@ impl MintRevealedValues {
|
||||
public_key: PublicKey,
|
||||
) -> Self {
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
|
||||
let coords = public_key.0.to_affine().coordinates().unwrap();
|
||||
let messages =
|
||||
|
||||
@@ -119,7 +119,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_proof_serialization() -> Result<()> {
|
||||
let value = 110_u64;
|
||||
let token_id = DrkTokenId::from(42);
|
||||
let token_id = DrkTokenId::random(&mut OsRng);
|
||||
let value_blind = DrkValueBlind::random(&mut OsRng);
|
||||
let token_blind = DrkValueBlind::random(&mut OsRng);
|
||||
let serial = DrkSerial::random(&mut OsRng);
|
||||
|
||||
@@ -34,8 +34,7 @@ pub trait SchnorrPublic {
|
||||
impl SchnorrSecret for SecretKey {
|
||||
fn sign(&self, message: &[u8]) -> Signature {
|
||||
let mask = pallas::Scalar::random(&mut OsRng);
|
||||
let nfk = NullifierK;
|
||||
let commit = nfk.generator() * mask;
|
||||
let commit = NullifierK.generator() * mask;
|
||||
|
||||
let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &commit.to_bytes(), message);
|
||||
let response = mask + challenge * mod_r_p(self.0);
|
||||
@@ -47,8 +46,7 @@ impl SchnorrSecret for SecretKey {
|
||||
impl SchnorrPublic for PublicKey {
|
||||
fn verify(&self, message: &[u8], signature: &Signature) -> bool {
|
||||
let challenge = hash_to_scalar(DRK_SCHNORR_DOMAIN, &signature.commit.to_bytes(), message);
|
||||
let nfk = NullifierK;
|
||||
nfk.generator() * signature.response - self.0 * challenge == signature.commit
|
||||
NullifierK.generator() * signature.response - self.0 * challenge == signature.commit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
use blake2b_simd::Params;
|
||||
use halo2_gadgets::ecc::chip::FixedPoint;
|
||||
use pasta_curves::{
|
||||
arithmetic::{CurveExt, FieldExt},
|
||||
group::ff::PrimeField,
|
||||
pallas,
|
||||
};
|
||||
|
||||
use super::constants::fixed_bases::{
|
||||
VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_R_BYTES, VALUE_COMMITMENT_V_BYTES,
|
||||
use super::{
|
||||
constants::{
|
||||
fixed_bases::{
|
||||
VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_R_BYTES, VALUE_COMMITMENT_V_BYTES,
|
||||
},
|
||||
util::gen_const_array,
|
||||
NullifierK,
|
||||
},
|
||||
types::*,
|
||||
};
|
||||
use crate::crypto::{constants::util::gen_const_array, types::*};
|
||||
|
||||
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();
|
||||
@@ -18,18 +25,24 @@ pub fn hash_to_scalar(persona: &[u8], a: &[u8], b: &[u8]) -> pallas::Scalar {
|
||||
pallas::Scalar::from_bytes_wide(ret.as_array())
|
||||
}
|
||||
|
||||
|
||||
/// Pedersen commitment for a full-width base field element.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn pedersen_commitment_scalar(value: pallas::Scalar, blind: DrkValueBlind) -> DrkValueCommit {
|
||||
pub fn pedersen_commitment_base(value: pallas::Base, blind: DrkValueBlind) -> DrkValueCommit {
|
||||
let hasher = DrkValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
|
||||
let V = NullifierK.generator();
|
||||
let R = hasher(&VALUE_COMMITMENT_R_BYTES);
|
||||
|
||||
V * mod_r_p(value) + R * blind
|
||||
}
|
||||
|
||||
/// Pedersen commitment for a 64-bit value, in the base field.
|
||||
#[allow(non_snake_case)]
|
||||
pub fn pedersen_commitment_u64(value: u64, blind: DrkValueBlind) -> DrkValueCommit {
|
||||
let hasher = DrkValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
|
||||
let V = hasher(&VALUE_COMMITMENT_V_BYTES);
|
||||
let R = hasher(&VALUE_COMMITMENT_R_BYTES);
|
||||
|
||||
V * value + R * blind
|
||||
}
|
||||
|
||||
pub fn pedersen_commitment_u64(value: u64, blind: DrkValueBlind) -> DrkValueCommit {
|
||||
pedersen_commitment_scalar(mod_r_p(DrkValue::from(value)), blind)
|
||||
V * mod_r_p(DrkValue::from(value)) + R * blind
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
|
||||
@@ -19,7 +19,7 @@ use crate::{
|
||||
schnorr,
|
||||
schnorr::SchnorrPublic,
|
||||
types::{DrkTokenId, DrkValueBlind, DrkValueCommit},
|
||||
util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
BurnRevealedValues, MintRevealedValues, Proof,
|
||||
},
|
||||
impl_vec,
|
||||
@@ -169,8 +169,7 @@ impl Transaction {
|
||||
|
||||
failed = failed ||
|
||||
self.clear_inputs.iter().any(|input| {
|
||||
pedersen_commitment_scalar(mod_r_p(input.token_id), input.token_blind) !=
|
||||
token_commit_value
|
||||
pedersen_commitment_base(input.token_id, input.token_blind) != token_commit_value
|
||||
});
|
||||
!failed
|
||||
}
|
||||
|
||||
@@ -369,8 +369,7 @@ impl Circuit<pallas::Base> for BurnContract {
|
||||
|
||||
// v * G_1
|
||||
let (commitment, _) = {
|
||||
let value_commit_v = ValueCommitV;
|
||||
let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v);
|
||||
let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), ValueCommitV);
|
||||
let value = ScalarFixedShort::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "value"),
|
||||
@@ -386,8 +385,8 @@ impl Circuit<pallas::Base> for BurnContract {
|
||||
layouter.namespace(|| "value_blind"),
|
||||
self.value_blind,
|
||||
)?;
|
||||
let value_commit_r = OrchardFixedBasesFull::ValueCommitR;
|
||||
let value_commit_r = FixedPoint::from_inner(ecc_chip.clone(), value_commit_r);
|
||||
let value_commit_r =
|
||||
FixedPoint::from_inner(ecc_chip.clone(), OrchardFixedBasesFull::ValueCommitR);
|
||||
value_commit_r.mul(layouter.namespace(|| "[value_blind] ValueCommitR"), rcv)?
|
||||
};
|
||||
|
||||
@@ -412,15 +411,9 @@ impl Circuit<pallas::Base> for BurnContract {
|
||||
assign_free_advice(layouter.namespace(|| "load token"), config.advices[0], self.token)?;
|
||||
|
||||
// a * G_1
|
||||
let (commitment, _) = {
|
||||
let token_commit_v = ValueCommitV;
|
||||
let token_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), token_commit_v);
|
||||
let token = ScalarFixedShort::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "token"),
|
||||
(token, one),
|
||||
)?;
|
||||
token_commit_v.mul(layouter.namespace(|| "[token] ValueCommitV"), token)?
|
||||
let commitment = {
|
||||
let token_commit_v = FixedPointBaseField::from_inner(ecc_chip.clone(), NullifierK);
|
||||
token_commit_v.mul(layouter.namespace(|| "[token] NullifierK"), token)?
|
||||
};
|
||||
|
||||
// r_A * G_2
|
||||
@@ -430,8 +423,8 @@ impl Circuit<pallas::Base> for BurnContract {
|
||||
layouter.namespace(|| "token_blind"),
|
||||
self.token_blind,
|
||||
)?;
|
||||
let token_commit_r = OrchardFixedBasesFull::ValueCommitR;
|
||||
let token_commit_r = FixedPoint::from_inner(ecc_chip.clone(), token_commit_r);
|
||||
let token_commit_r =
|
||||
FixedPoint::from_inner(ecc_chip.clone(), OrchardFixedBasesFull::ValueCommitR);
|
||||
token_commit_r.mul(layouter.namespace(|| "[token_blind] ValueCommitR"), rca)?
|
||||
};
|
||||
|
||||
@@ -488,7 +481,7 @@ mod tests {
|
||||
crypto::{
|
||||
keypair::{PublicKey, SecretKey},
|
||||
proof::{ProvingKey, VerifyingKey},
|
||||
util::{mod_r_p, pedersen_commitment_scalar},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
Proof,
|
||||
},
|
||||
Result,
|
||||
@@ -506,8 +499,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn burn_circuit_assert() -> Result<()> {
|
||||
let value = pallas::Base::from(42);
|
||||
let token_id = pallas::Base::from(22);
|
||||
let value = 42;
|
||||
let token_id = pallas::Base::random(&mut OsRng);
|
||||
let value_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let token_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let serial = pallas::Base::random(&mut OsRng);
|
||||
@@ -517,7 +510,8 @@ mod tests {
|
||||
|
||||
let coin2 = {
|
||||
let coords = PublicKey::from_secret(secret).0.to_affine().coordinates().unwrap();
|
||||
let msg = [*coords.x(), *coords.y(), value, token_id, serial, coin_blind];
|
||||
let msg =
|
||||
[*coords.x(), *coords.y(), pallas::Base::from(value), token_id, serial, coin_blind];
|
||||
poseidon::Hash::<_, P128Pow5T3, ConstantLength<6>, 3, 2>::init().hash(msg)
|
||||
};
|
||||
|
||||
@@ -542,10 +536,10 @@ mod tests {
|
||||
let nullifier =
|
||||
poseidon::Hash::<_, P128Pow5T3, ConstantLength<2>, 3, 2>::init().hash(nullifier);
|
||||
|
||||
let value_commit = pedersen_commitment_scalar(mod_r_p(value), value_blind);
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let value_coords = value_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
let token_coords = token_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let sig_pubkey = PublicKey::from_secret(sig_secret);
|
||||
@@ -565,7 +559,7 @@ mod tests {
|
||||
let circuit = BurnContract {
|
||||
secret_key: Value::known(secret.0),
|
||||
serial: Value::known(serial),
|
||||
value: Value::known(value),
|
||||
value: Value::known(pallas::Base::from(value)),
|
||||
token: Value::known(token_id),
|
||||
coin_blind: Value::known(coin_blind),
|
||||
value_blind: Value::known(value_blind),
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
use halo2_gadgets::{
|
||||
ecc::{
|
||||
chip::{EccChip, EccConfig},
|
||||
FixedPoint, FixedPointShort, ScalarFixed, ScalarFixedShort,
|
||||
FixedPoint, FixedPointBaseField, FixedPointShort, ScalarFixed, ScalarFixedShort,
|
||||
},
|
||||
poseidon::{
|
||||
primitives as poseidon, Hash as PoseidonHash, Pow5Chip as PoseidonChip,
|
||||
Pow5Config as PoseidonConfig,
|
||||
},
|
||||
sinsemilla::chip::{SinsemillaChip, SinsemillaConfig},
|
||||
utilities::lookup_range_check::LookupRangeCheckConfig,
|
||||
};
|
||||
use halo2_proofs::{
|
||||
circuit::{floor_planner, AssignedCell, Layouter, Value},
|
||||
pasta::{pallas, Fp},
|
||||
plonk,
|
||||
plonk::{Advice, Circuit, Column, ConstraintSystem, Instance as InstanceColumn},
|
||||
};
|
||||
use pasta_curves::{pallas, Fp};
|
||||
|
||||
use crate::{
|
||||
crypto::constants::{OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV},
|
||||
crypto::constants::{
|
||||
sinsemilla::{OrchardCommitDomains, OrchardHashDomains},
|
||||
NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV,
|
||||
},
|
||||
zk::assign_free_advice,
|
||||
};
|
||||
|
||||
@@ -27,6 +31,8 @@ pub struct MintConfig {
|
||||
advices: [Column<Advice>; 10],
|
||||
ecc_config: EccConfig<OrchardFixedBases>,
|
||||
poseidon_config: PoseidonConfig<pallas::Base, 3, 2>,
|
||||
sinsemilla_config:
|
||||
SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
|
||||
}
|
||||
|
||||
impl MintConfig {
|
||||
@@ -89,7 +95,9 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
meta.advice_column(),
|
||||
];
|
||||
|
||||
// Fixed columns for the Sinsemilla generator lookup table
|
||||
let table_idx = meta.lookup_table_column();
|
||||
let lookup = (table_idx, meta.lookup_table_column(), meta.lookup_table_column());
|
||||
|
||||
// Instance column used for public inputs
|
||||
let primary = meta.instance_column();
|
||||
@@ -147,7 +155,16 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
rc_b,
|
||||
);
|
||||
|
||||
MintConfig { primary, advices, ecc_config, poseidon_config }
|
||||
let sinsemilla_config = SinsemillaChip::configure(
|
||||
meta,
|
||||
advices[..5].try_into().unwrap(),
|
||||
advices[6],
|
||||
ecc_lagrange_coeffs[0],
|
||||
lookup,
|
||||
range_check,
|
||||
);
|
||||
|
||||
MintConfig { primary, advices, ecc_config, poseidon_config, sinsemilla_config }
|
||||
}
|
||||
|
||||
fn synthesize(
|
||||
@@ -155,6 +172,9 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
config: Self::Config,
|
||||
mut layouter: impl Layouter<pallas::Base>,
|
||||
) -> Result<(), plonk::Error> {
|
||||
// Load the Sinsemilla generator lookup table used by the whole circuit.
|
||||
SinsemillaChip::load(config.sinsemilla_config.clone(), &mut layouter)?;
|
||||
|
||||
let ecc_chip = config.ecc_chip();
|
||||
|
||||
let pub_x = assign_free_advice(
|
||||
@@ -227,8 +247,7 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
|
||||
// v * G_1
|
||||
let (commitment, _) = {
|
||||
let value_commit_v = ValueCommitV;
|
||||
let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), value_commit_v);
|
||||
let value_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), ValueCommitV);
|
||||
let value = ScalarFixedShort::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "value"),
|
||||
@@ -244,8 +263,8 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
layouter.namespace(|| "value_blind"),
|
||||
self.value_blind,
|
||||
)?;
|
||||
let value_commit_r = OrchardFixedBasesFull::ValueCommitR;
|
||||
let value_commit_r = FixedPoint::from_inner(ecc_chip.clone(), value_commit_r);
|
||||
let value_commit_r =
|
||||
FixedPoint::from_inner(ecc_chip.clone(), OrchardFixedBasesFull::ValueCommitR);
|
||||
value_commit_r.mul(layouter.namespace(|| "[value_blind] ValueCommitR"), rcv)?
|
||||
};
|
||||
|
||||
@@ -268,15 +287,9 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
// Token commitment
|
||||
// ================
|
||||
// a * G_1
|
||||
let (commitment, _) = {
|
||||
let token_commit_v = ValueCommitV;
|
||||
let token_commit_v = FixedPointShort::from_inner(ecc_chip.clone(), token_commit_v);
|
||||
let token = ScalarFixedShort::new(
|
||||
ecc_chip.clone(),
|
||||
layouter.namespace(|| "token"),
|
||||
(token, one),
|
||||
)?;
|
||||
token_commit_v.mul(layouter.namespace(|| "[token] ValueCommitV"), token)?
|
||||
let commitment = {
|
||||
let token_commit_v = FixedPointBaseField::from_inner(ecc_chip.clone(), NullifierK);
|
||||
token_commit_v.mul(layouter.namespace(|| "[token] NullifierK"), token)?
|
||||
};
|
||||
|
||||
// r_A * G_2
|
||||
@@ -286,8 +299,8 @@ impl Circuit<pallas::Base> for MintContract {
|
||||
layouter.namespace(|| "token_blind"),
|
||||
self.token_blind,
|
||||
)?;
|
||||
let token_commit_r = OrchardFixedBasesFull::ValueCommitR;
|
||||
let token_commit_r = FixedPoint::from_inner(ecc_chip, token_commit_r);
|
||||
let token_commit_r =
|
||||
FixedPoint::from_inner(ecc_chip, OrchardFixedBasesFull::ValueCommitR);
|
||||
token_commit_r.mul(layouter.namespace(|| "[token_blind] ValueCommitR"), rca)?
|
||||
};
|
||||
|
||||
@@ -318,12 +331,11 @@ mod tests {
|
||||
crypto::{
|
||||
keypair::PublicKey,
|
||||
proof::{ProvingKey, VerifyingKey},
|
||||
util::{mod_r_p, pedersen_commitment_scalar},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
Proof,
|
||||
},
|
||||
Result,
|
||||
};
|
||||
use group::{ff::Field, Curve};
|
||||
use halo2_gadgets::poseidon::{
|
||||
primitives as poseidon,
|
||||
primitives::{ConstantLength, P128Pow5T3},
|
||||
@@ -332,14 +344,17 @@ mod tests {
|
||||
circuit::Value,
|
||||
dev::{CircuitLayout, MockProver},
|
||||
};
|
||||
use pasta_curves::arithmetic::CurveAffine;
|
||||
use pasta_curves::{
|
||||
arithmetic::CurveAffine,
|
||||
group::{ff::Field, Curve},
|
||||
};
|
||||
use rand::rngs::OsRng;
|
||||
use std::time::Instant;
|
||||
|
||||
#[test]
|
||||
fn mint_circuit_assert() -> Result<()> {
|
||||
let value = pallas::Base::from(42);
|
||||
let token_id = pallas::Base::from(22);
|
||||
let value = 42;
|
||||
let token_id = pallas::Base::random(&mut OsRng);
|
||||
let value_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let token_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let serial = pallas::Base::random(&mut OsRng);
|
||||
@@ -347,13 +362,14 @@ mod tests {
|
||||
let public_key = PublicKey::random(&mut OsRng);
|
||||
let coords = public_key.0.to_affine().coordinates().unwrap();
|
||||
|
||||
let msg = [*coords.x(), *coords.y(), value, token_id, serial, coin_blind];
|
||||
let msg =
|
||||
[*coords.x(), *coords.y(), pallas::Base::from(value), token_id, serial, coin_blind];
|
||||
let coin = poseidon::Hash::<_, P128Pow5T3, ConstantLength<6>, 3, 2>::init().hash(msg);
|
||||
|
||||
let value_commit = pedersen_commitment_scalar(mod_r_p(value), value_blind);
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let value_coords = value_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
let token_coords = token_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let public_inputs =
|
||||
@@ -362,7 +378,7 @@ mod tests {
|
||||
let circuit = MintContract {
|
||||
pub_x: Value::known(*coords.x()),
|
||||
pub_y: Value::known(*coords.y()),
|
||||
value: Value::known(value),
|
||||
value: Value::known(pallas::Base::from(value)),
|
||||
token: Value::known(token_id),
|
||||
serial: Value::known(serial),
|
||||
coin_blind: Value::known(coin_blind),
|
||||
@@ -374,13 +390,13 @@ mod tests {
|
||||
let root = BitMapBackend::new("mint_circuit_layout.png", (3840, 2160)).into_drawing_area();
|
||||
root.fill(&WHITE).unwrap();
|
||||
let root = root.titled("Mint Circuit Layout", ("sans-serif", 60)).unwrap();
|
||||
CircuitLayout::default().render(8, &circuit, &root).unwrap();
|
||||
CircuitLayout::default().render(11, &circuit, &root).unwrap();
|
||||
|
||||
let prover = MockProver::run(8, &circuit, vec![public_inputs.clone()])?;
|
||||
let prover = MockProver::run(11, &circuit, vec![public_inputs.clone()])?;
|
||||
prover.assert_satisfied();
|
||||
|
||||
let now = Instant::now();
|
||||
let proving_key = ProvingKey::build(8, &circuit);
|
||||
let proving_key = ProvingKey::build(11, &circuit);
|
||||
println!("ProvingKey built [{:?}]", now.elapsed());
|
||||
let now = Instant::now();
|
||||
let proof = Proof::create(&proving_key, &[circuit], &public_inputs, &mut OsRng)?;
|
||||
@@ -388,7 +404,7 @@ mod tests {
|
||||
|
||||
let circuit = MintContract::default();
|
||||
let now = Instant::now();
|
||||
let verifying_key = VerifyingKey::build(8, &circuit);
|
||||
let verifying_key = VerifyingKey::build(11, &circuit);
|
||||
println!("VerifyingKey built [{:?}]", now.elapsed());
|
||||
let now = Instant::now();
|
||||
proof.verify(&verifying_key, &public_inputs)?;
|
||||
|
||||
@@ -15,7 +15,8 @@ use halo2_proofs::{
|
||||
plonk::{Advice, Assigned, Column},
|
||||
};
|
||||
|
||||
pub(in crate::zk) fn assign_free_advice<F: Field, V: Copy>(
|
||||
//pub(in crate::zk) fn assign_free_advice<F: Field, V: Copy>(
|
||||
pub fn assign_free_advice<F: Field, V: Copy>(
|
||||
mut layouter: impl Layouter<F>,
|
||||
column: Column<Advice>,
|
||||
value: Value<V>,
|
||||
|
||||
@@ -3,7 +3,7 @@ use darkfi::{
|
||||
keypair::{PublicKey, SecretKey},
|
||||
merkle_node::MerkleNode,
|
||||
proof::{ProvingKey, VerifyingKey},
|
||||
util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
Proof,
|
||||
},
|
||||
zk::{
|
||||
@@ -35,7 +35,7 @@ fn burn_proof() -> Result<()> {
|
||||
|
||||
// Witness values
|
||||
let value = 42;
|
||||
let token_id = pallas::Base::from(22);
|
||||
let token_id = pallas::Base::random(&mut OsRng);
|
||||
let value_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let token_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let serial = pallas::Base::random(&mut OsRng);
|
||||
@@ -94,7 +94,7 @@ fn burn_proof() -> Result<()> {
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let value_coords = value_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
let token_coords = token_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let sig_pubkey = PublicKey::from_secret(sig_secret);
|
||||
|
||||
@@ -2,7 +2,7 @@ use darkfi::{
|
||||
crypto::{
|
||||
keypair::PublicKey,
|
||||
proof::{ProvingKey, VerifyingKey},
|
||||
util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
|
||||
util::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
Proof,
|
||||
},
|
||||
zk::{
|
||||
@@ -33,7 +33,7 @@ fn mint_proof() -> Result<()> {
|
||||
|
||||
// Witness values
|
||||
let value = 42;
|
||||
let token_id = pallas::Base::from(22);
|
||||
let token_id = pallas::Base::random(&mut OsRng);
|
||||
let value_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let token_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let serial = pallas::Base::random(&mut OsRng);
|
||||
@@ -60,7 +60,7 @@ fn mint_proof() -> Result<()> {
|
||||
let value_commit = pedersen_commitment_u64(value, value_blind);
|
||||
let value_coords = value_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
|
||||
let token_commit = pedersen_commitment_base(token_id, token_blind);
|
||||
let token_coords = token_commit.to_affine().coordinates().unwrap();
|
||||
|
||||
let public_inputs =
|
||||
|
||||
Reference in New Issue
Block a user