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
8#![doc(
9    html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
10    html_favicon_url = "https://commonware.xyz/favicon.ico"
11)]
12#![cfg_attr(not(feature = "std"), no_std)]
13
14#[cfg(not(feature = "std"))]
15extern crate alloc;
16
17use commonware_codec::{Encode, ReadExt};
18use commonware_utils::Array;
19use rand::SeedableRng as _;
20use rand_chacha::ChaCha20Rng;
21
22pub mod bls12381;
23pub mod ed25519;
24pub mod sha256;
25use rand_core::CryptoRngCore;
26pub use sha256::{CoreSha256, Sha256};
27pub mod blake3;
28pub use blake3::{Blake3, CoreBlake3};
29pub mod bloomfilter;
30pub use bloomfilter::BloomFilter;
31#[cfg(feature = "std")]
32pub mod handshake;
33pub mod lthash;
34pub use lthash::LtHash;
35pub mod secp256r1;
36pub mod transcript;
37
38/// Produces [Signature]s over messages that can be verified with a corresponding [PublicKey].
39pub trait Signer: Send + Sync + Clone + 'static {
40    /// The type of [Signature] produced by this [Signer].
41    type Signature: Signature;
42
43    /// The corresponding [PublicKey] type.
44    type PublicKey: PublicKey<Signature = Self::Signature>;
45
46    /// Returns the [PublicKey] corresponding to this [Signer].
47    fn public_key(&self) -> Self::PublicKey;
48
49    /// Sign a message with the given namespace.
50    ///
51    /// The message should not be hashed prior to calling this function. If a particular scheme
52    /// requires a payload to be hashed before it is signed, it will be done internally.
53    ///
54    /// A namespace should be used to prevent cross-domain attacks (where a signature can be reused
55    /// in a different context). It must be prepended to the message so that a signature meant for
56    /// one context cannot be used unexpectedly in another (i.e. signing a message on the network
57    /// layer can't accidentally spend funds on the execution layer). See
58    /// [commonware_utils::union_unique] for details.
59    fn sign(&self, namespace: Option<&[u8]>, msg: &[u8]) -> Self::Signature;
60}
61
62/// A [Signer] that can be serialized/deserialized.
63pub trait PrivateKey: Signer + Sized + ReadExt + Encode + PartialEq + Array {}
64
65/// A [PrivateKey] that can be generated from a seed or RNG.
66pub trait PrivateKeyExt: PrivateKey {
67    /// Create a [PrivateKey] from a seed.
68    ///
69    /// # Warning
70    ///
71    /// This function is insecure and should only be used for examples
72    /// and testing.
73    fn from_seed(seed: u64) -> Self {
74        let mut rng = ChaCha20Rng::seed_from_u64(seed);
75        Self::from_rng(&mut rng)
76    }
77
78    /// Create a fresh [PrivateKey] using the supplied RNG.
79    fn from_rng<R: CryptoRngCore>(rng: &mut R) -> Self;
80}
81
82/// Verifies [Signature]s over messages.
83pub trait Verifier {
84    /// The type of [Signature] that this verifier can verify.
85    type Signature: Signature;
86
87    /// Verify that a [Signature] is a valid over a given message.
88    ///
89    /// The message should not be hashed prior to calling this function. If a particular
90    /// scheme requires a payload to be hashed before it is signed, it will be done internally.
91    ///
92    /// Because namespace is prepended to message before signing, the namespace provided here must
93    /// match the namespace provided during signing.
94    fn verify(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Self::Signature) -> bool;
95}
96
97/// A [PublicKey], able to verify [Signature]s.
98pub trait PublicKey: Verifier + Sized + ReadExt + Encode + PartialEq + Array {}
99
100/// A [Signature] over a message.
101pub trait Signature: Sized + Clone + ReadExt + Encode + PartialEq + Array {}
102
103/// Verifies whether all [Signature]s are correct or that some [Signature] is incorrect.
104pub trait BatchVerifier<K: PublicKey> {
105    /// Create a new batch verifier.
106    fn new() -> Self;
107
108    /// Append item to the batch.
109    ///
110    /// The message should not be hashed prior to calling this function. If a particular scheme
111    /// requires a payload to be hashed before it is signed, it will be done internally.
112    ///
113    /// A namespace should be used to prevent replay attacks. It will be prepended to the message so
114    /// that a signature meant for one context cannot be used unexpectedly in another (i.e. signing
115    /// a message on the network layer can't accidentally spend funds on the execution layer). See
116    /// [commonware_utils::union_unique] for details.
117    fn add(
118        &mut self,
119        namespace: Option<&[u8]>,
120        message: &[u8],
121        public_key: &K,
122        signature: &K::Signature,
123    ) -> bool;
124
125    /// Verify all items added to the batch.
126    ///
127    /// Returns `true` if all items are valid, `false` otherwise.
128    ///
129    /// # Why Randomness?
130    ///
131    /// When performing batch verification, it is often important to add some randomness
132    /// to prevent an attacker from constructing a malicious batch of signatures that pass
133    /// batch verification but are invalid individually. Abstractly, think of this as
134    /// there existing two valid signatures (`c_1` and `c_2`) and an attacker proposing
135    /// (`c_1 + d` and `c_2 - d`).
136    ///
137    /// You can read more about this [here](https://ethresear.ch/t/security-of-bls-batch-verification/10748#the-importance-of-randomness-4).
138    fn verify<R: CryptoRngCore>(self, rng: &mut R) -> bool;
139}
140
141/// Specializes the [commonware_utils::Array] trait with the Copy trait for cryptographic digests
142/// (which should be cheap to clone).
143pub trait Digest: Array + Copy {
144    /// Generate a random [Digest].
145    ///
146    /// # Warning
147    ///
148    /// This function is typically used for testing and is not recommended
149    /// for production use.
150    fn random<R: CryptoRngCore>(rng: &mut R) -> Self;
151}
152
153/// An object that can be uniquely represented as a [Digest].
154pub trait Digestible: Clone + Sized + Send + Sync + 'static {
155    /// The type of digest produced by this object.
156    type Digest: Digest;
157
158    /// Returns a unique representation of the object as a [Digest].
159    ///
160    /// If many objects with [Digest]s are related (map to some higher-level
161    /// group [Digest]), you should also implement [Committable].
162    fn digest(&self) -> Self::Digest;
163}
164
165/// An object that can produce a commitment of itself.
166pub trait Committable: Clone + Sized + Send + Sync + 'static {
167    /// The type of commitment produced by this object.
168    type Commitment: Digest;
169
170    /// Returns the unique commitment of the object as a [Digest].
171    ///
172    /// For simple objects (like a block), this is often just the digest of the object
173    /// itself. For more complex objects, however, this may represent some root or base
174    /// of a proof structure (where many unique objects map to the same commitment).
175    ///
176    /// # Warning
177    ///
178    /// It must not be possible for two objects with the same [Digest] to map
179    /// to different commitments. Primitives assume there is a one-to-one
180    /// relation between digest and commitment and a one-to-many relation
181    /// between commitment and digest.
182    fn commitment(&self) -> Self::Commitment;
183}
184
185/// Interface that commonware crates rely on for hashing.
186///
187/// Hash functions in commonware primitives are not typically hardcoded
188/// to a specific algorithm (e.g. SHA-256) because different hash functions
189/// may work better with different cryptographic schemes, may be more efficient
190/// to use in STARK/SNARK proofs, or provide different levels of security (with some
191/// performance/size penalty).
192///
193/// This trait is required to implement the `Clone` trait because it is often
194/// part of a struct that is cloned. In practice, implementations do not actually
195/// clone the hasher state but users should not rely on this behavior and call `reset`
196/// after cloning.
197pub trait Hasher: Default + Clone + Send + Sync + 'static {
198    /// Digest generated by the hasher.
199    type Digest: Digest;
200
201    /// Create a new, empty hasher.
202    fn new() -> Self {
203        Self::default()
204    }
205
206    /// Append message to previously recorded data.
207    fn update(&mut self, message: &[u8]) -> &mut Self;
208
209    /// Hash all recorded data and reset the hasher
210    /// to the initial state.
211    fn finalize(&mut self) -> Self::Digest;
212
213    /// Reset the hasher without generating a hash.
214    ///
215    /// This function does not need to be called after `finalize`.
216    fn reset(&mut self) -> &mut Self;
217
218    /// Return result of hashing nothing.
219    fn empty() -> Self::Digest;
220
221    /// Hash a single message with a one-time-use hasher.
222    fn hash(message: &[u8]) -> Self::Digest {
223        Self::new().update(message).finalize()
224    }
225}
226
227#[cfg(test)]
228mod tests {
229    use super::*;
230    use commonware_codec::{DecodeExt, FixedSize};
231    use rand::rngs::OsRng;
232
233    fn test_validate<C: PrivateKeyExt>() {
234        let private_key = C::from_rng(&mut OsRng);
235        let public_key = private_key.public_key();
236        assert!(C::PublicKey::decode(public_key.as_ref()).is_ok());
237    }
238
239    fn test_validate_invalid_public_key<C: Signer>() {
240        let result = C::PublicKey::decode(vec![0; 1024].as_ref());
241        assert!(result.is_err());
242    }
243
244    fn test_sign_and_verify<C: PrivateKeyExt>() {
245        let private_key = C::from_seed(0);
246        let namespace = Some(&b"test_namespace"[..]);
247        let message = b"test_message";
248        let signature = private_key.sign(namespace, message);
249        let public_key = private_key.public_key();
250        assert!(public_key.verify(namespace, message, &signature));
251    }
252
253    fn test_sign_and_verify_wrong_message<C: PrivateKeyExt>() {
254        let private_key = C::from_seed(0);
255        let namespace: Option<&[u8]> = Some(&b"test_namespace"[..]);
256        let message = b"test_message";
257        let wrong_message = b"wrong_message";
258        let signature = private_key.sign(namespace, message);
259        let public_key = private_key.public_key();
260        assert!(!public_key.verify(namespace, wrong_message, &signature));
261    }
262
263    fn test_sign_and_verify_wrong_namespace<C: PrivateKeyExt>() {
264        let private_key = C::from_seed(0);
265        let namespace = Some(&b"test_namespace"[..]);
266        let wrong_namespace = Some(&b"wrong_namespace"[..]);
267        let message = b"test_message";
268        let signature = private_key.sign(namespace, message);
269        let public_key = private_key.public_key();
270        assert!(!public_key.verify(wrong_namespace, message, &signature));
271    }
272
273    fn test_empty_vs_none_namespace<C: PrivateKeyExt>() {
274        let private_key = C::from_seed(0);
275        let empty_namespace = Some(&b""[..]);
276        let message = b"test_message";
277        let signature = private_key.sign(empty_namespace, message);
278        let public_key = private_key.public_key();
279        assert!(public_key.verify(empty_namespace, message, &signature));
280        assert!(!public_key.verify(None, message, &signature));
281    }
282
283    fn test_signature_determinism<C: PrivateKeyExt>() {
284        let private_key_1 = C::from_seed(0);
285        let private_key_2 = C::from_seed(0);
286        let namespace = Some(&b"test_namespace"[..]);
287        let message = b"test_message";
288        let signature_1 = private_key_1.sign(namespace, message);
289        let signature_2 = private_key_2.sign(namespace, message);
290        assert_eq!(private_key_1.public_key(), private_key_2.public_key());
291        assert_eq!(signature_1, signature_2);
292    }
293
294    fn test_invalid_signature_publickey_pair<C: PrivateKeyExt>() {
295        let private_key = C::from_seed(0);
296        let private_key_2 = C::from_seed(1);
297        let namespace = Some(&b"test_namespace"[..]);
298        let message = b"test_message";
299        let signature = private_key.sign(namespace, message);
300        let public_key = private_key_2.public_key();
301        assert!(!public_key.verify(namespace, message, &signature));
302    }
303
304    #[test]
305    fn test_ed25519_validate() {
306        test_validate::<ed25519::PrivateKey>();
307    }
308
309    #[test]
310    fn test_ed25519_validate_invalid_public_key() {
311        test_validate_invalid_public_key::<ed25519::PrivateKey>();
312    }
313
314    #[test]
315    fn test_ed25519_sign_and_verify() {
316        test_sign_and_verify::<ed25519::PrivateKey>();
317    }
318
319    #[test]
320    fn test_ed25519_sign_and_verify_wrong_message() {
321        test_sign_and_verify_wrong_message::<ed25519::PrivateKey>();
322    }
323
324    #[test]
325    fn test_ed25519_sign_and_verify_wrong_namespace() {
326        test_sign_and_verify_wrong_namespace::<ed25519::PrivateKey>();
327    }
328
329    #[test]
330    fn test_ed25519_empty_vs_none_namespace() {
331        test_empty_vs_none_namespace::<ed25519::PrivateKey>();
332    }
333
334    #[test]
335    fn test_ed25519_signature_determinism() {
336        test_signature_determinism::<ed25519::PrivateKey>();
337    }
338
339    #[test]
340    fn test_ed25519_invalid_signature_publickey_pair() {
341        test_invalid_signature_publickey_pair::<ed25519::PrivateKey>();
342    }
343
344    #[test]
345    fn test_ed25519_len() {
346        assert_eq!(ed25519::PublicKey::SIZE, 32);
347        assert_eq!(ed25519::Signature::SIZE, 64);
348    }
349
350    #[test]
351    fn test_bls12381_validate() {
352        test_validate::<bls12381::PrivateKey>();
353    }
354
355    #[test]
356    fn test_bls12381_validate_invalid_public_key() {
357        test_validate_invalid_public_key::<bls12381::PrivateKey>();
358    }
359
360    #[test]
361    fn test_bls12381_sign_and_verify() {
362        test_sign_and_verify::<bls12381::PrivateKey>();
363    }
364
365    #[test]
366    fn test_bls12381_sign_and_verify_wrong_message() {
367        test_sign_and_verify_wrong_message::<bls12381::PrivateKey>();
368    }
369
370    #[test]
371    fn test_bls12381_sign_and_verify_wrong_namespace() {
372        test_sign_and_verify_wrong_namespace::<bls12381::PrivateKey>();
373    }
374
375    #[test]
376    fn test_bls12381_empty_vs_none_namespace() {
377        test_empty_vs_none_namespace::<bls12381::PrivateKey>();
378    }
379
380    #[test]
381    fn test_bls12381_signature_determinism() {
382        test_signature_determinism::<bls12381::PrivateKey>();
383    }
384
385    #[test]
386    fn test_bls12381_invalid_signature_publickey_pair() {
387        test_invalid_signature_publickey_pair::<bls12381::PrivateKey>();
388    }
389
390    #[test]
391    fn test_bls12381_len() {
392        assert_eq!(bls12381::PublicKey::SIZE, 48);
393        assert_eq!(bls12381::Signature::SIZE, 96);
394    }
395
396    #[test]
397    fn test_secp256r1_validate() {
398        test_validate::<secp256r1::PrivateKey>();
399    }
400
401    #[test]
402    fn test_secp256r1_validate_invalid_public_key() {
403        test_validate_invalid_public_key::<secp256r1::PrivateKey>();
404    }
405
406    #[test]
407    fn test_secp256r1_sign_and_verify() {
408        test_sign_and_verify::<secp256r1::PrivateKey>();
409    }
410
411    #[test]
412    fn test_secp256r1_sign_and_verify_wrong_message() {
413        test_sign_and_verify_wrong_message::<secp256r1::PrivateKey>();
414    }
415
416    #[test]
417    fn test_secp256r1_sign_and_verify_wrong_namespace() {
418        test_sign_and_verify_wrong_namespace::<secp256r1::PrivateKey>();
419    }
420
421    #[test]
422    fn test_secp256r1_empty_vs_none_namespace() {
423        test_empty_vs_none_namespace::<secp256r1::PrivateKey>();
424    }
425
426    #[test]
427    fn test_secp256r1_signature_determinism() {
428        test_signature_determinism::<secp256r1::PrivateKey>();
429    }
430
431    #[test]
432    fn test_secp256r1_invalid_signature_publickey_pair() {
433        test_invalid_signature_publickey_pair::<secp256r1::PrivateKey>();
434    }
435
436    #[test]
437    fn test_secp256r1_len() {
438        assert_eq!(secp256r1::PublicKey::SIZE, 33);
439        assert_eq!(secp256r1::Signature::SIZE, 64);
440    }
441
442    fn test_hasher_multiple_runs<H: Hasher>() {
443        // Generate initial hash
444        let mut hasher = H::new();
445        hasher.update(b"hello world");
446        let digest = hasher.finalize();
447        assert!(H::Digest::decode(digest.as_ref()).is_ok());
448        assert_eq!(digest.as_ref().len(), H::Digest::SIZE);
449
450        // Reuse hasher without reset
451        hasher.update(b"hello world");
452        let digest_again = hasher.finalize();
453        assert!(H::Digest::decode(digest_again.as_ref()).is_ok());
454        assert_eq!(digest, digest_again);
455
456        // Reuse hasher with reset
457        hasher.update(b"hello mars");
458        hasher.reset();
459        hasher.update(b"hello world");
460        let digest_reset = hasher.finalize();
461        assert!(H::Digest::decode(digest_reset.as_ref()).is_ok());
462        assert_eq!(digest, digest_reset);
463
464        // Hash different data
465        hasher.update(b"hello mars");
466        let digest_mars = hasher.finalize();
467        assert!(H::Digest::decode(digest_mars.as_ref()).is_ok());
468        assert_ne!(digest, digest_mars);
469    }
470
471    fn test_hasher_multiple_updates<H: Hasher>() {
472        // Generate initial hash
473        let mut hasher = H::new();
474        hasher.update(b"hello");
475        hasher.update(b" world");
476        let digest = hasher.finalize();
477        assert!(H::Digest::decode(digest.as_ref()).is_ok());
478
479        // Generate hash in oneshot
480        let mut hasher = H::new();
481        hasher.update(b"hello world");
482        let digest_oneshot = hasher.finalize();
483        assert!(H::Digest::decode(digest_oneshot.as_ref()).is_ok());
484        assert_eq!(digest, digest_oneshot);
485    }
486
487    fn test_hasher_empty_input<H: Hasher>() {
488        let mut hasher = H::new();
489        let digest = hasher.finalize();
490        assert!(H::Digest::decode(digest.as_ref()).is_ok());
491    }
492
493    fn test_hasher_large_input<H: Hasher>() {
494        let mut hasher = H::new();
495        let data = vec![1; 1024];
496        hasher.update(&data);
497        let digest = hasher.finalize();
498        assert!(H::Digest::decode(digest.as_ref()).is_ok());
499    }
500
501    #[test]
502    fn test_sha256_hasher_multiple_runs() {
503        test_hasher_multiple_runs::<Sha256>();
504    }
505
506    #[test]
507    fn test_sha256_hasher_multiple_updates() {
508        test_hasher_multiple_updates::<Sha256>();
509    }
510
511    #[test]
512    fn test_sha256_hasher_empty_input() {
513        test_hasher_empty_input::<Sha256>();
514    }
515
516    #[test]
517    fn test_sha256_hasher_large_input() {
518        test_hasher_large_input::<Sha256>();
519    }
520}