1mod ed25519;
8mod hash;
9#[allow(dead_code)]
10mod secp256k1;
11pub mod signer;
12use std::{fmt::Display, io, num::ParseIntError, str::FromStr};
13
14use alloy_primitives::FixedBytes;
15use custom_debug_derive::Debug;
16pub use ed25519::{Ed25519PublicKey, Ed25519SecretKey, Ed25519Signature};
17pub use hash::*;
18use linera_witty::{WitLoad, WitStore, WitType};
19pub use secp256k1::{
20    evm::{EvmPublicKey, EvmSecretKey, EvmSignature},
21    Secp256k1PublicKey, Secp256k1SecretKey, Secp256k1Signature,
22};
23use serde::{Deserialize, Serialize};
24pub use signer::*;
25use thiserror::Error;
26
27use crate::{hex_debug, identifiers::AccountOwner};
28
29pub type ValidatorPublicKey = secp256k1::Secp256k1PublicKey;
31pub type ValidatorSecretKey = secp256k1::Secp256k1SecretKey;
33pub type ValidatorSignature = secp256k1::Secp256k1Signature;
35pub type ValidatorKeypair = secp256k1::Secp256k1KeyPair;
37
38#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)]
40pub enum SignatureScheme {
41    Ed25519,
43    Secp256k1,
45    EvmSecp256k1,
47}
48
49#[derive(
53    Serialize,
54    Deserialize,
55    Debug,
56    Eq,
57    PartialEq,
58    Ord,
59    PartialOrd,
60    Copy,
61    Clone,
62    Hash,
63    WitType,
64    WitLoad,
65    WitStore,
66)]
67pub enum AccountPublicKey {
68    Ed25519(ed25519::Ed25519PublicKey),
70    Secp256k1(secp256k1::Secp256k1PublicKey),
72    EvmSecp256k1(secp256k1::evm::EvmPublicKey),
74}
75
76#[derive(Serialize, Deserialize)]
78pub enum AccountSecretKey {
79    Ed25519(ed25519::Ed25519SecretKey),
81    Secp256k1(secp256k1::Secp256k1SecretKey),
83    EvmSecp256k1(secp256k1::evm::EvmSecretKey),
85}
86
87#[derive(Eq, PartialEq, Copy, Clone, Debug, Serialize, Deserialize)]
89pub enum AccountSignature {
90    Ed25519 {
92        signature: ed25519::Ed25519Signature,
94        public_key: ed25519::Ed25519PublicKey,
96    },
97    Secp256k1 {
99        signature: secp256k1::Secp256k1Signature,
101        public_key: secp256k1::Secp256k1PublicKey,
103    },
104    EvmSecp256k1 {
106        signature: secp256k1::evm::EvmSignature,
108        #[debug(with = "hex_debug")]
110        address: [u8; 20],
111    },
112}
113
114impl AccountSecretKey {
115    pub fn public(&self) -> AccountPublicKey {
117        match self {
118            AccountSecretKey::Ed25519(secret) => AccountPublicKey::Ed25519(secret.public()),
119            AccountSecretKey::Secp256k1(secret) => AccountPublicKey::Secp256k1(secret.public()),
120            AccountSecretKey::EvmSecp256k1(secret) => {
121                AccountPublicKey::EvmSecp256k1(secret.public())
122            }
123        }
124    }
125
126    pub fn copy(&self) -> Self {
128        match self {
129            AccountSecretKey::Ed25519(secret) => AccountSecretKey::Ed25519(secret.copy()),
130            AccountSecretKey::Secp256k1(secret) => AccountSecretKey::Secp256k1(secret.copy()),
131            AccountSecretKey::EvmSecp256k1(secret) => AccountSecretKey::EvmSecp256k1(secret.copy()),
132        }
133    }
134
135    pub fn sign<'de, T>(&self, value: &T) -> AccountSignature
137    where
138        T: BcsSignable<'de>,
139    {
140        match self {
141            AccountSecretKey::Ed25519(secret) => {
142                let signature = Ed25519Signature::new(value, secret);
143                let public_key = secret.public();
144                AccountSignature::Ed25519 {
145                    signature,
146                    public_key,
147                }
148            }
149            AccountSecretKey::Secp256k1(secret) => {
150                let signature = secp256k1::Secp256k1Signature::new(value, secret);
151                let public_key = secret.public();
152                AccountSignature::Secp256k1 {
153                    signature,
154                    public_key,
155                }
156            }
157            AccountSecretKey::EvmSecp256k1(secret) => {
158                let signature = secp256k1::evm::EvmSignature::new(CryptoHash::new(value), secret);
159                let address: [u8; 20] = secret.address().into();
160                AccountSignature::EvmSecp256k1 { signature, address }
161            }
162        }
163    }
164
165    pub fn sign_prehash(&self, value: CryptoHash) -> AccountSignature {
167        match self {
168            AccountSecretKey::Ed25519(secret) => {
169                let signature = Ed25519Signature::sign_prehash(secret, value);
170                let public_key = secret.public();
171                AccountSignature::Ed25519 {
172                    signature,
173                    public_key,
174                }
175            }
176            AccountSecretKey::Secp256k1(secret) => {
177                let signature = secp256k1::Secp256k1Signature::sign_prehash(secret, value);
178                let public_key = secret.public();
179                AccountSignature::Secp256k1 {
180                    signature,
181                    public_key,
182                }
183            }
184            AccountSecretKey::EvmSecp256k1(secret) => {
185                let signature = secp256k1::evm::EvmSignature::sign_prehash(secret, value);
186                let address: [u8; 20] = secret.address().into();
187                AccountSignature::EvmSecp256k1 { signature, address }
188            }
189        }
190    }
191
192    #[cfg(all(with_testing, with_getrandom))]
193    pub fn generate() -> Self {
195        AccountSecretKey::Ed25519(Ed25519SecretKey::generate())
196    }
197
198    #[cfg(all(with_getrandom, not(feature = "revm")))]
199    pub fn generate_from<R: CryptoRng>(rng: &mut R) -> Self {
201        AccountSecretKey::Ed25519(Ed25519SecretKey::generate_from(rng))
202    }
203
204    #[cfg(all(with_getrandom, feature = "revm"))]
205    pub fn generate_from<R: CryptoRng>(rng: &mut R) -> Self {
207        AccountSecretKey::EvmSecp256k1(EvmSecretKey::generate_from(rng))
208    }
209}
210
211impl AccountPublicKey {
212    pub fn scheme(&self) -> SignatureScheme {
214        match self {
215            AccountPublicKey::Ed25519(_) => SignatureScheme::Ed25519,
216            AccountPublicKey::Secp256k1(_) => SignatureScheme::Secp256k1,
217            AccountPublicKey::EvmSecp256k1(_) => SignatureScheme::EvmSecp256k1,
218        }
219    }
220
221    pub fn as_bytes(&self) -> Vec<u8> {
223        bcs::to_bytes(&self).expect("serialization to bytes should not fail")
224    }
225
226    pub fn from_slice(bytes: &[u8]) -> Result<Self, CryptoError> {
230        bcs::from_bytes(bytes).map_err(CryptoError::PublicKeyParseError)
231    }
232
233    #[cfg(with_testing)]
235    pub fn test_key(name: u8) -> Self {
236        AccountPublicKey::Ed25519(Ed25519PublicKey::test_key(name))
237    }
238}
239
240impl AccountSignature {
241    pub fn verify<'de, T>(&self, value: &T) -> Result<(), CryptoError>
243    where
244        T: BcsSignable<'de> + std::fmt::Debug,
245    {
246        match self {
247            AccountSignature::Ed25519 {
248                signature,
249                public_key,
250            } => signature.check(value, *public_key),
251            AccountSignature::Secp256k1 {
252                signature,
253                public_key,
254            } => signature.check(value, *public_key),
255            AccountSignature::EvmSecp256k1 {
256                signature,
257                address: sender_address,
258            } => {
259                signature.check_with_recover(value, *sender_address)?;
260                Ok(())
261            }
262        }
263    }
264
265    pub fn to_bytes(&self) -> Vec<u8> {
267        bcs::to_bytes(&self).expect("serialization to bytes should not fail")
268    }
269
270    pub fn from_slice(bytes: &[u8]) -> Result<Self, CryptoError> {
272        bcs::from_bytes(bytes).map_err(CryptoError::SignatureParseError)
273    }
274
275    pub fn owner(&self) -> AccountOwner {
277        match self {
278            AccountSignature::Ed25519 { public_key, .. } => AccountOwner::from(*public_key),
279            AccountSignature::Secp256k1 { public_key, .. } => AccountOwner::from(*public_key),
280            AccountSignature::EvmSecp256k1 { address, .. } => AccountOwner::Address20(*address),
281        }
282    }
283}
284
285impl FromStr for AccountPublicKey {
286    type Err = CryptoError;
287
288    fn from_str(s: &str) -> Result<Self, Self::Err> {
289        let value = hex::decode(s)?;
290        AccountPublicKey::from_slice(value.as_slice())
291    }
292}
293
294impl Display for AccountPublicKey {
295    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
296        write!(f, "{}", hex::encode(self.as_bytes()))
297    }
298}
299
300impl TryFrom<&[u8]> for AccountSignature {
301    type Error = CryptoError;
302
303    fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
304        AccountSignature::from_slice(bytes)
305    }
306}
307
308#[derive(Error, Debug)]
310#[allow(missing_docs)]
311pub enum CryptoError {
312    #[error("Signature for object {type_name} is not valid: {error}")]
313    InvalidSignature { error: String, type_name: String },
314    #[error("Signature from validator is missing")]
315    MissingValidatorSignature,
316    #[error(transparent)]
317    NonHexDigits(#[from] hex::FromHexError),
318    #[error(
319        "Byte slice has length {0} but a `CryptoHash` requires exactly {expected} bytes",
320        expected = FixedBytes::<32>::len_bytes(),
321    )]
322    IncorrectHashSize(usize),
323    #[error(
324        "Byte slice has length {len} but a {scheme} `PublicKey` requires exactly {expected} bytes"
325    )]
326    IncorrectPublicKeySize {
327        scheme: &'static str,
328        len: usize,
329        expected: usize,
330    },
331    #[error(
332        "byte slice has length {len} but a {scheme} `Signature` requires exactly {expected} bytes"
333    )]
334    IncorrectSignatureBytes {
335        scheme: &'static str,
336        len: usize,
337        expected: usize,
338    },
339    #[error("Could not parse integer: {0}")]
340    ParseIntError(#[from] ParseIntError),
341    #[error("secp256k1 error: {0}")]
342    Secp256k1Error(k256::ecdsa::Error),
343    #[error("could not parse public key: {0}: point at infinity")]
344    Secp256k1PointAtInfinity(String),
345    #[error("could not parse public key: {0}")]
346    PublicKeyParseError(bcs::Error),
347    #[error("could not parse signature: {0}")]
348    SignatureParseError(bcs::Error),
349}
350
351#[cfg(with_getrandom)]
352pub trait CryptoRng: rand::CryptoRng + rand::RngCore + Send + Sync {}
354
355#[cfg(with_getrandom)]
356impl<T: rand::CryptoRng + rand::RngCore + Send + Sync> CryptoRng for T {}
357
358#[cfg(with_getrandom)]
359impl From<Option<u64>> for Box<dyn CryptoRng> {
360    fn from(seed: Option<u64>) -> Self {
361        use rand::SeedableRng;
362
363        match seed {
364            Some(seed) => Box::new(rand::rngs::StdRng::seed_from_u64(seed)),
365            None => Box::new(rand::rngs::OsRng),
366        }
367    }
368}
369
370pub trait Hashable<Hasher> {
372    fn write(&self, hasher: &mut Hasher);
374}
375
376pub trait HasTypeName {
378    fn type_name() -> &'static str;
380}
381
382pub trait BcsHashable<'de>: Serialize + Deserialize<'de> {}
386
387pub trait BcsSignable<'de>: Serialize + Deserialize<'de> {}
391
392impl<'de, T: BcsSignable<'de>> BcsHashable<'de> for T {}
393
394impl<'de, T, Hasher> Hashable<Hasher> for T
395where
396    T: BcsHashable<'de>,
397    Hasher: io::Write,
398{
399    fn write(&self, hasher: &mut Hasher) {
400        let name = <Self as HasTypeName>::type_name();
401        write!(hasher, "{}::", name).expect("Hasher should not fail");
403        bcs::serialize_into(hasher, &self).expect("Message serialization should not fail");
404    }
405}
406
407impl<Hasher> Hashable<Hasher> for [u8]
408where
409    Hasher: io::Write,
410{
411    fn write(&self, hasher: &mut Hasher) {
412        hasher.write_all(self).expect("Hasher should not fail");
413    }
414}
415
416impl<'de, T> HasTypeName for T
417where
418    T: BcsHashable<'de>,
419{
420    fn type_name() -> &'static str {
421        serde_name::trace_name::<Self>().expect("Self must be a struct or an enum")
422    }
423}
424
425#[cfg(with_testing)]
427#[derive(Debug, Serialize, Deserialize)]
428pub struct TestString(pub String);
429
430#[cfg(with_testing)]
431impl TestString {
432    pub fn new(s: impl Into<String>) -> Self {
434        Self(s.into())
435    }
436}
437
438#[cfg(with_testing)]
439impl BcsSignable<'_> for TestString {}
440
441pub(crate) fn le_bytes_to_u64_array(bytes: &[u8]) -> [u64; 4] {
443    let mut integers = [0u64; 4];
444
445    integers[0] = u64::from_le_bytes(bytes[0..8].try_into().expect("incorrect indices"));
446    integers[1] = u64::from_le_bytes(bytes[8..16].try_into().expect("incorrect indices"));
447    integers[2] = u64::from_le_bytes(bytes[16..24].try_into().expect("incorrect indices"));
448    integers[3] = u64::from_le_bytes(bytes[24..32].try_into().expect("incorrect indices"));
449
450    integers
451}
452
453pub(crate) fn be_bytes_to_u64_array(bytes: &[u8]) -> [u64; 4] {
455    let mut integers = [0u64; 4];
456
457    integers[0] = u64::from_be_bytes(bytes[0..8].try_into().expect("incorrect indices"));
458    integers[1] = u64::from_be_bytes(bytes[8..16].try_into().expect("incorrect indices"));
459    integers[2] = u64::from_be_bytes(bytes[16..24].try_into().expect("incorrect indices"));
460    integers[3] = u64::from_be_bytes(bytes[24..32].try_into().expect("incorrect indices"));
461
462    integers
463}
464
465pub(crate) fn u64_array_to_le_bytes(integers: [u64; 4]) -> [u8; 32] {
467    let mut bytes = [0u8; 32];
468
469    bytes[0..8].copy_from_slice(&integers[0].to_le_bytes());
470    bytes[8..16].copy_from_slice(&integers[1].to_le_bytes());
471    bytes[16..24].copy_from_slice(&integers[2].to_le_bytes());
472    bytes[24..32].copy_from_slice(&integers[3].to_le_bytes());
473
474    bytes
475}
476
477pub fn u64_array_to_be_bytes(integers: [u64; 4]) -> [u8; 32] {
479    let mut bytes = [0u8; 32];
480
481    bytes[0..8].copy_from_slice(&integers[0].to_be_bytes());
482    bytes[8..16].copy_from_slice(&integers[1].to_be_bytes());
483    bytes[16..24].copy_from_slice(&integers[2].to_be_bytes());
484    bytes[24..32].copy_from_slice(&integers[3].to_be_bytes());
485
486    bytes
487}
488
489#[cfg(test)]
490mod tests {
491    use super::*;
492    use crate::crypto::{ed25519::Ed25519SecretKey, secp256k1::Secp256k1KeyPair};
493
494    #[test]
495    fn test_u64_array_to_be_bytes() {
496        let input = [
497            0x0123456789ABCDEF,
498            0xFEDCBA9876543210,
499            0x0011223344556677,
500            0x8899AABBCCDDEEFF,
501        ];
502        let expected_output = [
503            0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54,
504            0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB,
505            0xCC, 0xDD, 0xEE, 0xFF,
506        ];
507
508        let output = u64_array_to_be_bytes(input);
509        assert_eq!(output, expected_output);
510        assert_eq!(input, be_bytes_to_u64_array(&u64_array_to_be_bytes(input)));
511    }
512
513    #[test]
514    fn test_u64_array_to_le_bytes() {
515        let input = [
516            0x0123456789ABCDEF,
517            0xFEDCBA9876543210,
518            0x0011223344556677,
519            0x8899AABBCCDDEEFF,
520        ];
521        let expected_output = [
522            0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01, 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA,
523            0xDC, 0xFE, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0xFF, 0xEE, 0xDD, 0xCC,
524            0xBB, 0xAA, 0x99, 0x88,
525        ];
526
527        let output = u64_array_to_le_bytes(input);
528        assert_eq!(output, expected_output);
529        assert_eq!(input, le_bytes_to_u64_array(&u64_array_to_le_bytes(input)));
530    }
531
532    #[test]
533    fn roundtrip_account_pk_bytes_repr() {
534        fn roundtrip_test(secret: AccountSecretKey) {
535            let public = secret.public();
536            let bytes = public.as_bytes();
537            let parsed = AccountPublicKey::from_slice(&bytes).unwrap();
538            assert_eq!(public, parsed);
539        }
540        roundtrip_test(AccountSecretKey::Ed25519(Ed25519SecretKey::generate()));
541        roundtrip_test(AccountSecretKey::Secp256k1(
542            Secp256k1KeyPair::generate().secret_key,
543        ));
544    }
545
546    #[test]
547    fn roundtrip_signature_bytes_repr() {
548        fn roundtrip_test(secret: AccountSecretKey) {
549            let test_string = TestString::new("test");
550            let signature = secret.sign(&test_string);
551            let bytes = signature.to_bytes();
552            let parsed = AccountSignature::from_slice(&bytes).unwrap();
553            assert_eq!(signature, parsed);
554        }
555        roundtrip_test(AccountSecretKey::Ed25519(Ed25519SecretKey::generate()));
556        roundtrip_test(AccountSecretKey::Secp256k1(
557            Secp256k1KeyPair::generate().secret_key,
558        ));
559        roundtrip_test(AccountSecretKey::EvmSecp256k1(EvmSecretKey::generate()));
560    }
561
562    #[test]
563    fn roundtrip_display_from_str_pk() {
564        fn test(secret: AccountSecretKey) {
565            let public = secret.public();
566            let display = public.to_string();
567            let parsed = AccountPublicKey::from_str(&display).unwrap();
568            assert_eq!(public, parsed);
569        }
570        test(AccountSecretKey::Ed25519(Ed25519SecretKey::generate()));
571        test(AccountSecretKey::Secp256k1(
572            Secp256k1KeyPair::generate().secret_key,
573        ));
574    }
575}