iota_types/
crypto.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::{
6    collections::BTreeMap,
7    fmt::{self, Debug, Display, Formatter},
8    hash::{Hash, Hasher},
9    str::FromStr,
10};
11
12use anyhow::{Error, anyhow};
13use derive_more::{AsMut, AsRef, From};
14pub use enum_dispatch::enum_dispatch;
15use eyre::eyre;
16pub use fastcrypto::traits::{
17    AggregateAuthenticator, Authenticator, EncodeDecodeBase64, KeyPair as KeypairTraits, Signer,
18    SigningKey, ToFromBytes, VerifyingKey,
19};
20use fastcrypto::{
21    bls12381::min_sig::{
22        BLS12381AggregateSignature, BLS12381AggregateSignatureAsBytes, BLS12381KeyPair,
23        BLS12381PrivateKey, BLS12381PublicKey, BLS12381Signature,
24    },
25    ed25519::{
26        Ed25519KeyPair, Ed25519PrivateKey, Ed25519PublicKey, Ed25519PublicKeyAsBytes,
27        Ed25519Signature, Ed25519SignatureAsBytes,
28    },
29    encoding::{Base64, Bech32, Encoding, Hex},
30    error::{FastCryptoError, FastCryptoResult},
31    hash::{Blake2b256, HashFunction},
32    secp256k1::{
33        Secp256k1KeyPair, Secp256k1PublicKey, Secp256k1PublicKeyAsBytes, Secp256k1Signature,
34        Secp256k1SignatureAsBytes,
35    },
36    secp256r1::{
37        Secp256r1KeyPair, Secp256r1PublicKey, Secp256r1PublicKeyAsBytes, Secp256r1Signature,
38        Secp256r1SignatureAsBytes,
39    },
40};
41use fastcrypto_zkp::{bn254::zk_login::ZkLoginInputs, zk_login_utils::Bn254FrElement};
42use rand::{
43    SeedableRng,
44    rngs::{OsRng, StdRng},
45};
46use roaring::RoaringBitmap;
47use schemars::JsonSchema;
48use serde::{Deserialize, Deserializer, Serialize, ser::Serializer};
49use serde_with::{Bytes, serde_as};
50use shared_crypto::intent::{Intent, IntentMessage, IntentScope};
51use strum::EnumString;
52use tracing::{instrument, warn};
53
54use crate::{
55    base_types::{AuthorityName, ConciseableName, IotaAddress},
56    committee::{Committee, CommitteeTrait, EpochId, StakeUnit},
57    error::{IotaError, IotaResult},
58    iota_serde::{IotaBitmap, Readable},
59    signature::GenericSignature,
60};
61
62#[cfg(test)]
63#[path = "unit_tests/crypto_tests.rs"]
64mod crypto_tests;
65
66#[cfg(test)]
67#[path = "unit_tests/intent_tests.rs"]
68mod intent_tests;
69
70////////////////////////////////////////////////////////////////////////
71// Type aliases selecting the signature algorithm for the code base.
72////////////////////////////////////////////////////////////////////////
73// Here we select the types that are used by default in the code base.
74// The whole code base should only:
75// - refer to those aliases and not use the individual scheme implementations
76// - not use the schemes in a way that break genericity (e.g. using their Struct
77//   impl functions)
78// - swap one of those aliases to point to another type if necessary
79//
80// Beware: if you change those aliases to point to another scheme
81// implementation, you will have to change all related aliases to point to
82// concrete types that work with each other. Failure to do so will result in a
83// ton of compilation errors, and worse: it will not make sense!
84
85// Authority Objects
86pub type AuthorityKeyPair = BLS12381KeyPair;
87pub type AuthorityPublicKey = BLS12381PublicKey;
88pub type AuthorityPrivateKey = BLS12381PrivateKey;
89pub type AuthoritySignature = BLS12381Signature;
90pub type AggregateAuthoritySignature = BLS12381AggregateSignature;
91pub type AggregateAuthoritySignatureAsBytes = BLS12381AggregateSignatureAsBytes;
92
93// TODO(joyqvq): prefix these types with Default, DefaultAccountKeyPair etc
94pub type AccountKeyPair = Ed25519KeyPair;
95pub type AccountPublicKey = Ed25519PublicKey;
96pub type AccountPrivateKey = Ed25519PrivateKey;
97
98pub type NetworkKeyPair = Ed25519KeyPair;
99pub type NetworkPublicKey = Ed25519PublicKey;
100pub type NetworkPrivateKey = Ed25519PrivateKey;
101
102pub type DefaultHash = Blake2b256;
103
104pub const DEFAULT_EPOCH_ID: EpochId = 0;
105pub const IOTA_PRIV_KEY_PREFIX: &str = "iotaprivkey";
106
107/// Creates a proof of that the authority account address is owned by the
108/// holder of authority key, and also ensures that the authority
109/// public key exists. A proof of possession is an authority
110/// signature committed over the intent message `intent || message || epoch`
111/// (See more at [struct IntentMessage] and [struct Intent]) where the message
112/// is constructed as `authority_pubkey_bytes || authority_account_address`.
113pub fn generate_proof_of_possession(
114    keypair: &AuthorityKeyPair,
115    address: IotaAddress,
116) -> AuthoritySignature {
117    let mut msg: Vec<u8> = Vec::new();
118    msg.extend_from_slice(keypair.public().as_bytes());
119    msg.extend_from_slice(address.as_ref());
120    AuthoritySignature::new_secure(
121        &IntentMessage::new(Intent::iota_app(IntentScope::ProofOfPossession), msg),
122        &DEFAULT_EPOCH_ID,
123        keypair,
124    )
125}
126
127/// Verify proof of possession against the expected intent message,
128/// consisting of the authority pubkey and the authority account address.
129pub fn verify_proof_of_possession(
130    pop: &AuthoritySignature,
131    authority_pubkey: &AuthorityPublicKey,
132    iota_address: IotaAddress,
133) -> Result<(), IotaError> {
134    authority_pubkey
135        .validate()
136        .map_err(|_| IotaError::InvalidSignature {
137            error: "Fail to validate pubkey".to_string(),
138        })?;
139    let mut msg = authority_pubkey.as_bytes().to_vec();
140    msg.extend_from_slice(iota_address.as_ref());
141    pop.verify_secure(
142        &IntentMessage::new(Intent::iota_app(IntentScope::ProofOfPossession), msg),
143        DEFAULT_EPOCH_ID,
144        authority_pubkey.into(),
145    )
146}
147
148// Account Keys
149//
150// * The following section defines the keypairs that are used by
151// * accounts to interact with Iota.
152// * Currently we support eddsa and ecdsa on Iota.
153
154#[expect(clippy::large_enum_variant)]
155#[derive(Debug, From, PartialEq, Eq)]
156pub enum IotaKeyPair {
157    Ed25519(Ed25519KeyPair),
158    Secp256k1(Secp256k1KeyPair),
159    Secp256r1(Secp256r1KeyPair),
160}
161
162impl IotaKeyPair {
163    pub fn public(&self) -> PublicKey {
164        match self {
165            IotaKeyPair::Ed25519(kp) => PublicKey::Ed25519(kp.public().into()),
166            IotaKeyPair::Secp256k1(kp) => PublicKey::Secp256k1(kp.public().into()),
167            IotaKeyPair::Secp256r1(kp) => PublicKey::Secp256r1(kp.public().into()),
168        }
169    }
170}
171
172impl Clone for IotaKeyPair {
173    fn clone(&self) -> Self {
174        match self {
175            IotaKeyPair::Ed25519(kp) => kp.copy().into(),
176            IotaKeyPair::Secp256k1(kp) => kp.copy().into(),
177            IotaKeyPair::Secp256r1(kp) => kp.copy().into(),
178        }
179    }
180}
181
182impl Signer<Signature> for IotaKeyPair {
183    fn sign(&self, msg: &[u8]) -> Signature {
184        match self {
185            IotaKeyPair::Ed25519(kp) => kp.sign(msg),
186            IotaKeyPair::Secp256k1(kp) => kp.sign(msg),
187            IotaKeyPair::Secp256r1(kp) => kp.sign(msg),
188        }
189    }
190}
191
192impl EncodeDecodeBase64 for IotaKeyPair {
193    fn encode_base64(&self) -> String {
194        Base64::encode(self.to_bytes())
195    }
196
197    fn decode_base64(value: &str) -> FastCryptoResult<Self> {
198        let bytes = Base64::decode(value)?;
199        Self::from_bytes(&bytes).map_err(|_| FastCryptoError::InvalidInput)
200    }
201}
202
203impl IotaKeyPair {
204    pub fn to_bytes(&self) -> Vec<u8> {
205        let mut bytes: Vec<u8> = Vec::new();
206        bytes.push(self.public().flag());
207
208        match self {
209            IotaKeyPair::Ed25519(kp) => {
210                bytes.extend_from_slice(kp.as_bytes());
211            }
212            IotaKeyPair::Secp256k1(kp) => {
213                bytes.extend_from_slice(kp.as_bytes());
214            }
215            IotaKeyPair::Secp256r1(kp) => {
216                bytes.extend_from_slice(kp.as_bytes());
217            }
218        }
219        bytes
220    }
221
222    pub fn from_bytes(bytes: &[u8]) -> Result<Self, eyre::Report> {
223        match SignatureScheme::from_flag_byte(bytes.first().ok_or_else(|| eyre!("Invalid length"))?)
224        {
225            Ok(x) => match x {
226                SignatureScheme::ED25519 => Ok(IotaKeyPair::Ed25519(Ed25519KeyPair::from_bytes(
227                    bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
228                )?)),
229                SignatureScheme::Secp256k1 => {
230                    Ok(IotaKeyPair::Secp256k1(Secp256k1KeyPair::from_bytes(
231                        bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
232                    )?))
233                }
234                SignatureScheme::Secp256r1 => {
235                    Ok(IotaKeyPair::Secp256r1(Secp256r1KeyPair::from_bytes(
236                        bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
237                    )?))
238                }
239                _ => Err(eyre!("Invalid flag byte")),
240            },
241            _ => Err(eyre!("Invalid bytes")),
242        }
243    }
244
245    pub fn to_bytes_no_flag(&self) -> Vec<u8> {
246        match self {
247            IotaKeyPair::Ed25519(kp) => kp.as_bytes().to_vec(),
248            IotaKeyPair::Secp256k1(kp) => kp.as_bytes().to_vec(),
249            IotaKeyPair::Secp256r1(kp) => kp.as_bytes().to_vec(),
250        }
251    }
252
253    /// Encode a IotaKeyPair as `flag || privkey` in Bech32 starting with
254    /// "iotaprivkey" to a string. Note that the pubkey is not encoded.
255    pub fn encode(&self) -> Result<String, eyre::Report> {
256        Bech32::encode(self.to_bytes(), IOTA_PRIV_KEY_PREFIX).map_err(|e| eyre!(e))
257    }
258
259    /// Decode a IotaKeyPair from `flag || privkey` in Bech32 starting with
260    /// "iotaprivkey" to IotaKeyPair. The public key is computed directly from
261    /// the private key bytes.
262    pub fn decode(value: &str) -> Result<Self, eyre::Report> {
263        let bytes = Bech32::decode(value, IOTA_PRIV_KEY_PREFIX)?;
264        Self::from_bytes(&bytes)
265    }
266}
267
268impl Serialize for IotaKeyPair {
269    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
270    where
271        S: Serializer,
272    {
273        let s = self.encode_base64();
274        serializer.serialize_str(&s)
275    }
276}
277
278impl<'de> Deserialize<'de> for IotaKeyPair {
279    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
280    where
281        D: Deserializer<'de>,
282    {
283        use serde::de::Error;
284        let s = String::deserialize(deserializer)?;
285        IotaKeyPair::decode_base64(&s).map_err(|e| Error::custom(e.to_string()))
286    }
287}
288
289#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, Serialize, Deserialize)]
290pub enum PublicKey {
291    Ed25519(Ed25519PublicKeyAsBytes),
292    Secp256k1(Secp256k1PublicKeyAsBytes),
293    Secp256r1(Secp256r1PublicKeyAsBytes),
294    ZkLogin(ZkLoginPublicIdentifier),
295    Passkey(Secp256r1PublicKeyAsBytes),
296}
297
298/// A wrapper struct to retrofit in [enum PublicKey] for zkLogin.
299/// Useful to construct [struct MultiSigPublicKey].
300#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, Serialize, Deserialize)]
301pub struct ZkLoginPublicIdentifier(#[schemars(with = "Base64")] pub Vec<u8>);
302
303impl ZkLoginPublicIdentifier {
304    /// Consists of iss_bytes_len || iss_bytes || padded_32_byte_address_seed.
305    pub fn new(iss: &str, address_seed: &Bn254FrElement) -> IotaResult<Self> {
306        let mut bytes = Vec::new();
307        let iss_bytes = iss.as_bytes();
308        bytes.extend([iss_bytes.len() as u8]);
309        bytes.extend(iss_bytes);
310        bytes.extend(address_seed.padded());
311
312        Ok(Self(bytes))
313    }
314}
315impl AsRef<[u8]> for PublicKey {
316    fn as_ref(&self) -> &[u8] {
317        match self {
318            PublicKey::Ed25519(pk) => &pk.0,
319            PublicKey::Secp256k1(pk) => &pk.0,
320            PublicKey::Secp256r1(pk) => &pk.0,
321            PublicKey::ZkLogin(z) => &z.0,
322            PublicKey::Passkey(pk) => &pk.0,
323        }
324    }
325}
326
327impl EncodeDecodeBase64 for PublicKey {
328    fn encode_base64(&self) -> String {
329        let mut bytes: Vec<u8> = Vec::new();
330        bytes.extend_from_slice(&[self.flag()]);
331        bytes.extend_from_slice(self.as_ref());
332        Base64::encode(&bytes[..])
333    }
334
335    fn decode_base64(value: &str) -> FastCryptoResult<Self> {
336        let bytes = Base64::decode(value)?;
337        match bytes.first() {
338            Some(x) => {
339                if x == &SignatureScheme::ED25519.flag() {
340                    let pk: Ed25519PublicKey =
341                        Ed25519PublicKey::from_bytes(bytes.get(1..).ok_or(
342                            FastCryptoError::InputLengthWrong(Ed25519PublicKey::LENGTH + 1),
343                        )?)?;
344                    Ok(PublicKey::Ed25519((&pk).into()))
345                } else if x == &SignatureScheme::Secp256k1.flag() {
346                    let pk = Secp256k1PublicKey::from_bytes(bytes.get(1..).ok_or(
347                        FastCryptoError::InputLengthWrong(Secp256k1PublicKey::LENGTH + 1),
348                    )?)?;
349                    Ok(PublicKey::Secp256k1((&pk).into()))
350                } else if x == &SignatureScheme::Secp256r1.flag() {
351                    let pk = Secp256r1PublicKey::from_bytes(bytes.get(1..).ok_or(
352                        FastCryptoError::InputLengthWrong(Secp256r1PublicKey::LENGTH + 1),
353                    )?)?;
354                    Ok(PublicKey::Secp256r1((&pk).into()))
355                } else if x == &SignatureScheme::PasskeyAuthenticator.flag() {
356                    let pk = Secp256r1PublicKey::from_bytes(bytes.get(1..).ok_or(
357                        FastCryptoError::InputLengthWrong(Secp256r1PublicKey::LENGTH + 1),
358                    )?)?;
359                    Ok(PublicKey::Passkey((&pk).into()))
360                } else {
361                    Err(FastCryptoError::InvalidInput)
362                }
363            }
364            _ => Err(FastCryptoError::InvalidInput),
365        }
366    }
367}
368
369impl PublicKey {
370    pub fn flag(&self) -> u8 {
371        self.scheme().flag()
372    }
373
374    pub fn try_from_bytes(
375        curve: SignatureScheme,
376        key_bytes: &[u8],
377    ) -> Result<PublicKey, eyre::Report> {
378        match curve {
379            SignatureScheme::ED25519 => Ok(PublicKey::Ed25519(
380                (&Ed25519PublicKey::from_bytes(key_bytes)?).into(),
381            )),
382            SignatureScheme::Secp256k1 => Ok(PublicKey::Secp256k1(
383                (&Secp256k1PublicKey::from_bytes(key_bytes)?).into(),
384            )),
385            SignatureScheme::Secp256r1 => Ok(PublicKey::Secp256r1(
386                (&Secp256r1PublicKey::from_bytes(key_bytes)?).into(),
387            )),
388            SignatureScheme::PasskeyAuthenticator => Ok(PublicKey::Passkey(
389                (&Secp256r1PublicKey::from_bytes(key_bytes)?).into(),
390            )),
391            _ => Err(eyre!("Unsupported curve")),
392        }
393    }
394
395    pub fn scheme(&self) -> SignatureScheme {
396        match self {
397            PublicKey::Ed25519(_) => Ed25519IotaSignature::SCHEME,
398            PublicKey::Secp256k1(_) => Secp256k1IotaSignature::SCHEME,
399            PublicKey::Secp256r1(_) => Secp256r1IotaSignature::SCHEME,
400            PublicKey::ZkLogin(_) => SignatureScheme::ZkLoginAuthenticator,
401            PublicKey::Passkey(_) => SignatureScheme::PasskeyAuthenticator,
402        }
403    }
404
405    pub fn from_zklogin_inputs(inputs: &ZkLoginInputs) -> IotaResult<Self> {
406        Ok(PublicKey::ZkLogin(ZkLoginPublicIdentifier::new(
407            inputs.get_iss(),
408            inputs.get_address_seed(),
409        )?))
410    }
411}
412
413/// Defines the compressed version of the public key that we pass around
414/// in IOTA.
415#[serde_as]
416#[derive(
417    Copy,
418    Clone,
419    PartialEq,
420    Eq,
421    Hash,
422    PartialOrd,
423    Ord,
424    Serialize,
425    Deserialize,
426    schemars::JsonSchema,
427    AsRef,
428)]
429#[as_ref(forward)]
430pub struct AuthorityPublicKeyBytes(
431    #[schemars(with = "Base64")]
432    #[serde_as(as = "Readable<Base64, Bytes>")]
433    pub [u8; AuthorityPublicKey::LENGTH],
434);
435
436impl AuthorityPublicKeyBytes {
437    fn fmt_impl(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
438        let s = Hex::encode(self.0);
439        write!(f, "k#{s}")?;
440        Ok(())
441    }
442}
443
444impl<'a> ConciseableName<'a> for AuthorityPublicKeyBytes {
445    type ConciseTypeRef = ConciseAuthorityPublicKeyBytesRef<'a>;
446    type ConciseType = ConciseAuthorityPublicKeyBytes;
447
448    /// Get a ConciseAuthorityPublicKeyBytesRef. Usage:
449    ///
450    ///   debug!(name = ?authority.concise());
451    ///   format!("{:?}", authority.concise());
452    fn concise(&'a self) -> ConciseAuthorityPublicKeyBytesRef<'a> {
453        ConciseAuthorityPublicKeyBytesRef(self)
454    }
455
456    fn concise_owned(&self) -> ConciseAuthorityPublicKeyBytes {
457        ConciseAuthorityPublicKeyBytes(*self)
458    }
459}
460
461/// A wrapper around AuthorityPublicKeyBytes that provides a concise Debug impl.
462pub struct ConciseAuthorityPublicKeyBytesRef<'a>(&'a AuthorityPublicKeyBytes);
463
464impl Debug for ConciseAuthorityPublicKeyBytesRef<'_> {
465    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
466        let s = Hex::encode(self.0.0.get(0..4).ok_or(std::fmt::Error)?);
467        write!(f, "k#{s}..")
468    }
469}
470
471impl Display for ConciseAuthorityPublicKeyBytesRef<'_> {
472    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
473        Debug::fmt(self, f)
474    }
475}
476
477/// A wrapper around AuthorityPublicKeyBytes but owns it.
478#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, schemars::JsonSchema)]
479pub struct ConciseAuthorityPublicKeyBytes(AuthorityPublicKeyBytes);
480
481impl Debug for ConciseAuthorityPublicKeyBytes {
482    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
483        let s = Hex::encode(self.0.0.get(0..4).ok_or(std::fmt::Error)?);
484        write!(f, "k#{s}..")
485    }
486}
487
488impl Display for ConciseAuthorityPublicKeyBytes {
489    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
490        Debug::fmt(self, f)
491    }
492}
493
494impl TryFrom<AuthorityPublicKeyBytes> for AuthorityPublicKey {
495    type Error = FastCryptoError;
496
497    fn try_from(bytes: AuthorityPublicKeyBytes) -> Result<AuthorityPublicKey, Self::Error> {
498        AuthorityPublicKey::from_bytes(bytes.as_ref())
499    }
500}
501
502impl From<&AuthorityPublicKey> for AuthorityPublicKeyBytes {
503    fn from(pk: &AuthorityPublicKey) -> AuthorityPublicKeyBytes {
504        AuthorityPublicKeyBytes::from_bytes(pk.as_ref()).unwrap()
505    }
506}
507
508impl Debug for AuthorityPublicKeyBytes {
509    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
510        self.fmt_impl(f)
511    }
512}
513
514impl Display for AuthorityPublicKeyBytes {
515    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
516        self.fmt_impl(f)
517    }
518}
519
520impl ToFromBytes for AuthorityPublicKeyBytes {
521    fn from_bytes(bytes: &[u8]) -> Result<Self, fastcrypto::error::FastCryptoError> {
522        let bytes: [u8; AuthorityPublicKey::LENGTH] = bytes
523            .try_into()
524            .map_err(|_| fastcrypto::error::FastCryptoError::InvalidInput)?;
525        Ok(AuthorityPublicKeyBytes(bytes))
526    }
527}
528
529impl AuthorityPublicKeyBytes {
530    pub const ZERO: Self = Self::new([0u8; AuthorityPublicKey::LENGTH]);
531
532    /// This ensures it's impossible to construct an instance with other than
533    /// registered lengths
534    pub const fn new(bytes: [u8; AuthorityPublicKey::LENGTH]) -> AuthorityPublicKeyBytes
535where {
536        AuthorityPublicKeyBytes(bytes)
537    }
538}
539
540impl FromStr for AuthorityPublicKeyBytes {
541    type Err = Error;
542
543    fn from_str(s: &str) -> Result<Self, Self::Err> {
544        let value = Hex::decode(s).map_err(|e| anyhow!(e))?;
545        Self::from_bytes(&value[..]).map_err(|e| anyhow!(e))
546    }
547}
548
549impl Default for AuthorityPublicKeyBytes {
550    fn default() -> Self {
551        Self::ZERO
552    }
553}
554
555// Add helper calls for Authority Signature
556//
557
558pub trait IotaAuthoritySignature {
559    fn verify_secure<T>(
560        &self,
561        value: &IntentMessage<T>,
562        epoch_id: EpochId,
563        author: AuthorityPublicKeyBytes,
564    ) -> Result<(), IotaError>
565    where
566        T: Serialize;
567
568    fn new_secure<T>(
569        value: &IntentMessage<T>,
570        epoch_id: &EpochId,
571        secret: &dyn Signer<Self>,
572    ) -> Self
573    where
574        T: Serialize;
575}
576
577impl IotaAuthoritySignature for AuthoritySignature {
578    #[instrument(level = "trace", skip_all)]
579    fn new_secure<T>(value: &IntentMessage<T>, epoch: &EpochId, secret: &dyn Signer<Self>) -> Self
580    where
581        T: Serialize,
582    {
583        let mut intent_msg_bytes =
584            bcs::to_bytes(&value).expect("Message serialization should not fail");
585        epoch.write(&mut intent_msg_bytes);
586        secret.sign(&intent_msg_bytes)
587    }
588
589    #[instrument(level = "trace", skip_all)]
590    fn verify_secure<T>(
591        &self,
592        value: &IntentMessage<T>,
593        epoch: EpochId,
594        author: AuthorityPublicKeyBytes,
595    ) -> Result<(), IotaError>
596    where
597        T: Serialize,
598    {
599        let mut message = bcs::to_bytes(&value).expect("Message serialization should not fail");
600        epoch.write(&mut message);
601
602        let public_key = AuthorityPublicKey::try_from(author).map_err(|_| {
603            IotaError::KeyConversion(
604                "Failed to serialize public key bytes to valid public key".to_string(),
605            )
606        })?;
607        public_key
608            .verify(&message[..], self)
609            .map_err(|e| IotaError::InvalidSignature {
610                error: format!(
611                    "Fail to verify auth sig {} epoch: {} author: {}",
612                    e,
613                    epoch,
614                    author.concise()
615                ),
616            })
617    }
618}
619
620// TODO: get_key_pair() and get_key_pair_from_bytes() should return KeyPair
621// only. TODO: rename to random_key_pair
622pub fn get_key_pair<KP: KeypairTraits>() -> (IotaAddress, KP)
623where
624    <KP as KeypairTraits>::PubKey: IotaPublicKey,
625{
626    get_key_pair_from_rng(&mut OsRng)
627}
628
629/// Generate a random committee key pairs with a given committee size
630pub fn random_committee_key_pairs_of_size(size: usize) -> Vec<AuthorityKeyPair> {
631    let mut rng = StdRng::from_seed([0; 32]);
632    (0..size)
633        .map(|_| {
634            // TODO: We are generating the keys 4 times to match exactly as how we generate
635            // keys in ConfigBuilder::build (iota-config/src/network_config_builder). This
636            // is because we are using these key generation functions as
637            // fixtures and we call them independently in different paths and
638            // exact the results to be the same. We should eliminate them.
639            let key_pair = get_key_pair_from_rng::<AuthorityKeyPair, _>(&mut rng);
640            get_key_pair_from_rng::<AuthorityKeyPair, _>(&mut rng);
641            get_key_pair_from_rng::<AccountKeyPair, _>(&mut rng);
642            get_key_pair_from_rng::<AccountKeyPair, _>(&mut rng);
643            key_pair.1
644        })
645        .collect()
646}
647
648pub fn deterministic_random_account_key() -> (IotaAddress, AccountKeyPair) {
649    let mut rng = StdRng::from_seed([0; 32]);
650    get_key_pair_from_rng(&mut rng)
651}
652
653pub fn get_account_key_pair() -> (IotaAddress, AccountKeyPair) {
654    get_key_pair()
655}
656
657pub fn get_authority_key_pair() -> (IotaAddress, AuthorityKeyPair) {
658    get_key_pair()
659}
660
661/// Generate a keypair from the specified RNG (useful for testing with seedable
662/// rngs).
663pub fn get_key_pair_from_rng<KP: KeypairTraits, R>(csprng: &mut R) -> (IotaAddress, KP)
664where
665    R: rand::CryptoRng + rand::RngCore,
666    <KP as KeypairTraits>::PubKey: IotaPublicKey,
667{
668    let kp = KP::generate(&mut StdRng::from_rng(csprng).unwrap());
669    (kp.public().into(), kp)
670}
671
672// TODO: C-GETTER
673pub fn get_key_pair_from_bytes<KP: KeypairTraits>(bytes: &[u8]) -> IotaResult<(IotaAddress, KP)>
674where
675    <KP as KeypairTraits>::PubKey: IotaPublicKey,
676{
677    let priv_length = <KP as KeypairTraits>::PrivKey::LENGTH;
678    let pub_key_length = <KP as KeypairTraits>::PubKey::LENGTH;
679    if bytes.len() != priv_length + pub_key_length {
680        return Err(IotaError::KeyConversion(format!(
681            "Invalid input byte length, expected {}: {}",
682            priv_length,
683            bytes.len()
684        )));
685    }
686    let sk = <KP as KeypairTraits>::PrivKey::from_bytes(
687        bytes
688            .get(..priv_length)
689            .ok_or(IotaError::InvalidPrivateKey)?,
690    )
691    .map_err(|_| IotaError::InvalidPrivateKey)?;
692    let kp: KP = sk.into();
693    Ok((kp.public().into(), kp))
694}
695
696// Account Signatures
697//
698
699// Enums for signature scheme signatures
700#[enum_dispatch]
701#[derive(Clone, JsonSchema, Debug, PartialEq, Eq, Hash)]
702pub enum Signature {
703    Ed25519IotaSignature,
704    Secp256k1IotaSignature,
705    Secp256r1IotaSignature,
706}
707
708impl Serialize for Signature {
709    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
710    where
711        S: Serializer,
712    {
713        let bytes = self.as_ref();
714
715        if serializer.is_human_readable() {
716            let s = Base64::encode(bytes);
717            serializer.serialize_str(&s)
718        } else {
719            serializer.serialize_bytes(bytes)
720        }
721    }
722}
723
724impl<'de> Deserialize<'de> for Signature {
725    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
726    where
727        D: Deserializer<'de>,
728    {
729        use serde::de::Error;
730
731        let bytes = if deserializer.is_human_readable() {
732            let s = String::deserialize(deserializer)?;
733            Base64::decode(&s).map_err(|e| Error::custom(e.to_string()))?
734        } else {
735            let data: Vec<u8> = Vec::deserialize(deserializer)?;
736            data
737        };
738
739        Self::from_bytes(&bytes).map_err(|e| Error::custom(e.to_string()))
740    }
741}
742
743impl Signature {
744    /// The messaged passed in is already hashed form.
745    pub fn new_hashed(hashed_msg: &[u8], secret: &dyn Signer<Signature>) -> Self {
746        Signer::sign(secret, hashed_msg)
747    }
748
749    pub fn new_secure<T>(value: &IntentMessage<T>, secret: &dyn Signer<Signature>) -> Self
750    where
751        T: Serialize,
752    {
753        // Compute the BCS hash of the value in intent message. In the case of
754        // transaction data, this is the BCS hash of `struct TransactionData`,
755        // different from the transaction digest itself that computes the BCS
756        // hash of the Rust type prefix and `struct TransactionData`.
757        // (See `fn digest` in `impl Message for SenderSignedData`).
758        let mut hasher = DefaultHash::default();
759        hasher.update(bcs::to_bytes(&value).expect("Message serialization should not fail"));
760
761        Signer::sign(secret, &hasher.finalize().digest)
762    }
763}
764
765impl AsRef<[u8]> for Signature {
766    fn as_ref(&self) -> &[u8] {
767        match self {
768            Signature::Ed25519IotaSignature(sig) => sig.as_ref(),
769            Signature::Secp256k1IotaSignature(sig) => sig.as_ref(),
770            Signature::Secp256r1IotaSignature(sig) => sig.as_ref(),
771        }
772    }
773}
774impl AsMut<[u8]> for Signature {
775    fn as_mut(&mut self) -> &mut [u8] {
776        match self {
777            Signature::Ed25519IotaSignature(sig) => sig.as_mut(),
778            Signature::Secp256k1IotaSignature(sig) => sig.as_mut(),
779            Signature::Secp256r1IotaSignature(sig) => sig.as_mut(),
780        }
781    }
782}
783
784impl ToFromBytes for Signature {
785    fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
786        match bytes.first() {
787            Some(x) => {
788                if x == &Ed25519IotaSignature::SCHEME.flag() {
789                    Ok(<Ed25519IotaSignature as ToFromBytes>::from_bytes(bytes)?.into())
790                } else if x == &Secp256k1IotaSignature::SCHEME.flag() {
791                    Ok(<Secp256k1IotaSignature as ToFromBytes>::from_bytes(bytes)?.into())
792                } else if x == &Secp256r1IotaSignature::SCHEME.flag() {
793                    Ok(<Secp256r1IotaSignature as ToFromBytes>::from_bytes(bytes)?.into())
794                } else {
795                    Err(FastCryptoError::InvalidInput)
796                }
797            }
798            _ => Err(FastCryptoError::InvalidInput),
799        }
800    }
801}
802
803// BLS Port
804//
805
806impl IotaPublicKey for BLS12381PublicKey {
807    const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::BLS12381;
808}
809
810// Ed25519 Iota Signature port
811//
812
813#[serde_as]
814#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, AsRef, AsMut)]
815#[as_ref(forward)]
816#[as_mut(forward)]
817pub struct Ed25519IotaSignature(
818    #[schemars(with = "Base64")]
819    #[serde_as(as = "Readable<Base64, Bytes>")]
820    [u8; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1],
821);
822
823// Implementation useful for simplify testing when mock signature is needed
824impl Default for Ed25519IotaSignature {
825    fn default() -> Self {
826        Self([0; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1])
827    }
828}
829
830impl IotaSignatureInner for Ed25519IotaSignature {
831    type Sig = Ed25519Signature;
832    type PubKey = Ed25519PublicKey;
833    type KeyPair = Ed25519KeyPair;
834    const LENGTH: usize = Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1;
835}
836
837impl IotaPublicKey for Ed25519PublicKey {
838    const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::ED25519;
839}
840
841impl ToFromBytes for Ed25519IotaSignature {
842    fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
843        if bytes.len() != Self::LENGTH {
844            return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
845        }
846        let mut sig_bytes = [0; Self::LENGTH];
847        sig_bytes.copy_from_slice(bytes);
848        Ok(Self(sig_bytes))
849    }
850}
851
852impl Signer<Signature> for Ed25519KeyPair {
853    fn sign(&self, msg: &[u8]) -> Signature {
854        Ed25519IotaSignature::new(self, msg).into()
855    }
856}
857
858// Secp256k1 Iota Signature port
859//
860#[serde_as]
861#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, AsRef, AsMut)]
862#[as_ref(forward)]
863#[as_mut(forward)]
864pub struct Secp256k1IotaSignature(
865    #[schemars(with = "Base64")]
866    #[serde_as(as = "Readable<Base64, Bytes>")]
867    [u8; Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1],
868);
869
870impl IotaSignatureInner for Secp256k1IotaSignature {
871    type Sig = Secp256k1Signature;
872    type PubKey = Secp256k1PublicKey;
873    type KeyPair = Secp256k1KeyPair;
874    const LENGTH: usize = Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1;
875}
876
877impl IotaPublicKey for Secp256k1PublicKey {
878    const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256k1;
879}
880
881impl ToFromBytes for Secp256k1IotaSignature {
882    fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
883        if bytes.len() != Self::LENGTH {
884            return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
885        }
886        let mut sig_bytes = [0; Self::LENGTH];
887        sig_bytes.copy_from_slice(bytes);
888        Ok(Self(sig_bytes))
889    }
890}
891
892impl Signer<Signature> for Secp256k1KeyPair {
893    fn sign(&self, msg: &[u8]) -> Signature {
894        Secp256k1IotaSignature::new(self, msg).into()
895    }
896}
897
898// Secp256r1 Iota Signature port
899//
900#[serde_as]
901#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq, Hash, AsRef, AsMut)]
902#[as_ref(forward)]
903#[as_mut(forward)]
904pub struct Secp256r1IotaSignature(
905    #[schemars(with = "Base64")]
906    #[serde_as(as = "Readable<Base64, Bytes>")]
907    [u8; Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1],
908);
909
910impl IotaSignatureInner for Secp256r1IotaSignature {
911    type Sig = Secp256r1Signature;
912    type PubKey = Secp256r1PublicKey;
913    type KeyPair = Secp256r1KeyPair;
914    const LENGTH: usize = Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1;
915}
916
917impl IotaPublicKey for Secp256r1PublicKey {
918    const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256r1;
919}
920
921impl ToFromBytes for Secp256r1IotaSignature {
922    fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
923        if bytes.len() != Self::LENGTH {
924            return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
925        }
926        let mut sig_bytes = [0; Self::LENGTH];
927        sig_bytes.copy_from_slice(bytes);
928        Ok(Self(sig_bytes))
929    }
930}
931
932impl Signer<Signature> for Secp256r1KeyPair {
933    fn sign(&self, msg: &[u8]) -> Signature {
934        Secp256r1IotaSignature::new(self, msg).into()
935    }
936}
937
938// This struct exists due to the limitations of the `enum_dispatch` library.
939//
940pub trait IotaSignatureInner: Sized + ToFromBytes + PartialEq + Eq + Hash {
941    type Sig: Authenticator<PubKey = Self::PubKey>;
942    type PubKey: VerifyingKey<Sig = Self::Sig> + IotaPublicKey;
943    type KeyPair: KeypairTraits<PubKey = Self::PubKey, Sig = Self::Sig>;
944
945    const LENGTH: usize = Self::Sig::LENGTH + Self::PubKey::LENGTH + 1;
946    const SCHEME: SignatureScheme = Self::PubKey::SIGNATURE_SCHEME;
947
948    /// Returns the deserialized signature and deserialized pubkey.
949    fn get_verification_inputs(&self) -> IotaResult<(Self::Sig, Self::PubKey)> {
950        let pk = Self::PubKey::from_bytes(self.public_key_bytes())
951            .map_err(|_| IotaError::KeyConversion("Invalid public key".to_string()))?;
952
953        // deserialize the signature
954        let signature = Self::Sig::from_bytes(self.signature_bytes()).map_err(|_| {
955            IotaError::InvalidSignature {
956                error: "Fail to get pubkey and sig".to_string(),
957            }
958        })?;
959
960        Ok((signature, pk))
961    }
962
963    fn new(kp: &Self::KeyPair, message: &[u8]) -> Self {
964        let sig = Signer::sign(kp, message);
965
966        let mut signature_bytes: Vec<u8> = Vec::new();
967        signature_bytes
968            .extend_from_slice(&[<Self::PubKey as IotaPublicKey>::SIGNATURE_SCHEME.flag()]);
969        signature_bytes.extend_from_slice(sig.as_ref());
970        signature_bytes.extend_from_slice(kp.public().as_ref());
971        Self::from_bytes(&signature_bytes[..])
972            .expect("Serialized signature did not have expected size")
973    }
974}
975
976pub trait IotaPublicKey: VerifyingKey {
977    const SIGNATURE_SCHEME: SignatureScheme;
978}
979
980#[enum_dispatch(Signature)]
981pub trait IotaSignature: Sized + ToFromBytes {
982    fn signature_bytes(&self) -> &[u8];
983    fn public_key_bytes(&self) -> &[u8];
984    fn scheme(&self) -> SignatureScheme;
985
986    fn verify_secure<T>(
987        &self,
988        value: &IntentMessage<T>,
989        author: IotaAddress,
990        scheme: SignatureScheme,
991    ) -> IotaResult<()>
992    where
993        T: Serialize;
994}
995
996impl<S: IotaSignatureInner + Sized> IotaSignature for S {
997    fn signature_bytes(&self) -> &[u8] {
998        // Access array slice is safe because the array bytes is initialized as
999        // flag || signature || pubkey with its defined length.
1000        &self.as_ref()[1..1 + S::Sig::LENGTH]
1001    }
1002
1003    fn public_key_bytes(&self) -> &[u8] {
1004        // Access array slice is safe because the array bytes is initialized as
1005        // flag || signature || pubkey with its defined length.
1006        &self.as_ref()[S::Sig::LENGTH + 1..]
1007    }
1008
1009    fn scheme(&self) -> SignatureScheme {
1010        S::PubKey::SIGNATURE_SCHEME
1011    }
1012
1013    fn verify_secure<T>(
1014        &self,
1015        value: &IntentMessage<T>,
1016        author: IotaAddress,
1017        scheme: SignatureScheme,
1018    ) -> Result<(), IotaError>
1019    where
1020        T: Serialize,
1021    {
1022        let mut hasher = DefaultHash::default();
1023        hasher.update(bcs::to_bytes(&value).expect("Message serialization should not fail"));
1024        let digest = hasher.finalize().digest;
1025
1026        let (sig, pk) = &self.get_verification_inputs()?;
1027        match scheme {
1028            SignatureScheme::ZkLoginAuthenticator => {} // Pass this check because zk login does
1029            // not derive address from pubkey.
1030            _ => {
1031                let address = IotaAddress::from(pk);
1032                if author != address {
1033                    return Err(IotaError::IncorrectSigner {
1034                        error: format!("Incorrect signer, expected {author:?}, got {address:?}"),
1035                    });
1036                }
1037            }
1038        }
1039
1040        pk.verify(&digest, sig)
1041            .map_err(|e| IotaError::InvalidSignature {
1042                error: format!("Fail to verify user sig {e}"),
1043            })
1044    }
1045}
1046
1047/// AuthoritySignInfoTrait is a trait used specifically for a few structs in
1048/// messages.rs to template on whether the struct is signed by an authority. We
1049/// want to limit how those structs can be instantiated on, hence the sealed
1050/// trait. TODO: We could also add the aggregated signature as another impl of
1051/// the trait.       This will make CertifiedTransaction also an instance of the
1052/// same struct.
1053pub trait AuthoritySignInfoTrait: private::SealedAuthoritySignInfoTrait {
1054    fn verify_secure<T: Serialize>(
1055        &self,
1056        data: &T,
1057        intent: Intent,
1058        committee: &Committee,
1059    ) -> IotaResult;
1060
1061    fn add_to_verification_obligation<'a>(
1062        &self,
1063        committee: &'a Committee,
1064        obligation: &mut VerificationObligation<'a>,
1065        message_index: usize,
1066    ) -> IotaResult<()>;
1067}
1068
1069#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
1070pub struct EmptySignInfo {}
1071impl AuthoritySignInfoTrait for EmptySignInfo {
1072    fn verify_secure<T: Serialize>(
1073        &self,
1074        _data: &T,
1075        _intent: Intent,
1076        _committee: &Committee,
1077    ) -> IotaResult {
1078        Ok(())
1079    }
1080
1081    fn add_to_verification_obligation<'a>(
1082        &self,
1083        _committee: &'a Committee,
1084        _obligation: &mut VerificationObligation<'a>,
1085        _message_index: usize,
1086    ) -> IotaResult<()> {
1087        Ok(())
1088    }
1089}
1090
1091#[derive(Clone, Debug, Eq, Serialize, Deserialize)]
1092pub struct AuthoritySignInfo {
1093    pub epoch: EpochId,
1094    pub authority: AuthorityName,
1095    pub signature: AuthoritySignature,
1096}
1097
1098impl AuthoritySignInfoTrait for AuthoritySignInfo {
1099    fn verify_secure<T: Serialize>(
1100        &self,
1101        data: &T,
1102        intent: Intent,
1103        committee: &Committee,
1104    ) -> IotaResult<()> {
1105        let mut obligation = VerificationObligation::default();
1106        let idx = obligation.add_message(data, self.epoch, intent);
1107        self.add_to_verification_obligation(committee, &mut obligation, idx)?;
1108        obligation.verify_all()?;
1109        Ok(())
1110    }
1111
1112    fn add_to_verification_obligation<'a>(
1113        &self,
1114        committee: &'a Committee,
1115        obligation: &mut VerificationObligation<'a>,
1116        message_index: usize,
1117    ) -> IotaResult<()> {
1118        fp_ensure!(
1119            self.epoch == committee.epoch(),
1120            IotaError::WrongEpoch {
1121                expected_epoch: committee.epoch(),
1122                actual_epoch: self.epoch,
1123            }
1124        );
1125        let weight = committee.weight(&self.authority);
1126        fp_ensure!(
1127            weight > 0,
1128            IotaError::UnknownSigner {
1129                signer: Some(self.authority.concise().to_string()),
1130                index: None,
1131                committee: Box::new(committee.clone())
1132            }
1133        );
1134
1135        obligation
1136            .public_keys
1137            .get_mut(message_index)
1138            .ok_or(IotaError::InvalidAddress)?
1139            .push(committee.public_key(&self.authority)?);
1140        obligation
1141            .signatures
1142            .get_mut(message_index)
1143            .ok_or(IotaError::InvalidAddress)?
1144            .add_signature(self.signature.clone())
1145            .map_err(|_| IotaError::InvalidSignature {
1146                error: "Fail to aggregator auth sig".to_string(),
1147            })?;
1148        Ok(())
1149    }
1150}
1151
1152impl AuthoritySignInfo {
1153    pub fn new<T>(
1154        epoch: EpochId,
1155        value: &T,
1156        intent: Intent,
1157        name: AuthorityName,
1158        secret: &dyn Signer<AuthoritySignature>,
1159    ) -> Self
1160    where
1161        T: Serialize,
1162    {
1163        Self {
1164            epoch,
1165            authority: name,
1166            signature: AuthoritySignature::new_secure(
1167                &IntentMessage::new(intent, value),
1168                &epoch,
1169                secret,
1170            ),
1171        }
1172    }
1173}
1174
1175impl Hash for AuthoritySignInfo {
1176    fn hash<H: Hasher>(&self, state: &mut H) {
1177        self.epoch.hash(state);
1178        self.authority.hash(state);
1179    }
1180}
1181
1182impl Display for AuthoritySignInfo {
1183    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1184        write!(
1185            f,
1186            "AuthoritySignInfo {{ epoch: {:?}, authority: {} }}",
1187            self.epoch, self.authority,
1188        )
1189    }
1190}
1191
1192impl PartialEq for AuthoritySignInfo {
1193    fn eq(&self, other: &Self) -> bool {
1194        // We do not compare the signature, because there can be multiple
1195        // valid signatures for the same epoch and authority.
1196        self.epoch == other.epoch && self.authority == other.authority
1197    }
1198}
1199
1200/// Represents at least a quorum (could be more) of authority signatures.
1201/// STRONG_THRESHOLD indicates whether to use the quorum threshold for quorum
1202/// check. When STRONG_THRESHOLD is true, the quorum is valid when the total
1203/// stake is at least the quorum threshold (2f+1) of the committee; when
1204/// STRONG_THRESHOLD is false, the quorum is valid when the total stake is at
1205/// least the validity threshold (f+1) of the committee.
1206#[serde_as]
1207#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1208pub struct AuthorityQuorumSignInfo<const STRONG_THRESHOLD: bool> {
1209    pub epoch: EpochId,
1210    #[schemars(with = "Base64")]
1211    pub signature: AggregateAuthoritySignature,
1212    #[schemars(with = "Base64")]
1213    #[serde_as(as = "IotaBitmap")]
1214    pub signers_map: RoaringBitmap,
1215}
1216
1217pub type AuthorityStrongQuorumSignInfo = AuthorityQuorumSignInfo<true>;
1218
1219// Variant of [AuthorityStrongQuorumSignInfo] but with a serialized signature,
1220// to be used in external APIs.
1221#[serde_as]
1222#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
1223pub struct IotaAuthorityStrongQuorumSignInfo {
1224    pub epoch: EpochId,
1225    pub signature: AggregateAuthoritySignatureAsBytes,
1226    #[schemars(with = "Base64")]
1227    #[serde_as(as = "IotaBitmap")]
1228    pub signers_map: RoaringBitmap,
1229}
1230
1231impl From<&AuthorityStrongQuorumSignInfo> for IotaAuthorityStrongQuorumSignInfo {
1232    fn from(info: &AuthorityStrongQuorumSignInfo) -> Self {
1233        Self {
1234            epoch: info.epoch,
1235            signature: (&info.signature).into(),
1236            signers_map: info.signers_map.clone(),
1237        }
1238    }
1239}
1240
1241impl TryFrom<&IotaAuthorityStrongQuorumSignInfo> for AuthorityStrongQuorumSignInfo {
1242    type Error = FastCryptoError;
1243
1244    fn try_from(info: &IotaAuthorityStrongQuorumSignInfo) -> Result<Self, Self::Error> {
1245        Ok(Self {
1246            epoch: info.epoch,
1247            signature: (&info.signature).try_into()?,
1248            signers_map: info.signers_map.clone(),
1249        })
1250    }
1251}
1252
1253// Note: if you meet an error due to this line it may be because you need an Eq
1254// implementation for `CertifiedTransaction`, or one of the structs that include
1255// it, i.e. `ConfirmationTransaction`, `TransactionInfoResponse` or
1256// `ObjectInfoResponse`.
1257//
1258// Please note that any such implementation must be agnostic to the exact set of
1259// signatures in the certificate, as clients are allowed to equivocate on the
1260// exact nature of valid certificates they send to the system. This assertion is
1261// a simple tool to make sure certificates are accounted for correctly - should
1262// you remove it, you're on your own to maintain the invariant that valid
1263// certificates with distinct signatures are equivalent, but yet-unchecked
1264// certificates that differ on signers aren't.
1265//
1266// see also https://github.com/iotaledger/iota/issues/266
1267static_assertions::assert_not_impl_any!(AuthorityStrongQuorumSignInfo: Hash, Eq, PartialEq);
1268
1269impl<const STRONG_THRESHOLD: bool> AuthoritySignInfoTrait
1270    for AuthorityQuorumSignInfo<STRONG_THRESHOLD>
1271{
1272    fn verify_secure<T: Serialize>(
1273        &self,
1274        data: &T,
1275        intent: Intent,
1276        committee: &Committee,
1277    ) -> IotaResult {
1278        let mut obligation = VerificationObligation::default();
1279        let idx = obligation.add_message(data, self.epoch, intent);
1280        self.add_to_verification_obligation(committee, &mut obligation, idx)?;
1281        obligation.verify_all()?;
1282        Ok(())
1283    }
1284
1285    fn add_to_verification_obligation<'a>(
1286        &self,
1287        committee: &'a Committee,
1288        obligation: &mut VerificationObligation<'a>,
1289        message_index: usize,
1290    ) -> IotaResult<()> {
1291        // Check epoch
1292        fp_ensure!(
1293            self.epoch == committee.epoch(),
1294            IotaError::WrongEpoch {
1295                expected_epoch: committee.epoch(),
1296                actual_epoch: self.epoch,
1297            }
1298        );
1299
1300        let mut weight = 0;
1301
1302        // Create obligations for the committee signatures
1303        obligation
1304            .signatures
1305            .get_mut(message_index)
1306            .ok_or(IotaError::InvalidAuthenticator)?
1307            .add_aggregate(self.signature.clone())
1308            .map_err(|_| IotaError::InvalidSignature {
1309                error: "Signature Aggregation failed".to_string(),
1310            })?;
1311
1312        let selected_public_keys = obligation
1313            .public_keys
1314            .get_mut(message_index)
1315            .ok_or(IotaError::InvalidAuthenticator)?;
1316
1317        for authority_index in self.signers_map.iter() {
1318            let authority = committee
1319                .authority_by_index(authority_index)
1320                .ok_or_else(|| IotaError::UnknownSigner {
1321                    signer: None,
1322                    index: Some(authority_index),
1323                    committee: Box::new(committee.clone()),
1324                })?;
1325
1326            // Update weight.
1327            let voting_rights = committee.weight(authority);
1328            fp_ensure!(
1329                voting_rights > 0,
1330                IotaError::UnknownSigner {
1331                    signer: Some(authority.concise().to_string()),
1332                    index: Some(authority_index),
1333                    committee: Box::new(committee.clone()),
1334                }
1335            );
1336            weight += voting_rights;
1337
1338            selected_public_keys.push(committee.public_key(authority)?);
1339        }
1340
1341        fp_ensure!(
1342            weight >= Self::quorum_threshold(committee),
1343            IotaError::CertificateRequiresQuorum
1344        );
1345
1346        Ok(())
1347    }
1348}
1349
1350impl<const STRONG_THRESHOLD: bool> AuthorityQuorumSignInfo<STRONG_THRESHOLD> {
1351    pub fn new_from_auth_sign_infos(
1352        auth_sign_infos: Vec<AuthoritySignInfo>,
1353        committee: &Committee,
1354    ) -> IotaResult<Self> {
1355        fp_ensure!(
1356            auth_sign_infos.iter().all(|a| a.epoch == committee.epoch),
1357            IotaError::InvalidSignature {
1358                error: "All signatures must be from the same epoch as the committee".to_string()
1359            }
1360        );
1361        let total_stake: StakeUnit = auth_sign_infos
1362            .iter()
1363            .map(|a| committee.weight(&a.authority))
1364            .sum();
1365        fp_ensure!(
1366            total_stake >= Self::quorum_threshold(committee),
1367            IotaError::InvalidSignature {
1368                error: "Signatures don't have enough stake to form a quorum".to_string()
1369            }
1370        );
1371
1372        let signatures: BTreeMap<_, _> = auth_sign_infos
1373            .into_iter()
1374            .map(|a| (a.authority, a.signature))
1375            .collect();
1376        let mut map = RoaringBitmap::new();
1377        for pk in signatures.keys() {
1378            map.insert(
1379                committee
1380                    .authority_index(pk)
1381                    .ok_or_else(|| IotaError::UnknownSigner {
1382                        signer: Some(pk.concise().to_string()),
1383                        index: None,
1384                        committee: Box::new(committee.clone()),
1385                    })?,
1386            );
1387        }
1388        let sigs: Vec<AuthoritySignature> = signatures.into_values().collect();
1389
1390        Ok(AuthorityQuorumSignInfo {
1391            epoch: committee.epoch,
1392            signature: AggregateAuthoritySignature::aggregate(&sigs).map_err(|e| {
1393                IotaError::InvalidSignature {
1394                    error: e.to_string(),
1395                }
1396            })?,
1397            signers_map: map,
1398        })
1399    }
1400
1401    pub fn authorities<'a>(
1402        &'a self,
1403        committee: &'a Committee,
1404    ) -> impl Iterator<Item = IotaResult<&'a AuthorityName>> {
1405        self.signers_map.iter().map(|i| {
1406            committee
1407                .authority_by_index(i)
1408                .ok_or(IotaError::InvalidAuthenticator)
1409        })
1410    }
1411
1412    pub fn quorum_threshold(committee: &Committee) -> StakeUnit {
1413        committee.threshold::<STRONG_THRESHOLD>()
1414    }
1415
1416    pub fn len(&self) -> u64 {
1417        self.signers_map.len()
1418    }
1419
1420    pub fn is_empty(&self) -> bool {
1421        self.signers_map.is_empty()
1422    }
1423}
1424
1425impl<const S: bool> Display for AuthorityQuorumSignInfo<S> {
1426    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1427        writeln!(
1428            f,
1429            "{} {{ epoch: {:?}, signers_map: {:?} }}",
1430            if S {
1431                "AuthorityStrongQuorumSignInfo"
1432            } else {
1433                "AuthorityWeakQuorumSignInfo"
1434            },
1435            self.epoch,
1436            self.signers_map,
1437        )?;
1438        Ok(())
1439    }
1440}
1441
1442mod private {
1443    pub trait SealedAuthoritySignInfoTrait {}
1444    impl SealedAuthoritySignInfoTrait for super::EmptySignInfo {}
1445    impl SealedAuthoritySignInfoTrait for super::AuthoritySignInfo {}
1446    impl<const S: bool> SealedAuthoritySignInfoTrait for super::AuthorityQuorumSignInfo<S> {}
1447}
1448
1449/// Something that we know how to hash and sign.
1450pub trait Signable<W> {
1451    fn write(&self, writer: &mut W);
1452}
1453
1454pub trait SignableBytes
1455where
1456    Self: Sized,
1457{
1458    fn from_signable_bytes(bytes: &[u8]) -> Result<Self, Error>;
1459}
1460
1461/// Activate the blanket implementation of `Signable` based on serde and BCS.
1462/// * We use `serde_name` to extract a seed from the name of structs and enums.
1463/// * We use `BCS` to generate canonical bytes suitable for hashing and signing.
1464///
1465/// # Safety
1466/// We protect the access to this marker trait through a "sealed trait" pattern:
1467/// impls must be add added here (nowehre else) which lets us note those impls
1468/// MUST be on types that comply with the `serde_name` machinery
1469/// for the below implementations not to panic. One way to check they work is to
1470/// write a unit test for serialization to / deserialization from signable
1471/// bytes.
1472mod bcs_signable {
1473
1474    pub trait BcsSignable: serde::Serialize + serde::de::DeserializeOwned {}
1475    impl BcsSignable for crate::committee::Committee {}
1476    impl BcsSignable for crate::messages_checkpoint::CheckpointSummary {}
1477    impl BcsSignable for crate::messages_checkpoint::CheckpointContents {}
1478
1479    impl BcsSignable for crate::effects::TransactionEffects {}
1480    impl BcsSignable for crate::effects::TransactionEvents {}
1481    impl BcsSignable for crate::transaction::TransactionData {}
1482    impl BcsSignable for crate::transaction::SenderSignedData {}
1483    impl BcsSignable for crate::object::ObjectInner {}
1484
1485    impl BcsSignable for crate::accumulator::Accumulator {}
1486
1487    impl BcsSignable for super::bcs_signable_test::Foo {}
1488    #[cfg(test)]
1489    impl BcsSignable for super::bcs_signable_test::Bar {}
1490}
1491
1492impl<T, W> Signable<W> for T
1493where
1494    T: bcs_signable::BcsSignable,
1495    W: std::io::Write,
1496{
1497    fn write(&self, writer: &mut W) {
1498        let name = serde_name::trace_name::<Self>().expect("Self must be a struct or an enum");
1499        // Note: This assumes that names never contain the separator `::`.
1500        write!(writer, "{name}::").expect("Hasher should not fail");
1501        bcs::serialize_into(writer, &self).expect("Message serialization should not fail");
1502    }
1503}
1504
1505impl<W> Signable<W> for EpochId
1506where
1507    W: std::io::Write,
1508{
1509    fn write(&self, writer: &mut W) {
1510        bcs::serialize_into(writer, &self).expect("Message serialization should not fail");
1511    }
1512}
1513
1514impl<T> SignableBytes for T
1515where
1516    T: bcs_signable::BcsSignable,
1517{
1518    fn from_signable_bytes(bytes: &[u8]) -> Result<Self, Error> {
1519        // Remove name tag before deserialization using BCS
1520        let name = serde_name::trace_name::<Self>().expect("Self should be a struct or an enum");
1521        let name_byte_len = format!("{name}::").bytes().len();
1522        Ok(bcs::from_bytes(bytes.get(name_byte_len..).ok_or_else(
1523            || anyhow!("Failed to deserialize to {name}."),
1524        )?)?)
1525    }
1526}
1527
1528fn hash<S: Signable<H>, H: HashFunction<DIGEST_SIZE>, const DIGEST_SIZE: usize>(
1529    signable: &S,
1530) -> [u8; DIGEST_SIZE] {
1531    let mut digest = H::default();
1532    signable.write(&mut digest);
1533    let hash = digest.finalize();
1534    hash.into()
1535}
1536
1537pub fn default_hash<S: Signable<DefaultHash>>(signable: &S) -> [u8; 32] {
1538    hash::<S, DefaultHash, 32>(signable)
1539}
1540
1541#[derive(Default)]
1542pub struct VerificationObligation<'a> {
1543    pub messages: Vec<Vec<u8>>,
1544    pub signatures: Vec<AggregateAuthoritySignature>,
1545    pub public_keys: Vec<Vec<&'a AuthorityPublicKey>>,
1546}
1547
1548impl<'a> VerificationObligation<'a> {
1549    pub fn new() -> VerificationObligation<'a> {
1550        VerificationObligation::default()
1551    }
1552
1553    /// Add a new message to the list of messages to be verified.
1554    /// Returns the index of the message.
1555    pub fn add_message<T>(&mut self, message_value: &T, epoch: EpochId, intent: Intent) -> usize
1556    where
1557        T: Serialize,
1558    {
1559        let intent_msg = IntentMessage::new(intent, message_value);
1560        let mut intent_msg_bytes =
1561            bcs::to_bytes(&intent_msg).expect("Message serialization should not fail");
1562        epoch.write(&mut intent_msg_bytes);
1563        self.signatures.push(AggregateAuthoritySignature::default());
1564        self.public_keys.push(Vec::new());
1565        self.messages.push(intent_msg_bytes);
1566        self.messages.len() - 1
1567    }
1568
1569    // Attempts to add signature and public key to the obligation. If this fails,
1570    // ensure to call `verify` manually.
1571    pub fn add_signature_and_public_key(
1572        &mut self,
1573        signature: &AuthoritySignature,
1574        public_key: &'a AuthorityPublicKey,
1575        idx: usize,
1576    ) -> IotaResult<()> {
1577        self.public_keys
1578            .get_mut(idx)
1579            .ok_or(IotaError::InvalidAuthenticator)?
1580            .push(public_key);
1581        self.signatures
1582            .get_mut(idx)
1583            .ok_or(IotaError::InvalidAuthenticator)?
1584            .add_signature(signature.clone())
1585            .map_err(|_| IotaError::InvalidSignature {
1586                error: "Failed to add signature to obligation".to_string(),
1587            })?;
1588        Ok(())
1589    }
1590
1591    pub fn verify_all(self) -> IotaResult<()> {
1592        let mut pks = Vec::with_capacity(self.public_keys.len());
1593        for pk in self.public_keys.clone() {
1594            pks.push(pk.into_iter());
1595        }
1596        AggregateAuthoritySignature::batch_verify(
1597            &self.signatures.iter().collect::<Vec<_>>()[..],
1598            pks,
1599            &self.messages.iter().map(|x| &x[..]).collect::<Vec<_>>()[..],
1600        )
1601        .map_err(|e| {
1602            let message = format!(
1603                "pks: {:?}, messages: {:?}, sigs: {:?}",
1604                &self.public_keys,
1605                self.messages
1606                    .iter()
1607                    .map(Base64::encode)
1608                    .collect::<Vec<String>>(),
1609                &self
1610                    .signatures
1611                    .iter()
1612                    .map(|s| Base64::encode(s.as_ref()))
1613                    .collect::<Vec<String>>()
1614            );
1615
1616            let chunk_size = 2048;
1617
1618            // This error message may be very long, so we print out the error in chunks of
1619            // to avoid hitting a max log line length on the system.
1620            for (i, chunk) in message
1621                .as_bytes()
1622                .chunks(chunk_size)
1623                .map(std::str::from_utf8)
1624                .enumerate()
1625            {
1626                warn!(
1627                    "Failed to batch verify aggregated auth sig: {} (chunk {}): {}",
1628                    e,
1629                    i,
1630                    chunk.unwrap()
1631                );
1632            }
1633
1634            IotaError::InvalidSignature {
1635                error: format!("Failed to batch verify aggregated auth sig: {e}"),
1636            }
1637        })?;
1638        Ok(())
1639    }
1640}
1641
1642pub mod bcs_signable_test {
1643    use serde::{Deserialize, Serialize};
1644
1645    #[derive(Clone, Serialize, Deserialize)]
1646    pub struct Foo(pub String);
1647
1648    #[cfg(test)]
1649    #[derive(Serialize, Deserialize)]
1650    pub struct Bar(pub String);
1651
1652    #[cfg(test)]
1653    use super::VerificationObligation;
1654
1655    #[cfg(test)]
1656    pub fn get_obligation_input<T>(value: &T) -> (VerificationObligation<'_>, usize)
1657    where
1658        T: super::bcs_signable::BcsSignable,
1659    {
1660        use shared_crypto::intent::{Intent, IntentScope};
1661
1662        let mut obligation = VerificationObligation::default();
1663        // Add the obligation of the authority signature verifications.
1664        let idx = obligation.add_message(
1665            value,
1666            0,
1667            Intent::iota_app(IntentScope::SenderSignedTransaction),
1668        );
1669        (obligation, idx)
1670    }
1671}
1672
1673#[derive(
1674    Clone,
1675    Copy,
1676    Deserialize,
1677    Serialize,
1678    JsonSchema,
1679    Debug,
1680    EnumString,
1681    strum_macros::Display,
1682    PartialEq,
1683    Eq,
1684)]
1685#[strum(serialize_all = "lowercase")]
1686pub enum SignatureScheme {
1687    ED25519,
1688    Secp256k1,
1689    Secp256r1,
1690    BLS12381, // This is currently not supported for user Iota Address.
1691    MultiSig,
1692    ZkLoginAuthenticator,
1693    PasskeyAuthenticator,
1694}
1695
1696impl SignatureScheme {
1697    pub fn flag(&self) -> u8 {
1698        match self {
1699            SignatureScheme::ED25519 => 0x00,
1700            SignatureScheme::Secp256k1 => 0x01,
1701            SignatureScheme::Secp256r1 => 0x02,
1702            SignatureScheme::MultiSig => 0x03,
1703            SignatureScheme::BLS12381 => 0x04, // This is currently not supported for user Iota
1704            // Address.
1705            SignatureScheme::ZkLoginAuthenticator => 0x05,
1706            SignatureScheme::PasskeyAuthenticator => 0x06,
1707        }
1708    }
1709
1710    /// Takes as input an hasher and updates it with a flag byte if the input
1711    /// scheme is not ED25519; it does nothing otherwise.
1712    pub fn update_hasher_with_flag(&self, hasher: &mut DefaultHash) {
1713        match self {
1714            SignatureScheme::ED25519 => (),
1715            _ => hasher.update([self.flag()]),
1716        };
1717    }
1718
1719    pub fn from_flag(flag: &str) -> Result<SignatureScheme, IotaError> {
1720        let byte_int = flag
1721            .parse::<u8>()
1722            .map_err(|_| IotaError::KeyConversion("Invalid key scheme".to_string()))?;
1723        Self::from_flag_byte(&byte_int)
1724    }
1725
1726    pub fn from_flag_byte(byte_int: &u8) -> Result<SignatureScheme, IotaError> {
1727        match byte_int {
1728            0x00 => Ok(SignatureScheme::ED25519),
1729            0x01 => Ok(SignatureScheme::Secp256k1),
1730            0x02 => Ok(SignatureScheme::Secp256r1),
1731            0x03 => Ok(SignatureScheme::MultiSig),
1732            0x04 => Ok(SignatureScheme::BLS12381),
1733            0x05 => Ok(SignatureScheme::ZkLoginAuthenticator),
1734            0x06 => Ok(SignatureScheme::PasskeyAuthenticator),
1735            _ => Err(IotaError::KeyConversion("Invalid key scheme".to_string())),
1736        }
1737    }
1738}
1739/// Unlike [enum Signature], [enum CompressedSignature] does not contain public
1740/// key.
1741#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
1742pub enum CompressedSignature {
1743    Ed25519(Ed25519SignatureAsBytes),
1744    Secp256k1(Secp256k1SignatureAsBytes),
1745    Secp256r1(Secp256r1SignatureAsBytes),
1746    ZkLogin(ZkLoginAuthenticatorAsBytes),
1747    Passkey(PasskeyAuthenticatorAsBytes),
1748}
1749
1750#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
1751pub struct ZkLoginAuthenticatorAsBytes(#[schemars(with = "Base64")] pub Vec<u8>);
1752
1753#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, JsonSchema)]
1754pub struct PasskeyAuthenticatorAsBytes(#[schemars(with = "Base64")] pub Vec<u8>);
1755
1756impl AsRef<[u8]> for CompressedSignature {
1757    fn as_ref(&self) -> &[u8] {
1758        match self {
1759            CompressedSignature::Ed25519(sig) => &sig.0,
1760            CompressedSignature::Secp256k1(sig) => &sig.0,
1761            CompressedSignature::Secp256r1(sig) => &sig.0,
1762            CompressedSignature::ZkLogin(sig) => &sig.0,
1763            CompressedSignature::Passkey(sig) => &sig.0,
1764        }
1765    }
1766}
1767
1768impl FromStr for Signature {
1769    type Err = eyre::Report;
1770    fn from_str(s: &str) -> Result<Self, Self::Err> {
1771        Self::decode_base64(s).map_err(|e| eyre!("Fail to decode base64 {}", e.to_string()))
1772    }
1773}
1774
1775impl FromStr for PublicKey {
1776    type Err = eyre::Report;
1777    fn from_str(s: &str) -> Result<Self, Self::Err> {
1778        Self::decode_base64(s).map_err(|e| eyre!("Fail to decode base64 {}", e.to_string()))
1779    }
1780}
1781
1782impl FromStr for GenericSignature {
1783    type Err = eyre::Report;
1784    fn from_str(s: &str) -> Result<Self, Self::Err> {
1785        Self::decode_base64(s).map_err(|e| eyre!("Fail to decode base64 {}", e.to_string()))
1786    }
1787}
1788
1789// Types for randomness generation
1790//
1791pub type RandomnessSignature = fastcrypto_tbls::types::Signature;
1792pub type RandomnessPartialSignature = fastcrypto_tbls::tbls::PartialSignature<RandomnessSignature>;
1793pub type RandomnessPrivateKey =
1794    fastcrypto_tbls::ecies_v1::PrivateKey<fastcrypto::groups::bls12381::G2Element>;
1795
1796/// Round number of generated randomness.
1797#[derive(Clone, Copy, Hash, Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)]
1798pub struct RandomnessRound(pub u64);
1799
1800impl Display for RandomnessRound {
1801    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1802        write!(f, "{}", self.0)
1803    }
1804}
1805
1806impl std::ops::Add for RandomnessRound {
1807    type Output = Self;
1808    fn add(self, other: Self) -> Self {
1809        Self(self.0 + other.0)
1810    }
1811}
1812
1813impl std::ops::Add<u64> for RandomnessRound {
1814    type Output = Self;
1815    fn add(self, other: u64) -> Self {
1816        Self(self.0 + other)
1817    }
1818}
1819
1820impl std::ops::Sub for RandomnessRound {
1821    type Output = Self;
1822    fn sub(self, other: Self) -> Self {
1823        Self(self.0 - other.0)
1824    }
1825}
1826
1827impl std::ops::Sub<u64> for RandomnessRound {
1828    type Output = Self;
1829    fn sub(self, other: u64) -> Self {
1830        Self(self.0 - other)
1831    }
1832}
1833
1834impl RandomnessRound {
1835    pub fn new(round: u64) -> Self {
1836        Self(round)
1837    }
1838
1839    pub fn checked_add(self, rhs: u64) -> Option<Self> {
1840        self.0.checked_add(rhs).map(Self)
1841    }
1842
1843    pub fn signature_message(&self) -> Vec<u8> {
1844        "random_beacon round "
1845            .as_bytes()
1846            .iter()
1847            .cloned()
1848            .chain(bcs::to_bytes(&self.0).expect("serialization should not fail"))
1849            .collect()
1850    }
1851}