commonware_cryptography/
lib.rs

1//! Generate keys, sign arbitrary messages, and deterministically verify signatures.
2//!
3//! # Status
4//!
5//! `commonware-cryptography` is **ALPHA** software and is not yet recommended for production use. Developers should
6//! expect breaking changes and occasional instability.
7
8use bytes::Buf;
9use commonware_utils::SizedSerialize;
10use rand::{CryptoRng, Rng, RngCore, SeedableRng};
11use std::fmt::Display;
12use std::{fmt::Debug, hash::Hash, ops::Deref};
13use thiserror::Error;
14
15pub mod bls12381;
16pub use bls12381::Bls12381;
17pub mod ed25519;
18pub use ed25519::{Ed25519, Ed25519Batch};
19pub mod sha256;
20pub use sha256::{hash, Sha256};
21pub mod secp256r1;
22pub use secp256r1::Secp256r1;
23
24/// Errors that can occur when interacting with cryptographic primitives.
25#[derive(Error, Debug, PartialEq)]
26pub enum Error {
27    #[error("invalid digest length")]
28    InvalidDigestLength,
29    #[error("invalid private key")]
30    InvalidPrivateKey,
31    #[error("invalid private key length")]
32    InvalidPrivateKeyLength,
33    #[error("invalid public key")]
34    InvalidPublicKey,
35    #[error("invalid public key length")]
36    InvalidPublicKeyLength,
37    #[error("invalid signature")]
38    InvalidSignature,
39    #[error("invalid signature length")]
40    InvalidSignatureLength,
41    #[error("invalid bytes")]
42    InsufficientBytes,
43}
44
45/// Types that can be fallibly read from a fixed-size byte sequence.
46///
47/// `Array` is typically used to parse things like `PublicKeys` and `Signatures`
48/// from an untrusted network connection. Once parsed, these types are assumed
49/// to be well-formed (which prevents duplicate validation).
50///
51/// If a byte sequencer is not properly formatted, `TryFrom` must return an error.
52pub trait Array:
53    Clone
54    + Send
55    + Sync
56    + 'static
57    + Eq
58    + PartialEq
59    + Ord
60    + PartialOrd
61    + Debug
62    + Hash
63    + Display
64    + AsRef<[u8]>
65    + Deref<Target = [u8]>
66    + for<'a> TryFrom<&'a [u8], Error = Error>
67    + for<'a> TryFrom<&'a Vec<u8>, Error = Error>
68    + TryFrom<Vec<u8>, Error = Error>
69    + SizedSerialize
70{
71    /// Attempts to read an array from the provided buffer.
72    fn read_from<B: Buf>(buf: &mut B) -> Result<Self, Error> {
73        // Check if there are enough bytes in the buffer to read a digest.
74        let len = Self::SERIALIZED_LEN;
75        if buf.remaining() < len {
76            return Err(Error::InsufficientBytes);
77        }
78
79        // If there are enough contiguous bytes in the buffer, use them directly.
80        let chunk = buf.chunk();
81        if chunk.len() >= len {
82            let array = Self::try_from(&chunk[..len])?;
83            buf.advance(len);
84            return Ok(array);
85        }
86
87        // Otherwise, copy the bytes into a temporary buffer.
88        let mut temp = vec![0u8; len];
89        buf.copy_to_slice(&mut temp);
90        Self::try_from(temp)
91    }
92}
93
94/// Interface that commonware crates rely on for most cryptographic operations.
95pub trait Scheme: Clone + Send + Sync + 'static {
96    /// Private key used for signing.
97    type PrivateKey: Array;
98
99    /// Public key used for verifying signatures.
100    type PublicKey: Array;
101
102    /// Signature generated by signing a message.
103    type Signature: Array;
104
105    /// Returns a new instance of the scheme.
106    fn new<R: Rng + CryptoRng>(rng: &mut R) -> Self;
107
108    /// Returns a new instance of the scheme from a secret key.
109    fn from(private_key: Self::PrivateKey) -> Option<Self>;
110
111    /// Returns a new instance of the scheme from a provided seed.
112    ///
113    /// # Warning
114    ///
115    /// This function is insecure and should only be used for examples
116    /// and testing.
117    fn from_seed(seed: u64) -> Self {
118        let mut rng = rand::rngs::StdRng::seed_from_u64(seed);
119        Self::new(&mut rng)
120    }
121
122    /// Returns the private key of the signer.
123    fn private_key(&self) -> Self::PrivateKey;
124
125    /// Returns the public key of the signer.
126    fn public_key(&self) -> Self::PublicKey;
127
128    /// Sign the given message.
129    ///
130    /// The message should not be hashed prior to calling this function. If a particular scheme
131    /// requires a payload to be hashed before it is signed, it will be done internally.
132    ///
133    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
134    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
135    /// a message on the network layer can't accidentally spend funds on the execution layer). See
136    /// [union_unique](commonware_utils::union_unique) for details.
137    fn sign(&mut self, namespace: Option<&[u8]>, message: &[u8]) -> Self::Signature;
138
139    /// Check that a signature is valid for the given message and public key.
140    ///
141    /// The message should not be hashed prior to calling this function. If a particular
142    /// scheme requires a payload to be hashed before it is signed, it will be done internally.
143    ///
144    /// Because namespace is prepended to message before signing, the namespace provided here must
145    /// match the namespace provided during signing.
146    fn verify(
147        namespace: Option<&[u8]>,
148        message: &[u8],
149        public_key: &Self::PublicKey,
150        signature: &Self::Signature,
151    ) -> bool;
152}
153
154/// Interface that commonware crates rely on for batched cryptographic operations.
155pub trait BatchScheme {
156    /// Public key used for verifying signatures.
157    type PublicKey: Array;
158
159    /// Signature generated by signing a message.
160    type Signature: Array;
161
162    /// Create a new batch scheme.
163    fn new() -> Self;
164
165    /// Append item to the batch.
166    ///
167    /// The message should not be hashed prior to calling this function. If a particular scheme
168    /// requires a payload to be hashed before it is signed, it will be done internally.
169    ///
170    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
171    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
172    /// a message on the network layer can't accidentally spend funds on the execution layer). See
173    /// [union_unique](commonware_utils::union_unique) for details.
174    fn add(
175        &mut self,
176        namespace: Option<&[u8]>,
177        message: &[u8],
178        public_key: &Self::PublicKey,
179        signature: &Self::Signature,
180    ) -> bool;
181
182    /// Verify all items added to the batch.
183    ///
184    /// Returns `true` if all items are valid, `false` otherwise.
185    ///
186    /// # Why Randomness?
187    ///
188    /// When performing batch verification, it is often important to add some randomness
189    /// to prevent an attacker from constructing a malicious batch of signatures that pass
190    /// batch verification but are invalid individually. Abstractly, think of this as
191    /// there existing two valid signatures (`c_1` and `c_2`) and an attacker proposing
192    /// (`c_1 + d` and `c_2 - d`).
193    ///
194    /// You can read more about this [here](https://ethresear.ch/t/security-of-bls-batch-verification/10748#the-importance-of-randomness-4).
195    fn verify<R: RngCore + CryptoRng>(self, rng: &mut R) -> bool;
196}
197
198/// Interface that commonware crates rely on for hashing.
199///
200/// Hash functions in commonware primitives are not typically hardcoded
201/// to a specific algorithm (e.g. SHA-256) because different hash functions
202/// may work better with different cryptographic schemes, may be more efficient
203/// to use in STARK/SNARK proofs, or provide different levels of security (with some
204/// performance/size penalty).
205///
206/// This trait is required to implement the `Clone` trait because it is often
207/// part of a struct that is cloned. In practice, implementations do not actually
208/// clone the hasher state but users should not rely on this behavior and call `reset`
209/// after cloning.
210pub trait Hasher: Clone + Send + Sync + 'static {
211    /// Digest generated by the hasher.
212    type Digest: Array;
213
214    /// Create a new hasher.
215    fn new() -> Self;
216
217    /// Append message to previously recorded data.
218    fn update(&mut self, message: &[u8]);
219
220    /// Hash all recorded data and reset the hasher
221    /// to the initial state.
222    fn finalize(&mut self) -> Self::Digest;
223
224    /// Reset the hasher without generating a hash.
225    ///
226    /// This function does not need to be called after `finalize`.
227    fn reset(&mut self);
228
229    /// Generate a random digest.
230    ///
231    /// # Warning
232    ///
233    /// This function is typically used for testing and is not recommended
234    /// for production use.
235    fn random<R: Rng + CryptoRng>(rng: &mut R) -> Self::Digest;
236}
237
238#[cfg(test)]
239mod tests {
240    use super::*;
241    use rand::rngs::OsRng;
242
243    fn test_validate<C: Scheme>() {
244        let signer = C::new(&mut OsRng);
245        let public_key = signer.public_key();
246        assert!(C::PublicKey::try_from(public_key.as_ref()).is_ok());
247    }
248
249    fn test_from_valid_private_key<C: Scheme>() {
250        let signer = C::new(&mut OsRng);
251        let private_key = signer.private_key();
252        let public_key = signer.public_key();
253        let signer = C::from(private_key).unwrap();
254        assert_eq!(public_key, signer.public_key());
255    }
256
257    fn test_validate_invalid_public_key<C: Scheme>() {
258        let result = C::PublicKey::try_from(vec![0; 1024]);
259        assert_eq!(result, Err(Error::InvalidPublicKeyLength));
260    }
261
262    fn test_sign_and_verify<C: Scheme>() {
263        let mut signer = C::from_seed(0);
264        let namespace = Some(&b"test_namespace"[..]);
265        let message = b"test_message";
266        let signature = signer.sign(namespace, message);
267        let public_key = signer.public_key();
268        assert!(C::verify(namespace, message, &public_key, &signature));
269    }
270
271    fn test_sign_and_verify_wrong_message<C: Scheme>() {
272        let mut signer = C::from_seed(0);
273        let namespace: Option<&[u8]> = Some(&b"test_namespace"[..]);
274        let message = b"test_message";
275        let wrong_message = b"wrong_message";
276        let signature = signer.sign(namespace, message);
277        let public_key = signer.public_key();
278        assert!(!C::verify(
279            namespace,
280            wrong_message,
281            &public_key,
282            &signature
283        ));
284    }
285
286    fn test_sign_and_verify_wrong_namespace<C: Scheme>() {
287        let mut signer = C::from_seed(0);
288        let namespace = Some(&b"test_namespace"[..]);
289        let wrong_namespace = Some(&b"wrong_namespace"[..]);
290        let message = b"test_message";
291        let signature = signer.sign(namespace, message);
292        let public_key = signer.public_key();
293        assert!(!C::verify(
294            wrong_namespace,
295            message,
296            &public_key,
297            &signature
298        ));
299    }
300
301    fn test_empty_vs_none_namespace<C: Scheme>() {
302        let mut signer = C::from_seed(0);
303        let empty_namespace = Some(&b""[..]);
304        let message = b"test_message";
305        let signature = signer.sign(empty_namespace, message);
306        let public_key = signer.public_key();
307        assert!(C::verify(empty_namespace, message, &public_key, &signature));
308        assert!(!C::verify(None, message, &public_key, &signature));
309    }
310
311    fn test_signature_determinism<C: Scheme>() {
312        let mut signer_1 = C::from_seed(0);
313        let mut signer_2 = C::from_seed(0);
314        let namespace = Some(&b"test_namespace"[..]);
315        let message = b"test_message";
316        let signature_1 = signer_1.sign(namespace, message);
317        let signature_2 = signer_2.sign(namespace, message);
318        assert_eq!(signer_1.public_key(), signer_2.public_key());
319        assert_eq!(signature_1, signature_2);
320    }
321
322    fn test_invalid_signature_publickey_pair<C: Scheme>() {
323        let mut signer = C::from_seed(0);
324        let signer_2 = C::from_seed(1);
325        let namespace = Some(&b"test_namespace"[..]);
326        let message = b"test_message";
327        let signature = signer.sign(namespace, message);
328        let public_key = signer_2.public_key();
329        assert!(!C::verify(namespace, message, &public_key, &signature));
330    }
331
332    #[test]
333    fn test_ed25519_validate() {
334        test_validate::<Ed25519>();
335    }
336
337    #[test]
338    fn test_ed25519_validate_invalid_public_key() {
339        test_validate_invalid_public_key::<Ed25519>();
340    }
341
342    #[test]
343    fn test_ed25519_from_valid_private_key() {
344        test_from_valid_private_key::<Ed25519>();
345    }
346
347    #[test]
348    fn test_ed25519_sign_and_verify() {
349        test_sign_and_verify::<Ed25519>();
350    }
351
352    #[test]
353    fn test_ed25519_sign_and_verify_wrong_message() {
354        test_sign_and_verify_wrong_message::<Ed25519>();
355    }
356
357    #[test]
358    fn test_ed25519_sign_and_verify_wrong_namespace() {
359        test_sign_and_verify_wrong_namespace::<Ed25519>();
360    }
361
362    #[test]
363    fn test_ed25519_empty_vs_none_namespace() {
364        test_empty_vs_none_namespace::<Ed25519>();
365    }
366
367    #[test]
368    fn test_ed25519_signature_determinism() {
369        test_signature_determinism::<Ed25519>();
370    }
371
372    #[test]
373    fn test_ed25519_invalid_signature_publickey_pair() {
374        test_invalid_signature_publickey_pair::<Ed25519>();
375    }
376
377    #[test]
378    fn test_ed25519_len() {
379        assert_eq!(<Ed25519 as Scheme>::PublicKey::SERIALIZED_LEN, 32);
380        assert_eq!(<Ed25519 as Scheme>::Signature::SERIALIZED_LEN, 64);
381    }
382
383    #[test]
384    fn test_bls12381_validate() {
385        test_validate::<Bls12381>();
386    }
387
388    #[test]
389    fn test_bls12381_validate_invalid_public_key() {
390        test_validate_invalid_public_key::<Bls12381>();
391    }
392
393    #[test]
394    fn test_bls12381_from_valid_private_key() {
395        test_from_valid_private_key::<Bls12381>();
396    }
397
398    #[test]
399    fn test_bls12381_sign_and_verify() {
400        test_sign_and_verify::<Bls12381>();
401    }
402
403    #[test]
404    fn test_bls12381_sign_and_verify_wrong_message() {
405        test_sign_and_verify_wrong_message::<Bls12381>();
406    }
407
408    #[test]
409    fn test_bls12381_sign_and_verify_wrong_namespace() {
410        test_sign_and_verify_wrong_namespace::<Bls12381>();
411    }
412
413    #[test]
414    fn test_bls12381_empty_vs_none_namespace() {
415        test_empty_vs_none_namespace::<Bls12381>();
416    }
417
418    #[test]
419    fn test_bls12381_signature_determinism() {
420        test_signature_determinism::<Bls12381>();
421    }
422
423    #[test]
424    fn test_bls12381_invalid_signature_publickey_pair() {
425        test_invalid_signature_publickey_pair::<Bls12381>();
426    }
427
428    #[test]
429    fn test_bls12381_len() {
430        assert_eq!(<Bls12381 as Scheme>::PublicKey::SERIALIZED_LEN, 48);
431        assert_eq!(<Bls12381 as Scheme>::Signature::SERIALIZED_LEN, 96);
432    }
433
434    #[test]
435    fn test_secp256r1_validate() {
436        test_validate::<Secp256r1>();
437    }
438
439    #[test]
440    fn test_secp256r1_validate_invalid_public_key() {
441        test_validate_invalid_public_key::<Secp256r1>();
442    }
443
444    #[test]
445    fn test_secp256r1_from_valid_private_key() {
446        test_from_valid_private_key::<Secp256r1>();
447    }
448
449    #[test]
450    fn test_secp256r1_sign_and_verify() {
451        test_sign_and_verify::<Secp256r1>();
452    }
453
454    #[test]
455    fn test_secp256r1_sign_and_verify_wrong_message() {
456        test_sign_and_verify_wrong_message::<Secp256r1>();
457    }
458
459    #[test]
460    fn test_secp256r1_sign_and_verify_wrong_namespace() {
461        test_sign_and_verify_wrong_namespace::<Secp256r1>();
462    }
463
464    #[test]
465    fn test_secp256r1_empty_vs_none_namespace() {
466        test_empty_vs_none_namespace::<Secp256r1>();
467    }
468
469    #[test]
470    fn test_secp256r1_signature_determinism() {
471        test_signature_determinism::<Secp256r1>();
472    }
473
474    #[test]
475    fn test_secp256r1_invalid_signature_publickey_pair() {
476        test_invalid_signature_publickey_pair::<Secp256r1>();
477    }
478
479    #[test]
480    fn test_secp256r1_len() {
481        assert_eq!(<Secp256r1 as Scheme>::PublicKey::SERIALIZED_LEN, 33);
482        assert_eq!(<Secp256r1 as Scheme>::Signature::SERIALIZED_LEN, 64);
483    }
484
485    fn test_hasher_multiple_runs<H: Hasher>() {
486        // Generate initial hash
487        let mut hasher = H::new();
488        hasher.update(b"hello world");
489        let digest = hasher.finalize();
490        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
491        assert_eq!(digest.as_ref().len(), H::Digest::SERIALIZED_LEN);
492
493        // Reuse hasher without reset
494        hasher.update(b"hello world");
495        let digest_again = hasher.finalize();
496        assert!(H::Digest::try_from(digest_again.as_ref()).is_ok());
497        assert_eq!(digest, digest_again);
498
499        // Reuse hasher with reset
500        hasher.update(b"hello mars");
501        hasher.reset();
502        hasher.update(b"hello world");
503        let digest_reset = hasher.finalize();
504        assert!(H::Digest::try_from(digest_reset.as_ref()).is_ok());
505        assert_eq!(digest, digest_reset);
506
507        // Hash different data
508        hasher.update(b"hello mars");
509        let digest_mars = hasher.finalize();
510        assert!(H::Digest::try_from(digest_mars.as_ref()).is_ok());
511        assert_ne!(digest, digest_mars);
512    }
513
514    fn test_hasher_multiple_updates<H: Hasher>() {
515        // Generate initial hash
516        let mut hasher = H::new();
517        hasher.update(b"hello");
518        hasher.update(b" world");
519        let digest = hasher.finalize();
520        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
521
522        // Generate hash in oneshot
523        let mut hasher = H::new();
524        hasher.update(b"hello world");
525        let digest_oneshot = hasher.finalize();
526        assert!(H::Digest::try_from(digest_oneshot.as_ref()).is_ok());
527        assert_eq!(digest, digest_oneshot);
528    }
529
530    fn test_hasher_empty_input<H: Hasher>() {
531        let mut hasher = H::new();
532        let digest = hasher.finalize();
533        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
534    }
535
536    fn test_hasher_large_input<H: Hasher>() {
537        let mut hasher = H::new();
538        let data = vec![1; 1024];
539        hasher.update(&data);
540        let digest = hasher.finalize();
541        assert!(H::Digest::try_from(digest.as_ref()).is_ok());
542    }
543
544    #[test]
545    fn test_sha256_hasher_multiple_runs() {
546        test_hasher_multiple_runs::<Sha256>();
547    }
548
549    #[test]
550    fn test_sha256_hasher_multiple_updates() {
551        test_hasher_multiple_updates::<Sha256>();
552    }
553
554    #[test]
555    fn test_sha256_hasher_empty_input() {
556        test_hasher_empty_input::<Sha256>();
557    }
558
559    #[test]
560    fn test_sha256_hasher_large_input() {
561        test_hasher_large_input::<Sha256>();
562    }
563}