decaf377_rdsa/
domain.rs

1/// Abstracts over different signature domains.
2///
3/// This design is described [at the end of ยง5.4.6][concretereddsa] of the Zcash
4/// protocol specification: the generator used for the signature scheme is left
5/// as an unspecified parameter, chosen differently for each signature domain.
6///
7/// To handle this, we encode the domain as a type parameter.
8///
9/// [concretereddsa]: https://zips.z.cash/protocol/protocol.pdf#concretereddsa
10pub trait Domain: private::Sealed {}
11
12/// A type variable corresponding to Zcash's `BindingSig`.
13#[derive(Copy, Clone, PartialEq, Eq, Debug)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub enum Binding {}
16impl Domain for Binding {}
17
18/// A type variable corresponding to Zcash's `SpendAuthSig`.
19#[derive(Copy, Clone, PartialEq, Eq, Debug)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub enum SpendAuth {}
22impl Domain for SpendAuth {}
23
24pub(crate) mod private {
25    use super::*;
26
27    fn hash_to_group(input: &[u8]) -> decaf377::Element {
28        decaf377::Element::encode_to_curve(&decaf377::Fq::from_le_bytes_mod_order(
29            blake2b_simd::blake2b(input).as_bytes(),
30        ))
31    }
32
33    pub trait Sealed: Copy + Clone + Eq + PartialEq + core::fmt::Debug {
34        fn basepoint() -> decaf377::Element;
35    }
36
37    impl Sealed for Binding {
38        fn basepoint() -> decaf377::Element {
39            hash_to_group(b"decaf377-rdsa-binding")
40        }
41    }
42
43    impl Sealed for SpendAuth {
44        fn basepoint() -> decaf377::Element {
45            decaf377::Element::GENERATOR
46        }
47    }
48}
49
50pub(crate) use private::Sealed;