From f1167440371599dc5d628f2b198f760e504b68dd Mon Sep 17 00:00:00 2001 From: Rahul Patni Date: Thu, 11 Jan 2024 13:49:21 -0800 Subject: [PATCH] Rahul/ifl 2093 add frost signature to unsigned spends and mints (#4532) * adding frost signature assignment * moved sign_frost to unsignedMintDescription * adding frost sign test for mints * function name change * running linter * removing return type from add signature functions * linting * adding description return type * removing extra key in test --- ironfish-rust/src/transaction/mints.rs | 30 ++++++++++++++++- ironfish-rust/src/transaction/spends.rs | 45 ++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/ironfish-rust/src/transaction/mints.rs b/ironfish-rust/src/transaction/mints.rs index 2ee55dc902..1e47d5ac27 100644 --- a/ironfish-rust/src/transaction/mints.rs +++ b/ironfish-rust/src/transaction/mints.rs @@ -149,6 +149,11 @@ impl UnsignedMintDescription { Ok(self.description) } + pub fn add_signature(mut self, signature: Signature) -> MintDescription { + self.description.authorizing_signature = signature; + self.description + } + pub fn read( mut reader: R, version: TransactionVersion, @@ -356,7 +361,7 @@ impl MintDescription { mod test { use ff::Field; use ironfish_zkp::{constants::SPENDING_KEY_GENERATOR, redjubjub}; - use rand::thread_rng; + use rand::{random, thread_rng}; use crate::{ assets::asset::Asset, @@ -670,4 +675,27 @@ mod test { ); assert!(unsigned_mint.is_err()); } + + #[test] + fn test_add_signature() { + let key = SaplingKey::generate_key(); + let public_address = key.public_address(); + + let asset = Asset::new(public_address, "name", "").expect("should be able to create asset"); + let public_key_randomness = jubjub::Fr::random(thread_rng()); + let randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) + .randomize(public_key_randomness, *SPENDING_KEY_GENERATOR); + let value = random(); + let builder = MintBuilder::new(asset, value); + // create a random private key and sign random message as placeholder + let private_key = redjubjub::PrivateKey(jubjub::Fr::random(thread_rng())); + let public_key = redjubjub::PublicKey::from_private(&private_key, *SPENDING_KEY_GENERATOR); + let msg = [0u8; 32]; + let signature = private_key.sign(&msg, &mut thread_rng(), *SPENDING_KEY_GENERATOR); + let unsigned_spend_description = builder + .build(&key, &public_key_randomness, &randomized_public_key) + .expect("should be able to build proof"); + unsigned_spend_description.add_signature(signature); + assert!(public_key.verify(&msg, &signature, *SPENDING_KEY_GENERATOR)) + } } diff --git a/ironfish-rust/src/transaction/spends.rs b/ironfish-rust/src/transaction/spends.rs index 9fbc388899..583858d2e2 100644 --- a/ironfish-rust/src/transaction/spends.rs +++ b/ironfish-rust/src/transaction/spends.rs @@ -194,6 +194,11 @@ impl UnsignedSpendDescription { Ok(self.description) } + pub fn add_signature(mut self, signature: Signature) -> SpendDescription { + self.description.authorizing_signature = signature; + self.description + } + pub fn read(mut reader: R) -> Result { let public_key_randomness = read_scalar(&mut reader)?; let description = SpendDescription::read(&mut reader)?; @@ -409,7 +414,7 @@ mod test { use ff::Field; use group::Curve; use ironfish_zkp::constants::SPENDING_KEY_GENERATOR; - use ironfish_zkp::redjubjub; + use ironfish_zkp::redjubjub::{self, PrivateKey, PublicKey}; use rand::prelude::*; use rand::{thread_rng, Rng}; @@ -579,4 +584,42 @@ mod test { .expect("should be able to serialize proof again"); assert_eq!(serialized_proof, serialized_again); } + + #[test] + fn test_add_signature() { + let key = SaplingKey::generate_key(); + let public_address = key.public_address(); + let sender_key = SaplingKey::generate_key(); + + let note_randomness = random(); + + let note = Note::new( + public_address, + note_randomness, + "", + NATIVE_ASSET, + sender_key.public_address(), + ); + let witness = make_fake_witness(¬e); + let public_key_randomness = jubjub::Fr::random(thread_rng()); + let randomized_public_key = redjubjub::PublicKey(key.view_key.authorizing_key.into()) + .randomize(public_key_randomness, *SPENDING_KEY_GENERATOR); + + let builder = SpendBuilder::new(note, &witness); + // create a random private key and sign random message as placeholder + let private_key = PrivateKey(jubjub::Fr::random(thread_rng())); + let public_key = PublicKey::from_private(&private_key, *SPENDING_KEY_GENERATOR); + let msg = [0u8; 32]; + let signature = private_key.sign(&msg, &mut thread_rng(), *SPENDING_KEY_GENERATOR); + let unsigned_spend_description = builder + .build( + &key.sapling_proof_generation_key(), + key.view_key(), + &public_key_randomness, + &randomized_public_key, + ) + .expect("should be able to build proof"); + unsigned_spend_description.add_signature(signature); + assert!(public_key.verify(&msg, &signature, *SPENDING_KEY_GENERATOR)) + } }