lit_node_core/models/
signing_scheme.rs

1use crate::{CurveType, Error};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::fmt::{self, Display, Formatter};
4use std::str::FromStr;
5
6#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
7pub enum SigningAlgorithm {
8    Pairing,
9    Ecdsa,
10    Schnorr,
11}
12
13#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
14pub enum KeyFormatPreference {
15    Uncompressed,
16    Compressed,
17}
18
19#[derive(Clone, Copy, Debug, Default, Hash, Eq, PartialEq)]
20pub enum SigningScheme {
21    #[default]
22    Bls12381,
23    EcdsaK256Sha256,
24    EcdsaP256Sha256,
25    EcdsaP384Sha384,
26    SchnorrEd25519Sha512,
27    SchnorrK256Sha256,
28    SchnorrP256Sha256,
29    SchnorrP384Sha384,
30    SchnorrRistretto25519Sha512,
31    SchnorrEd448Shake256,
32    SchnorrRedJubjubBlake2b512,
33    SchnorrK256Taproot,
34    SchnorrRedDecaf377Blake2b512,
35    SchnorrRedPallasBlake2b512,
36    SchnorrkelSubstrate,
37    Bls12381G1ProofOfPossession,
38}
39
40impl Display for SigningScheme {
41    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
42        match self {
43            Self::Bls12381 => write!(f, "Bls12381"),
44            Self::EcdsaK256Sha256 => write!(f, "EcdsaK256Sha256"),
45            Self::EcdsaP256Sha256 => write!(f, "EcdsaP256Sha256"),
46            Self::EcdsaP384Sha384 => write!(f, "EcdsaP384Sha384"),
47            Self::SchnorrEd25519Sha512 => write!(f, "SchnorrEd25519Sha512"),
48            Self::SchnorrK256Sha256 => write!(f, "SchnorrK256Sha256"),
49            Self::SchnorrP256Sha256 => write!(f, "SchnorrP256Sha256"),
50            Self::SchnorrP384Sha384 => write!(f, "SchnorrP384Sha384"),
51            Self::SchnorrRistretto25519Sha512 => write!(f, "SchnorrRistretto25519Sha512"),
52            Self::SchnorrEd448Shake256 => write!(f, "SchnorrEd448Shake256"),
53            Self::SchnorrRedJubjubBlake2b512 => write!(f, "SchnorrRedJubjubBlake2b512"),
54            Self::SchnorrRedPallasBlake2b512 => write!(f, "SchnorrRedPallasBlake2b512"),
55            Self::SchnorrK256Taproot => write!(f, "SchnorrK256Taproot"),
56            Self::SchnorrRedDecaf377Blake2b512 => write!(f, "SchnorrRedDecaf377Blake2b512"),
57            Self::SchnorrkelSubstrate => write!(f, "SchnorrkelSubstrate"),
58            Self::Bls12381G1ProofOfPossession => write!(f, "Bls12381G1ProofOfPossession"),
59        }
60    }
61}
62
63impl FromStr for SigningScheme {
64    type Err = Error;
65
66    fn from_str(s: &str) -> Result<Self, Self::Err> {
67        match s {
68            "Bls12381" => Ok(SigningScheme::Bls12381),
69            "EcdsaK256Sha256" => Ok(SigningScheme::EcdsaK256Sha256),
70            "EcdsaP256Sha256" => Ok(SigningScheme::EcdsaP256Sha256),
71            "EcdsaP384Sha384" => Ok(SigningScheme::EcdsaP384Sha384),
72            "SchnorrEd25519Sha512" => Ok(SigningScheme::SchnorrEd25519Sha512),
73            "SchnorrK256Sha256" => Ok(SigningScheme::SchnorrK256Sha256),
74            "SchnorrP256Sha256" => Ok(SigningScheme::SchnorrP256Sha256),
75            "SchnorrP384Sha384" => Ok(SigningScheme::SchnorrP384Sha384),
76            "SchnorrRistretto25519Sha512" => Ok(SigningScheme::SchnorrRistretto25519Sha512),
77            "SchnorrEd448Shake256" => Ok(SigningScheme::SchnorrEd448Shake256),
78            "SchnorrRedJubjubBlake2b512" => Ok(SigningScheme::SchnorrRedJubjubBlake2b512),
79            "SchnorrRedPallasBlake2b512" => Ok(SigningScheme::SchnorrRedPallasBlake2b512),
80            "SchnorrK256Taproot" => Ok(SigningScheme::SchnorrK256Taproot),
81            "SchnorrRedDecaf377Blake2b512" => Ok(SigningScheme::SchnorrRedDecaf377Blake2b512),
82            "SchnorrkelSubstrate" => Ok(SigningScheme::SchnorrkelSubstrate),
83            "Bls12381G1ProofOfPossession" => Ok(SigningScheme::Bls12381G1ProofOfPossession),
84            _ => Err(Error::Parse(format!("Invalid signing scheme: {}", s))),
85        }
86    }
87}
88
89impl From<SigningScheme> for u8 {
90    fn from(value: SigningScheme) -> Self {
91        match value {
92            SigningScheme::Bls12381 => 1,
93            SigningScheme::EcdsaK256Sha256 => 2,
94            SigningScheme::EcdsaP256Sha256 => 3,
95            SigningScheme::EcdsaP384Sha384 => 4,
96            SigningScheme::SchnorrEd25519Sha512 => 5,
97            SigningScheme::SchnorrK256Sha256 => 6,
98            SigningScheme::SchnorrP256Sha256 => 7,
99            SigningScheme::SchnorrP384Sha384 => 8,
100            SigningScheme::SchnorrRistretto25519Sha512 => 9,
101            SigningScheme::SchnorrEd448Shake256 => 10,
102            SigningScheme::SchnorrRedJubjubBlake2b512 => 11,
103            SigningScheme::SchnorrK256Taproot => 12,
104            SigningScheme::SchnorrRedDecaf377Blake2b512 => 13,
105            SigningScheme::SchnorrkelSubstrate => 14,
106            SigningScheme::Bls12381G1ProofOfPossession => 15,
107            SigningScheme::SchnorrRedPallasBlake2b512 => 16,
108        }
109    }
110}
111
112impl TryFrom<u8> for SigningScheme {
113    type Error = Error;
114
115    fn try_from(value: u8) -> Result<Self, Self::Error> {
116        match value {
117            1 => Ok(SigningScheme::Bls12381),
118            2 => Ok(SigningScheme::EcdsaK256Sha256),
119            3 => Ok(SigningScheme::EcdsaP256Sha256),
120            4 => Ok(SigningScheme::EcdsaP384Sha384),
121            5 => Ok(SigningScheme::SchnorrEd25519Sha512),
122            6 => Ok(SigningScheme::SchnorrK256Sha256),
123            7 => Ok(SigningScheme::SchnorrP256Sha256),
124            8 => Ok(SigningScheme::SchnorrP384Sha384),
125            9 => Ok(SigningScheme::SchnorrRistretto25519Sha512),
126            10 => Ok(SigningScheme::SchnorrEd448Shake256),
127            11 => Ok(SigningScheme::SchnorrRedJubjubBlake2b512),
128            12 => Ok(SigningScheme::SchnorrK256Taproot),
129            13 => Ok(SigningScheme::SchnorrRedDecaf377Blake2b512),
130            14 => Ok(SigningScheme::SchnorrkelSubstrate),
131            15 => Ok(SigningScheme::Bls12381G1ProofOfPossession),
132            16 => Ok(SigningScheme::SchnorrRedPallasBlake2b512),
133            _ => Err(Error::Parse(format!("Invalid signing scheme: {}", value))),
134        }
135    }
136}
137
138impl Serialize for SigningScheme {
139    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
140    where
141        S: Serializer,
142    {
143        if serializer.is_human_readable() {
144            serializer.serialize_str(&self.to_string())
145        } else {
146            serializer.serialize_u8((*self).into())
147        }
148    }
149}
150
151impl<'de> Deserialize<'de> for SigningScheme {
152    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153    where
154        D: Deserializer<'de>,
155    {
156        if deserializer.is_human_readable() {
157            let s = String::deserialize(deserializer)?;
158            SigningScheme::from_str(&s).map_err(serde::de::Error::custom)
159        } else {
160            SigningScheme::try_from(u8::deserialize(deserializer)?)
161                .map_err(serde::de::Error::custom)
162        }
163    }
164}
165
166impl SigningScheme {
167    pub fn supports_algorithm(&self, algorithm: SigningAlgorithm) -> bool {
168        // required to keep the matches aligned like this.
169        matches!(
170            (algorithm, self),
171            (SigningAlgorithm::Pairing, SigningScheme::Bls12381)
172                | (
173                    SigningAlgorithm::Pairing,
174                    SigningScheme::Bls12381G1ProofOfPossession
175                )
176                | (SigningAlgorithm::Ecdsa, SigningScheme::EcdsaK256Sha256)
177                | (
178                    SigningAlgorithm::Schnorr,
179                    SigningScheme::SchnorrEd25519Sha512
180                )
181                | (SigningAlgorithm::Schnorr, SigningScheme::SchnorrK256Sha256)
182                | (SigningAlgorithm::Schnorr, SigningScheme::SchnorrP256Sha256)
183                | (SigningAlgorithm::Schnorr, SigningScheme::SchnorrP384Sha384)
184                | (
185                    SigningAlgorithm::Schnorr,
186                    SigningScheme::SchnorrRistretto25519Sha512
187                )
188                | (
189                    SigningAlgorithm::Schnorr,
190                    SigningScheme::SchnorrEd448Shake256
191                )
192                | (
193                    SigningAlgorithm::Schnorr,
194                    SigningScheme::SchnorrRedJubjubBlake2b512
195                )
196                | (SigningAlgorithm::Schnorr, SigningScheme::SchnorrK256Taproot)
197                | (
198                    SigningAlgorithm::Schnorr,
199                    SigningScheme::SchnorrRedDecaf377Blake2b512
200                )
201                | (
202                    SigningAlgorithm::Schnorr,
203                    SigningScheme::SchnorrkelSubstrate
204                )
205                | (
206                    SigningAlgorithm::Schnorr,
207                    SigningScheme::SchnorrRedPallasBlake2b512
208                )
209        )
210    }
211
212    pub fn supports_curve(&self, curve_type: CurveType) -> bool {
213        self.curve_type() == curve_type
214    }
215
216    pub fn preferred_format(&self) -> KeyFormatPreference {
217        match self {
218            Self::Bls12381
219            | Self::Bls12381G1ProofOfPossession
220            | Self::SchnorrK256Sha256
221            | Self::SchnorrP256Sha256
222            | Self::SchnorrP384Sha384
223            | Self::SchnorrK256Taproot
224            | Self::SchnorrEd25519Sha512
225            | Self::SchnorrRistretto25519Sha512
226            | Self::SchnorrEd448Shake256
227            | Self::SchnorrRedJubjubBlake2b512
228            | Self::SchnorrRedPallasBlake2b512
229            | Self::SchnorrRedDecaf377Blake2b512
230            | Self::SchnorrkelSubstrate => KeyFormatPreference::Compressed,
231            Self::EcdsaK256Sha256 | Self::EcdsaP256Sha256 | Self::EcdsaP384Sha384 => {
232                KeyFormatPreference::Uncompressed
233            }
234        }
235    }
236
237    pub const fn ecdsa_message_len(&self) -> usize {
238        match self {
239            Self::EcdsaK256Sha256 => 32,
240            Self::EcdsaP256Sha256 => 32,
241            Self::EcdsaP384Sha384 => 48,
242            _ => 0,
243        }
244    }
245
246    pub const fn curve_type(&self) -> CurveType {
247        match self {
248            Self::Bls12381 => CurveType::BLS,
249            Self::EcdsaK256Sha256 => CurveType::K256,
250            Self::EcdsaP256Sha256 => CurveType::P256,
251            Self::EcdsaP384Sha384 => CurveType::P384,
252            Self::SchnorrEd25519Sha512 => CurveType::Ed25519,
253            Self::SchnorrK256Sha256 => CurveType::K256,
254            Self::SchnorrP256Sha256 => CurveType::P256,
255            Self::SchnorrP384Sha384 => CurveType::P384,
256            Self::SchnorrRistretto25519Sha512 | Self::SchnorrkelSubstrate => {
257                CurveType::Ristretto25519
258            }
259            Self::SchnorrEd448Shake256 => CurveType::Ed448,
260            Self::SchnorrRedJubjubBlake2b512 => CurveType::RedJubjub,
261            Self::SchnorrRedPallasBlake2b512 => CurveType::RedPallas,
262            Self::SchnorrK256Taproot => CurveType::K256,
263            Self::SchnorrRedDecaf377Blake2b512 => CurveType::RedDecaf377,
264            Self::Bls12381G1ProofOfPossession => CurveType::BLS12381G1,
265        }
266    }
267
268    pub const fn id_sign_ctx(&self) -> &'static [u8] {
269        match self {
270            SigningScheme::Bls12381 => b"LIT_HD_KEY_ID_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_",
271            SigningScheme::EcdsaP256Sha256 | SigningScheme::SchnorrP256Sha256 => {
272                b"LIT_HD_KEY_ID_P256_XMD:SHA-256_SSWU_RO_NUL_"
273            }
274            SigningScheme::SchnorrK256Taproot
275            | SigningScheme::EcdsaK256Sha256
276            | SigningScheme::SchnorrK256Sha256 => b"LIT_HD_KEY_ID_K256_XMD:SHA-256_SSWU_RO_NUL_",
277            SigningScheme::EcdsaP384Sha384 | SigningScheme::SchnorrP384Sha384 => {
278                b"LIT_HD_KEY_ID_P384_XMD:SHA-384_SSWU_RO_NUL_"
279            }
280            SigningScheme::SchnorrRistretto25519Sha512 | SigningScheme::SchnorrkelSubstrate => {
281                b"LIT_HD_KEY_ID_RISTRETTO255_XMD:SHA-512_ELL2_RO_NUL_"
282            }
283            SigningScheme::SchnorrEd25519Sha512 => {
284                b"LIT_HD_KEY_ID_ED25519_XMD:SHA-512_ELL2_RO_NUL_"
285            }
286            SigningScheme::SchnorrEd448Shake256 => {
287                b"LIT_HD_KEY_ID_ED448_XOF:SHAKE-256_ELL2_RO_NUL_"
288            }
289            SigningScheme::SchnorrRedJubjubBlake2b512 => {
290                b"LIT_HD_KEY_ID_REDJUBJUB_XMD:BLAKE2B-512_ELL2_RO_NUL_"
291            }
292            SigningScheme::SchnorrRedPallasBlake2b512 => {
293                b"LIT_HD_KEY_ID_REDPALLAS_XMD:BLAKE2B-512_SSWU_RO_NUL_"
294            }
295            SigningScheme::SchnorrRedDecaf377Blake2b512 => {
296                b"LIT_HD_KEY_ID_DECAF377_XMD:BLAKE2B-512_ELL2_RO_NUL_"
297            }
298            SigningScheme::Bls12381G1ProofOfPossession => {
299                b"LIT_HD_KEY_ID_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"
300            }
301        }
302    }
303
304    pub const fn hash_prior_to_sending(&self) -> bool {
305        match self {
306            Self::SchnorrK256Sha256
307            | Self::SchnorrP256Sha256
308            | Self::SchnorrP384Sha384
309            | Self::SchnorrEd25519Sha512
310            | Self::SchnorrRistretto25519Sha512
311            | Self::SchnorrEd448Shake256
312            | Self::SchnorrRedJubjubBlake2b512
313            | Self::SchnorrRedPallasBlake2b512
314            | Self::SchnorrRedDecaf377Blake2b512
315            | Self::SchnorrkelSubstrate
316            | Self::Bls12381
317            | Self::Bls12381G1ProofOfPossession => false,
318            Self::EcdsaK256Sha256
319            | Self::EcdsaP256Sha256
320            | Self::EcdsaP384Sha384
321            | Self::SchnorrK256Taproot => true,
322        }
323    }
324
325    pub const fn as_str(&self) -> &'static str {
326        match self {
327            Self::Bls12381 => "Bls12381",
328            Self::EcdsaK256Sha256 => "EcdsaK256Sha256",
329            Self::EcdsaP256Sha256 => "EcdsaP256Sha256",
330            Self::EcdsaP384Sha384 => "EcdsaP384Sha384",
331            Self::SchnorrEd25519Sha512 => "SchnorrEd25519Sha512",
332            Self::SchnorrK256Sha256 => "SchnorrK256Sha256",
333            Self::SchnorrP256Sha256 => "SchnorrP256Sha256",
334            Self::SchnorrP384Sha384 => "SchnorrP384Sha384",
335            Self::SchnorrRistretto25519Sha512 => "SchnorrRistretto25519Sha512",
336            Self::SchnorrEd448Shake256 => "SchnorrEd448Shake256",
337            Self::SchnorrRedJubjubBlake2b512 => "SchnorrRedJubjubBlake2b512",
338            Self::SchnorrRedPallasBlake2b512 => "SchnorrRedPallasBlake2b512",
339            Self::SchnorrK256Taproot => "SchnorrK256Taproot",
340            Self::SchnorrRedDecaf377Blake2b512 => "SchnorrRedDecaf377Blake2b512",
341            Self::SchnorrkelSubstrate => "SchnorrkelSubstrate",
342            Self::Bls12381G1ProofOfPossession => "Bls12381G1ProofOfPossession",
343        }
344    }
345}