mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
working signatures for clear inputs (deposits)
This commit is contained in:
@@ -4,6 +4,7 @@ use ff::{Field, PrimeField};
|
||||
use group::Group;
|
||||
use rand::rngs::OsRng;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
use sapvi::crypto::{
|
||||
coin::Coin,
|
||||
@@ -17,23 +18,33 @@ use sapvi::error::{Error, Result};
|
||||
use sapvi::serial::{Decodable, Encodable, VarInt};
|
||||
use sapvi::tx;
|
||||
|
||||
fn txbuilding() {
|
||||
//{
|
||||
// let params = setup_mint_prover();
|
||||
// save_params("mint.params", ¶ms);
|
||||
//}
|
||||
//{
|
||||
// let params = setup_spend_prover();
|
||||
// save_params("spend.params", ¶ms);
|
||||
//}
|
||||
fn main() {
|
||||
// Auto create trusted ceremony parameters if they don't exist
|
||||
if !Path::new("mint.params").exists() {
|
||||
let params = setup_mint_prover();
|
||||
save_params("mint.params", ¶ms);
|
||||
}
|
||||
if !Path::new("spend.params").exists() {
|
||||
let params = setup_spend_prover();
|
||||
save_params("spend.params", ¶ms);
|
||||
}
|
||||
|
||||
// Load trusted setup parameters
|
||||
let (mint_params, mint_pvk) = load_params("mint.params").expect("params should load");
|
||||
let (spend_params, spend_pvk) = load_params("spend.params").expect("params should load");
|
||||
|
||||
// Cashier creates a secret key
|
||||
let cashier_secret = jubjub::Fr::random(&mut OsRng);
|
||||
// This is their public key
|
||||
let cashier_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * cashier_secret;
|
||||
|
||||
// Wallet 1 creates a secret key
|
||||
let secret = jubjub::Fr::random(&mut OsRng);
|
||||
// This is their public key
|
||||
let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
|
||||
|
||||
let builder = tx::TransactionBuilder {
|
||||
clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110 }],
|
||||
clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110, signature_secret: cashier_secret }],
|
||||
inputs: vec![],
|
||||
outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
|
||||
};
|
||||
@@ -106,22 +117,5 @@ fn txbuilding() {
|
||||
let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
|
||||
assert!(tx.verify(&mint_pvk, &spend_pvk));
|
||||
}
|
||||
|
||||
/*let note = Note {
|
||||
serial: jubjub::Fr::random(&mut OsRng),
|
||||
value: 110,
|
||||
coin_blind: jubjub::Fr::random(&mut OsRng),
|
||||
valcom_blind: jubjub::Fr::random(&mut OsRng),
|
||||
};
|
||||
|
||||
let secret = jubjub::Fr::random(&mut OsRng);
|
||||
let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
|
||||
|
||||
let encrypted_note = note.encrypt(&public).unwrap();
|
||||
let note2 = encrypted_note.decrypt(&secret).unwrap();
|
||||
assert_eq!(note.value, note2.value);*/
|
||||
}
|
||||
|
||||
fn main() {
|
||||
txbuilding();
|
||||
}
|
||||
|
||||
115
src/tx.rs
115
src/tx.rs
@@ -26,7 +26,7 @@ pub struct TransactionBuilder {
|
||||
|
||||
impl TransactionBuilder {
|
||||
fn compute_remainder_blind(
|
||||
clear_inputs: &Vec<TransactionClearInput>,
|
||||
clear_inputs: &Vec<PartialTransactionClearInput>,
|
||||
input_blinds: &Vec<jubjub::Fr>,
|
||||
output_blinds: &Vec<jubjub::Fr>,
|
||||
) -> jubjub::Fr {
|
||||
@@ -54,10 +54,14 @@ impl TransactionBuilder {
|
||||
) -> Transaction {
|
||||
let mut clear_inputs = vec![];
|
||||
for input in &self.clear_inputs {
|
||||
let signature_public =
|
||||
zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
|
||||
|
||||
let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let clear_input = TransactionClearInput {
|
||||
let clear_input = PartialTransactionClearInput {
|
||||
value: input.value,
|
||||
valcom_blind,
|
||||
signature_public
|
||||
};
|
||||
clear_inputs.push(clear_input);
|
||||
}
|
||||
@@ -69,8 +73,6 @@ impl TransactionBuilder {
|
||||
input_blinds.push(input.note.valcom_blind.clone());
|
||||
|
||||
let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let signature_public =
|
||||
zcash_primitives::constants::SPENDING_KEY_GENERATOR * signature_secret;
|
||||
|
||||
// make proof
|
||||
|
||||
@@ -148,6 +150,14 @@ impl TransactionBuilder {
|
||||
.encode(&mut unsigned_tx_data)
|
||||
.expect("TODO handle this");
|
||||
|
||||
let mut clear_inputs = vec![];
|
||||
for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
|
||||
let secret = schnorr::SecretKey(info.signature_secret.clone());
|
||||
let signature = secret.sign(&unsigned_tx_data[..]);
|
||||
let input = TransactionClearInput::from_partial(input, signature);
|
||||
clear_inputs.push(input);
|
||||
}
|
||||
|
||||
let mut inputs = vec![];
|
||||
for (input, signature_secret) in partial_tx
|
||||
.inputs
|
||||
@@ -160,7 +170,7 @@ impl TransactionBuilder {
|
||||
}
|
||||
|
||||
Transaction {
|
||||
clear_inputs: partial_tx.clear_inputs,
|
||||
clear_inputs,
|
||||
inputs,
|
||||
outputs: partial_tx.outputs,
|
||||
}
|
||||
@@ -169,6 +179,7 @@ impl TransactionBuilder {
|
||||
|
||||
pub struct TransactionBuilderClearInputInfo {
|
||||
pub value: u64,
|
||||
pub signature_secret: jubjub::Fr,
|
||||
}
|
||||
|
||||
pub struct TransactionBuilderInputInfo {
|
||||
@@ -185,7 +196,7 @@ pub struct TransactionBuilderOutputInfo {
|
||||
}
|
||||
|
||||
pub struct PartialTransaction {
|
||||
pub clear_inputs: Vec<TransactionClearInput>,
|
||||
pub clear_inputs: Vec<PartialTransactionClearInput>,
|
||||
pub inputs: Vec<PartialTransactionInput>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
}
|
||||
@@ -239,7 +250,7 @@ impl Decodable for Transaction {
|
||||
impl Transaction {
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.clear_inputs.encode(&mut s)?;
|
||||
len += self.clear_inputs.encode_without_signature(&mut s)?;
|
||||
len += self.inputs.encode_without_signature(&mut s)?;
|
||||
len += self.outputs.encode(s)?;
|
||||
Ok(len)
|
||||
@@ -280,6 +291,12 @@ impl Transaction {
|
||||
self
|
||||
.encode_without_signature(&mut unsigned_tx_data)
|
||||
.expect("TODO handle this");
|
||||
for input in &self.clear_inputs {
|
||||
let public = schnorr::PublicKey(input.signature_public.clone());
|
||||
if !public.verify(&unsigned_tx_data[..], &input.signature) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for input in &self.inputs {
|
||||
let public = schnorr::PublicKey(input.revealed.signature_public.clone());
|
||||
if !public.verify(&unsigned_tx_data[..], &input.signature) {
|
||||
@@ -294,8 +311,47 @@ impl Transaction {
|
||||
pub struct TransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
pub signature: schnorr::Signature,
|
||||
}
|
||||
|
||||
impl TransactionClearInput {
|
||||
fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
|
||||
Self {
|
||||
value: partial.value,
|
||||
valcom_blind: partial.valcom_blind,
|
||||
signature_public: partial.signature_public,
|
||||
signature
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.signature_public.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_vec_without_signature {
|
||||
($type: ty) => {
|
||||
impl EncodableWithoutSignature for Vec<$type> {
|
||||
#[inline]
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += VarInt(self.len() as u64).encode(&mut s)?;
|
||||
for c in self.iter() {
|
||||
len += c.encode_without_signature(&mut s)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_vec_without_signature!(TransactionClearInput);
|
||||
|
||||
impl_vec!(TransactionClearInput);
|
||||
|
||||
impl Encodable for TransactionClearInput {
|
||||
@@ -303,6 +359,8 @@ impl Encodable for TransactionClearInput {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.signature_public.encode(&mut s)?;
|
||||
len += self.signature.encode(s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
@@ -311,7 +369,37 @@ impl Decodable for TransactionClearInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
value: Decodable::decode(&mut d)?,
|
||||
valcom_blind: Decodable::decode(d)?,
|
||||
valcom_blind: Decodable::decode(&mut d)?,
|
||||
signature_public: Decodable::decode(&mut d)?,
|
||||
signature: Decodable::decode(d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PartialTransactionClearInput {
|
||||
pub value: u64,
|
||||
pub valcom_blind: jubjub::Fr,
|
||||
pub signature_public: jubjub::SubgroupPoint,
|
||||
}
|
||||
|
||||
impl_vec!(PartialTransactionClearInput);
|
||||
|
||||
impl Encodable for PartialTransactionClearInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.value.encode(&mut s)?;
|
||||
len += self.valcom_blind.encode(&mut s)?;
|
||||
len += self.signature_public.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for PartialTransactionClearInput {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self {
|
||||
value: Decodable::decode(&mut d)?,
|
||||
valcom_blind: Decodable::decode(&mut d)?,
|
||||
signature_public: Decodable::decode(&mut d)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -368,16 +456,7 @@ trait EncodableWithoutSignature {
|
||||
fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
|
||||
}
|
||||
|
||||
impl EncodableWithoutSignature for Vec<TransactionInput> {
|
||||
fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += VarInt(self.len() as u64).encode(&mut s)?;
|
||||
for c in self.iter() {
|
||||
len += c.encode_without_signature(&mut s)?;
|
||||
}
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
impl_vec_without_signature!(TransactionInput);
|
||||
|
||||
impl Encodable for TransactionInput {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
|
||||
Reference in New Issue
Block a user