sapling_crypto/pczt/
signer.rs

1use rand::{CryptoRng, RngCore};
2
3use crate::keys::SpendAuthorizingKey;
4
5impl super::Spend {
6    /// Signs the Sapling spend with the given spend authorizing key.
7    ///
8    /// It is the caller's responsibility to perform any semantic validity checks on the
9    /// PCZT (for example, comfirming that the change amounts are correct) before calling
10    /// this method.
11    pub fn sign<R: RngCore + CryptoRng>(
12        &mut self,
13        sighash: [u8; 32],
14        ask: &SpendAuthorizingKey,
15        rng: R,
16    ) -> Result<(), SignerError> {
17        let alpha = self.alpha.ok_or(SignerError::MissingSpendAuthRandomizer)?;
18
19        let rsk = ask.randomize(&alpha);
20        let rk = redjubjub::VerificationKey::from(&rsk);
21
22        if self.rk == rk {
23            self.spend_auth_sig = Some(rsk.sign(rng, &sighash));
24            Ok(())
25        } else {
26            Err(SignerError::WrongSpendAuthorizingKey)
27        }
28    }
29}
30
31/// Errors that can occur while signing an Orchard action in a PCZT.
32#[derive(Debug)]
33pub enum SignerError {
34    /// The Signer role requires `alpha` to be set.
35    MissingSpendAuthRandomizer,
36    /// The provided `ask` does not own the action's spent note.
37    WrongSpendAuthorizingKey,
38}