consensus_config/
crypto.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5//! Here we select the cryptographic types that are used by default in the code
6//! base. The whole code base should only:
7//! - refer to those aliases and not use the individual scheme implementations
8//! - not use the schemes in a way that break genericity (e.g. using their
9//!   Struct impl functions)
10//! - swap one of those aliases to point to another type if necessary
11//!
12//! Beware: if you change those aliases to point to another scheme
13//! implementation, you will have to change all four aliases to point to
14//! concrete types that work with each other. Failure to do so will result in a
15//! ton of compilation errors, and worse: it will not make sense!
16
17use fastcrypto::{
18    bls12381, ed25519,
19    error::FastCryptoError,
20    hash::{Blake2b256, HashFunction},
21    traits::{KeyPair as _, Signer as _, ToFromBytes as _, VerifyingKey as _},
22};
23use iota_sdk_types::crypto::INTENT_PREFIX_LENGTH;
24use serde::{Deserialize, Serialize};
25use tracing::instrument;
26
27/// Network key is used for TLS and as the network identity of the authority.
28#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
29pub struct NetworkPublicKey(ed25519::Ed25519PublicKey);
30pub struct NetworkPrivateKey(ed25519::Ed25519PrivateKey);
31pub struct NetworkKeyPair(ed25519::Ed25519KeyPair);
32
33impl NetworkPublicKey {
34    pub fn new(key: ed25519::Ed25519PublicKey) -> Self {
35        Self(key)
36    }
37
38    pub fn into_inner(self) -> ed25519::Ed25519PublicKey {
39        self.0
40    }
41
42    pub fn to_bytes(&self) -> [u8; 32] {
43        self.0.0.to_bytes()
44    }
45}
46
47impl NetworkPrivateKey {
48    pub fn into_inner(self) -> ed25519::Ed25519PrivateKey {
49        self.0
50    }
51}
52
53impl NetworkKeyPair {
54    pub fn new(keypair: ed25519::Ed25519KeyPair) -> Self {
55        Self(keypair)
56    }
57
58    pub fn generate<R: rand::Rng + fastcrypto::traits::AllowedRng>(rng: &mut R) -> Self {
59        Self(ed25519::Ed25519KeyPair::generate(rng))
60    }
61
62    pub fn public(&self) -> NetworkPublicKey {
63        NetworkPublicKey(self.0.public().clone())
64    }
65
66    pub fn private_key(self) -> NetworkPrivateKey {
67        NetworkPrivateKey(self.0.copy().private())
68    }
69
70    pub fn private_key_bytes(self) -> [u8; 32] {
71        self.0.private().0.to_bytes()
72    }
73}
74
75impl Clone for NetworkKeyPair {
76    fn clone(&self) -> Self {
77        Self(self.0.copy())
78    }
79}
80
81/// Protocol key is used for signing blocks and verifying block signatures.
82#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
83pub struct ProtocolPublicKey(ed25519::Ed25519PublicKey);
84pub struct ProtocolKeyPair(ed25519::Ed25519KeyPair);
85pub struct ProtocolKeySignature(ed25519::Ed25519Signature);
86
87impl ProtocolPublicKey {
88    pub fn new(key: ed25519::Ed25519PublicKey) -> Self {
89        Self(key)
90    }
91
92    #[instrument(level = "trace", skip_all)]
93    pub fn verify(
94        &self,
95        message: &[u8],
96        signature: &ProtocolKeySignature,
97    ) -> Result<(), FastCryptoError> {
98        self.0.verify(message, &signature.0)
99    }
100
101    pub fn to_bytes(&self) -> &[u8] {
102        self.0.as_bytes()
103    }
104}
105
106impl ProtocolKeyPair {
107    pub fn new(keypair: ed25519::Ed25519KeyPair) -> Self {
108        Self(keypair)
109    }
110
111    pub fn generate<R: rand::Rng + fastcrypto::traits::AllowedRng>(rng: &mut R) -> Self {
112        Self(ed25519::Ed25519KeyPair::generate(rng))
113    }
114
115    pub fn public(&self) -> ProtocolPublicKey {
116        ProtocolPublicKey(self.0.public().clone())
117    }
118
119    #[instrument(level = "trace", skip_all)]
120    pub fn sign(&self, message: &[u8]) -> ProtocolKeySignature {
121        ProtocolKeySignature(self.0.sign(message))
122    }
123}
124
125impl Clone for ProtocolKeyPair {
126    fn clone(&self) -> Self {
127        Self(self.0.copy())
128    }
129}
130
131impl ProtocolKeySignature {
132    pub fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
133        Ok(Self(ed25519::Ed25519Signature::from_bytes(bytes)?))
134    }
135
136    pub fn to_bytes(&self) -> &[u8] {
137        self.0.as_bytes()
138    }
139}
140
141/// Authority key represents the identity of an authority. It is only used for
142/// identity sanity checks and not used for verification.
143#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
144pub struct AuthorityPublicKey(bls12381::min_sig::BLS12381PublicKey);
145pub struct AuthorityKeyPair(bls12381::min_sig::BLS12381KeyPair);
146
147impl AuthorityPublicKey {
148    pub fn new(key: bls12381::min_sig::BLS12381PublicKey) -> Self {
149        Self(key)
150    }
151
152    pub fn inner(&self) -> &bls12381::min_sig::BLS12381PublicKey {
153        &self.0
154    }
155
156    pub fn to_bytes(&self) -> &[u8] {
157        self.0.as_bytes()
158    }
159}
160
161impl AuthorityKeyPair {
162    pub fn new(keypair: bls12381::min_sig::BLS12381KeyPair) -> Self {
163        Self(keypair)
164    }
165
166    pub fn generate<R: rand::Rng + fastcrypto::traits::AllowedRng>(rng: &mut R) -> Self {
167        Self(bls12381::min_sig::BLS12381KeyPair::generate(rng))
168    }
169
170    pub fn public(&self) -> AuthorityPublicKey {
171        AuthorityPublicKey(self.0.public().clone())
172    }
173}
174
175/// Defines algorithm and format of block and commit digests.
176pub type DefaultHashFunction = Blake2b256;
177pub const DIGEST_LENGTH: usize = DefaultHashFunction::OUTPUT_SIZE;
178pub const INTENT_MESSAGE_LENGTH: usize = INTENT_PREFIX_LENGTH + DIGEST_LENGTH;