diff --git a/src/issuance.rs b/src/issuance.rs index 3316cfe8..b36c2350 100644 --- a/src/issuance.rs +++ b/src/issuance.rs @@ -2,7 +2,7 @@ use memuse::DynamicUsage; use nonempty::NonEmpty; -use rand::RngCore; +use rand::{CryptoRng, RngCore}; use std::fmt; use crate::keys::IssuerValidatingKey; @@ -28,6 +28,17 @@ impl IssueAction { authorization: Unauthorized, } } + + /// inject the `sighash` for signature into the bundle. + pub fn prepare(self, sighash: [u8; 32]) -> IssueAction { + return IssueAction { + ik: self.ik, + asset_desc: self.asset_desc, + notes: self.notes, + finalize: self.finalize, + authorization: Prepared { sighash }, + }; + } } impl IssueAction { @@ -234,7 +245,6 @@ impl Default for IssueBundle { } impl IssueBundle { - /// Return the actions for a given `IssueBundle`. pub fn actions(&self) -> &Vec> { &self.actions @@ -342,6 +352,22 @@ impl IssueBundle { Ok(()) } + + /// Loads the sighash into this bundle, preparing it for signing. + /// + /// This API ensures that all signatures are created over the same sighash. + /// pub fn prepare( + // self, + // mut rng: R, + pub fn prepare(self, sighash: [u8; 32]) -> IssueBundle { + IssueBundle { + actions: self + .actions + .into_iter() + .map(|a| a.prepare(sighash)) + .collect(), + } + } } /// Errors produced during the issuance process @@ -505,6 +531,39 @@ mod tests { IssueActionAlreadyFinalized ); } + + #[test] + fn issue_bundle_prepare() { + let mut rng = OsRng; + let sk = SpendingKey::random(&mut rng); + let isk: IssuerAuthorizingKey = (&sk).into(); + let ik: IssuerValidatingKey = (&isk).into(); + + let fvk = FullViewingKey::from(&sk); + let recipient = fvk.address_at(0u32, Scope::External); + + let mut bundle = IssueBundle::new(); + + bundle + .add_recipient( + ik.clone(), + String::from("Frost"), + recipient, + NoteValue::from_raw(5), + false, + rng, + ) + .unwrap(); + + let fake_sighash = [1; 32]; + let prepared = bundle.prepare(fake_sighash); + + let action = prepared + .get_action(ik.clone(), String::from("Frost")) + .unwrap(); + let auth = action.authorization(); + assert_eq!(auth.sighash, fake_sighash); + } } // mod tests { diff --git a/src/keys.rs b/src/keys.rs index 37a7b0ea..0e495207 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -212,7 +212,11 @@ impl IssuerAuthorizingKey { /// RXXXX /// /// XXXXX - pub fn sign(&self, rng: &mut (impl RngCore + CryptoRng), msg: &[u8]) -> redpallas::Signature { + pub fn sign( + &self, + rng: &mut (impl RngCore + CryptoRng), + msg: &[u8], + ) -> redpallas::Signature { self.0.sign(rng, msg) } } diff --git a/src/note/note_type.rs b/src/note/note_type.rs index 3571b215..c3f2480a 100644 --- a/src/note/note_type.rs +++ b/src/note/note_type.rs @@ -92,17 +92,13 @@ pub mod testing { pub fn arb_note_type()( is_native in prop::bool::ANY, sk in arb_spending_key(), - // bytes32a in prop::array::uniform32(prop::num::u8::ANY), - // bytes32b in prop::array::uniform32(prop::num::u8::ANY), - vec in prop::collection::vec(any::(), 0..=255), + str in "[A-Za-z]{255}", ) -> NoteType { if is_native { NoteType::native() } else { - //let bytes64 = [bytes32a, bytes32b].concat(); - let asset_desc = String::from_utf8(vec).unwrap(); let isk = IssuerAuthorizingKey::from(&sk); - NoteType::derive(&IssuerValidatingKey::from(&isk), asset_desc.as_str()) + NoteType::derive(&IssuerValidatingKey::from(&isk), &str) } } }