From 6b495f711a19fb15de4174c56c9ddc05aa242330 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 28 Jul 2021 13:45:24 +0100 Subject: [PATCH] Extract InProgress type from Unauthorized and PartiallyAuthorized This enables bundle proofs and signatures to be handled separately outside the builder. --- src/builder.rs | 58 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 31bade20..db8ba598 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -285,7 +285,7 @@ impl Builder { mut self, mut rng: impl RngCore, pk: &ProvingKey, - ) -> Result, Error> { + ) -> Result, V>, Error> { // Pair up the spends and recipients, extending with dummy values as necessary. // // TODO: Do we want to shuffle the order like we do for Sapling? And if we do, do @@ -360,11 +360,31 @@ impl Builder { flags, result_value_balance, anchor, - Unauthorized { proof, bsk }, + InProgress { + proof, + sigs: Unauthorized { bsk }, + }, )) } } +/// Marker trait representing bundle signatures in the process of being created. +pub trait InProgressSignatures { + /// The authorization type of an Orchard action in the process of being authorized. + type SpendAuth; +} + +/// Marker for a bundle in the process of being built. +#[derive(Debug)] +pub struct InProgress { + proof: P, + sigs: S, +} + +impl Authorization for InProgress { + type SpendAuth = S::SpendAuth; +} + /// The parts needed to sign an [`Action`]. #[derive(Debug)] pub struct SigningParts { @@ -375,14 +395,13 @@ pub struct SigningParts { alpha: pallas::Scalar, } -/// Marker for an unauthorized bundle, with a proof but no signatures. +/// Marker for an unauthorized bundle with no signatures. #[derive(Debug)] pub struct Unauthorized { - proof: Proof, bsk: redpallas::SigningKey, } -impl Authorization for Unauthorized { +impl InProgressSignatures for Unauthorized { type SpendAuth = SigningMetadata; } @@ -401,12 +420,11 @@ pub struct SigningMetadata { /// Marker for a partially-authorized bundle, in the process of being signed. #[derive(Debug)] pub struct PartiallyAuthorized { - proof: Proof, binding_signature: redpallas::Signature, sighash: [u8; 32], } -impl Authorization for PartiallyAuthorized { +impl InProgressSignatures for PartiallyAuthorized { type SpendAuth = MaybeSigned; } @@ -430,7 +448,7 @@ impl MaybeSigned { } } -impl Bundle { +impl Bundle, V> { /// Loads the sighash into this bundle, preparing it for signing. /// /// This API ensures that all signatures are created over the same sighash. @@ -438,7 +456,7 @@ impl Bundle { self, mut rng: R, sighash: [u8; 32], - ) -> Bundle { + ) -> Bundle, V> { self.authorize( &mut rng, |rng, _, SigningMetadata { dummy_ask, parts }| { @@ -448,14 +466,18 @@ impl Bundle { .map(MaybeSigned::Signature) .unwrap_or(MaybeSigned::SigningMetadata(parts)) }, - |rng, unauth| PartiallyAuthorized { - proof: unauth.proof, - binding_signature: unauth.bsk.sign(rng, &sighash), - sighash, + |rng, auth| InProgress { + proof: auth.proof, + sigs: PartiallyAuthorized { + binding_signature: auth.sigs.bsk.sign(rng, &sighash), + sighash, + }, }, ) } +} +impl Bundle, V> { /// Applies signatures to this bundle, in order to authorize it. pub fn apply_signatures( self, @@ -472,7 +494,7 @@ impl Bundle { } } -impl Bundle { +impl Bundle, V> { /// Signs this bundle with the given [`SpendAuthorizingKey`]. /// /// This will apply signatures for all notes controlled by this spending key. @@ -482,14 +504,18 @@ impl Bundle { &mut rng, |rng, partial, maybe| match maybe { MaybeSigned::SigningMetadata(parts) if parts.ak == expected_ak => { - MaybeSigned::Signature(ask.randomize(&parts.alpha).sign(rng, &partial.sighash)) + MaybeSigned::Signature( + ask.randomize(&parts.alpha).sign(rng, &partial.sigs.sighash), + ) } s => s, }, |_, partial| partial, ) } +} +impl Bundle, V> { /// Finalizes this bundle, enabling it to be included in a transaction. /// /// Returns an error if any signatures are missing. @@ -500,7 +526,7 @@ impl Bundle { |_, partial| { Ok(Authorized::from_parts( partial.proof, - partial.binding_signature, + partial.sigs.binding_signature, )) }, )