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