From cb5ba6860ae0a78d7ba4b44f2296cf3a57088170 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 16 Oct 2024 11:37:19 +0000 Subject: [PATCH] WIP unfinished changes --- pczt/src/lib.rs | 51 +++++++++++++++++++++++++++++++++++++++++ pczt/src/orchard.rs | 6 +++++ pczt/src/sapling.rs | 6 +++++ pczt/src/transparent.rs | 12 ++++++++++ 4 files changed, 75 insertions(+) diff --git a/pczt/src/lib.rs b/pczt/src/lib.rs index e0216df087..b7c7b1dcf0 100644 --- a/pczt/src/lib.rs +++ b/pczt/src/lib.rs @@ -1,12 +1,54 @@ //! The Partially Created Zcash Transaction (PCZT) format. //! +//! General flow for creating a shielded transaction: +//! - Create "unsigned transaction" +//! - In practice means deciding on the global parts of the transaction +//! - Collect each output +//! - Proofs can be created at this time +//! - Decide on an anchor +//! - All spends should use the same anchor for indistinguishability +//! - In a future transaction version, all spends will be required to do so +//! - Collect each spend +//! - Proofs can and should be created at this time +//! - Create proofs for each spend and output +//! - Data necessary for proofs can be stripped out of the format +//! - Collect proofs +//! - Distribute collected data to signers +//! - Signers must verify the transaction before signing, and reject if not satisfied. +//! - This is the no-turning-back point regarding spend authorization! +//! - Collect signatures +//! - Create binding signature +//! - The party that performs this does not need to be trusted, because each signer +//! has verified the transaction and signed it, so the bindingSig can only be +//! computed over the same data if a valid transaction is to be created. +//! - Extract final transaction +//! //! Goal is to split up the parts of creating a transaction across distinct entities. //! The entity roles roughly match BIP 174: Partially Signed Bitcoin Transaction Format. //! - Creator //! - Creates the base PCZT with no information about spends or outputs. //! - Constructor //! - Adds spends and outputs to the PCZT. +//! - Before any input or output may be added, the constructor must check the +//! PSBT_GLOBAL_TX_MODIFIABLE field. Inputs may only be added if the Inputs Modifiable +//! flag is True. Outputs may only be added if the Outputs Modifiable flag is True. //! - A single entity is likely to be both a Creator and Constructor. +//! - IO Finalizer +//! - Sets the appropriate bits in PSBT_GLOBAL_TX_MODIFIABLE to 0. (TODO fix up) +//! - Inspects the inputs and outputs throughout the PCZT and picks a transaction +//! version that is compatible with all of them (or returns an error). +//! - Updates the various bsk values using the rcv information from spends and outputs. +//! - This can happen after each spend or output is added if they are added serially. +//! If spends and outputs are created in parallel, the IO Finalizer must act after +//! the Combiner. +//! - Updater +//! - Adds information necessary for subsequent entities to proceed, such as key paths +//! for signing spends. +//! - Redactor +//! - Removes information that is unnecessary for subsequent entities to proceed. +//! - This can be useful e.g. when creating a transaction that has inputs from multiple +//! independent Signers; each can receive a PCZT with just the information they need +//! to sign, but (e.g.) not the `alpha` values for other Signers. //! - Prover //! - Needs all private information for a single spend or output. //! - In practice, the Updater that adds a given spend or output will either act as @@ -14,7 +56,13 @@ //! then receive back the PCZT with private data stripped and proof added. //! - Signer //! - Needs the spend authorization randomizers to create signatures. +//! - Needs sufficient information to verify that the proof is over the correct data. +//! without needing to verify the proof itself. //! - A Signer should only need to implement: +//! - Pedersen commitments using Jubjub arithmetic (for note and value commitments) +//! - BLAKE2b and BLAKE2s (and the various PRFs / CRHs they are used in) +//! - Nullifier check (using Jubjub arithmetic) +//! - KDF plus note decryption (AEAD_CHACHA20_POLY1305) //! - SignatureHash algorithm //! - Signatures (RedJubjub) //! - A source of randomness. @@ -34,6 +82,9 @@ //! the PCZT, with spendAuthSigs and bindingSig empty, and then enforcing equality. //! - This is equivalent to BIP 147's equality definition (the partial transactions //! must be identical). +//! - Spend Finalizer +//! - Currently unnecessary, but when shielded multisig is implemented, this would be the +//! entity that combines the separate signatures into a multisignature. //! - Transaction Extractor //! - Creates bindingSig and extracts the final transaction. diff --git a/pczt/src/orchard.rs b/pczt/src/orchard.rs index 4e3c2a6806..f30d7020b6 100644 --- a/pczt/src/orchard.rs +++ b/pczt/src/orchard.rs @@ -140,6 +140,10 @@ pub(crate) struct Spend { /// - After`zkproof` / `spend_auth_sig` has been set, this can be redacted. pub(crate) alpha: Option<[u8; 32]>, + // TODO derivation path + + // TODO FROST + pub(crate) proprietary: BTreeMap>, } @@ -198,6 +202,8 @@ pub(crate) struct Output { /// "None", to make the output unrecoverable from the chain by the sender. pub(crate) ock: Option<[u8; 32]>, + // TODO derivation path + pub(crate) proprietary: BTreeMap>, } diff --git a/pczt/src/sapling.rs b/pczt/src/sapling.rs index 3db0cc1cc3..a58f9e617d 100644 --- a/pczt/src/sapling.rs +++ b/pczt/src/sapling.rs @@ -107,6 +107,10 @@ pub(crate) struct Spend { /// - After`zkproof` / `spend_auth_sig` has been set, this can be redacted. pub(crate) alpha: Option<[u8; 32]>, + // TODO derivation path + + // TODO FROST + pub(crate) proprietary: BTreeMap>, } @@ -182,6 +186,8 @@ pub(crate) struct Output { /// "None", to make the output unrecoverable from the chain by the sender. pub(crate) ock: Option<[u8; 32]>, + // TODO derivation path + pub(crate) proprietary: BTreeMap>, } diff --git a/pczt/src/transparent.rs b/pczt/src/transparent.rs index 152d05e711..76484241d2 100644 --- a/pczt/src/transparent.rs +++ b/pczt/src/transparent.rs @@ -42,6 +42,16 @@ pub(crate) struct Input { pub(crate) value: u64, pub(crate) script_pubkey: Vec, + /// A map from a pubkey to a signature created by it. + /// + /// - Each entry is set by a Signer. + /// - These are required by the Spend Finalizer to assemble `script_sig`. + /// + /// TODO: Decide on map key type. + pub(crate) signatures: BTreeMap, Vec>, + + // TODO derivation path + pub(crate) proprietary: BTreeMap>, } @@ -56,6 +66,8 @@ pub(crate) struct Output { pub(crate) value: u64, pub(crate) script_pubkey: Vec, + // TODO derivation path + pub(crate) proprietary: BTreeMap>, }