Skip to main content

sui_crypto/
lib.rs

1#![cfg_attr(doc_cfg, feature(doc_cfg))]
2
3use sui_sdk_types::PersonalMessage;
4use sui_sdk_types::Transaction;
5use sui_sdk_types::UserSignature;
6
7pub use signature::Error as SignatureError;
8pub use signature::Signer;
9pub use signature::Verifier;
10
11#[cfg(feature = "bls12381")]
12#[cfg_attr(doc_cfg, doc(cfg(feature = "bls12381")))]
13pub mod bls12381;
14
15#[cfg(feature = "ed25519")]
16#[cfg_attr(doc_cfg, doc(cfg(feature = "ed25519")))]
17pub mod ed25519;
18
19#[cfg(feature = "secp256k1")]
20#[cfg_attr(doc_cfg, doc(cfg(feature = "secp256k1")))]
21pub mod secp256k1;
22
23#[cfg(feature = "secp256r1")]
24#[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
25pub mod secp256r1;
26
27#[cfg(feature = "passkey")]
28#[cfg_attr(doc_cfg, doc(cfg(feature = "passkey")))]
29pub mod passkey;
30
31#[cfg(feature = "mldsa65")]
32#[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
33pub mod mldsa65;
34
35#[cfg(feature = "zklogin")]
36#[cfg_attr(doc_cfg, doc(cfg(feature = "zklogin")))]
37pub mod zklogin;
38
39#[cfg(all(test, feature = "mldsa65"))]
40mod test_util;
41
42#[cfg(any(
43    feature = "ed25519",
44    feature = "secp256r1",
45    feature = "secp256k1",
46    feature = "mldsa65",
47    feature = "zklogin"
48))]
49#[cfg_attr(
50    doc_cfg,
51    doc(cfg(any(
52        feature = "ed25519",
53        feature = "secp256r1",
54        feature = "secp256k1",
55        feature = "mldsa65",
56        feature = "zklogin"
57    )))
58)]
59pub mod simple;
60
61#[cfg(any(
62    feature = "ed25519",
63    feature = "secp256r1",
64    feature = "secp256k1",
65    feature = "mldsa65"
66))]
67mod suipriv;
68
69#[cfg(any(
70    feature = "ed25519",
71    feature = "secp256r1",
72    feature = "secp256k1",
73    feature = "mldsa65",
74    feature = "zklogin"
75))]
76#[cfg_attr(
77    doc_cfg,
78    doc(cfg(any(
79        feature = "ed25519",
80        feature = "secp256r1",
81        feature = "secp256k1",
82        feature = "mldsa65",
83        feature = "zklogin"
84    )))
85)]
86pub mod multisig;
87
88#[cfg(any(
89    feature = "ed25519",
90    feature = "secp256r1",
91    feature = "secp256k1",
92    feature = "mldsa65",
93    feature = "zklogin"
94))]
95#[cfg_attr(
96    doc_cfg,
97    doc(cfg(any(
98        feature = "ed25519",
99        feature = "secp256r1",
100        feature = "secp256k1",
101        feature = "mldsa65",
102        feature = "zklogin"
103    )))
104)]
105#[doc(inline)]
106pub use multisig::UserSignatureVerifier;
107
108/// Interface for signing user transactions and messages in Sui
109///
110/// # Note
111///
112/// There is a blanket implementation of `SuiSigner` for all `T` where `T:
113/// `[`Signer`]`<`[`UserSignature`]`>` so it is generally recommended for a signer to implement
114/// `Signer<UserSignature>` and rely on the blanket implementation which handles the proper
115/// construction of the signing message.
116pub trait SuiSigner {
117    fn sign_transaction(&self, transaction: &Transaction) -> Result<UserSignature, SignatureError>;
118    fn sign_personal_message(
119        &self,
120        message: &PersonalMessage<'_>,
121    ) -> Result<UserSignature, SignatureError>;
122}
123
124impl<T: Signer<UserSignature>> SuiSigner for T {
125    fn sign_transaction(&self, transaction: &Transaction) -> Result<UserSignature, SignatureError> {
126        let msg = transaction.signing_digest();
127        self.try_sign(&msg)
128    }
129
130    fn sign_personal_message(
131        &self,
132        message: &PersonalMessage<'_>,
133    ) -> Result<UserSignature, SignatureError> {
134        let msg = message.signing_digest();
135        self.try_sign(&msg)
136    }
137}
138
139/// Interface for signing user transactions and messages with a scheme that
140/// takes fresh randomness per signature
141///
142/// Randomized counterpart of [`SuiSigner`]. Today that is ML-DSA-65 only.
143///
144/// # Note
145///
146/// There is a blanket implementation of `SuiRandomizedSigner` for all `T`
147/// where `T: `[`signature::RandomizedSigner`]`<`[`UserSignature`]`>`, which handles the
148/// proper construction of the signing message.
149///
150/// The rng is taken as `&mut dyn CryptoRngCore` rather than `&mut impl
151/// CryptoRngCore` so that the trait stays dyn-compatible, like
152/// [`SuiSigner`], and signers can be held as `dyn SuiRandomizedSigner`.
153#[cfg(feature = "mldsa65")]
154#[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
155pub trait SuiRandomizedSigner {
156    fn sign_transaction_with_rng(
157        &self,
158        rng: &mut dyn rand_core::CryptoRngCore,
159        transaction: &Transaction,
160    ) -> Result<UserSignature, SignatureError>;
161    fn sign_personal_message_with_rng(
162        &self,
163        rng: &mut dyn rand_core::CryptoRngCore,
164        message: &PersonalMessage<'_>,
165    ) -> Result<UserSignature, SignatureError>;
166}
167
168#[cfg(feature = "mldsa65")]
169impl<T: signature::RandomizedSigner<UserSignature>> SuiRandomizedSigner for T {
170    fn sign_transaction_with_rng(
171        &self,
172        mut rng: &mut dyn rand_core::CryptoRngCore,
173        transaction: &Transaction,
174    ) -> Result<UserSignature, SignatureError> {
175        let msg = transaction.signing_digest();
176        self.try_sign_with_rng(&mut rng, &msg)
177    }
178
179    fn sign_personal_message_with_rng(
180        &self,
181        mut rng: &mut dyn rand_core::CryptoRngCore,
182        message: &PersonalMessage<'_>,
183    ) -> Result<UserSignature, SignatureError> {
184        let msg = message.signing_digest();
185        self.try_sign_with_rng(&mut rng, &msg)
186    }
187}
188
189/// Interface for verifying user transactions and messages in Sui
190///
191/// # Note
192///
193/// There is a blanket implementation of `SuiVerifier` for all `T` where `T:
194/// `[`Verifier`]`<`[`UserSignature`]`>` so it is generally recommended for a signer to implement
195/// `Verifier<UserSignature>` and rely on the blanket implementation which handles the proper
196/// construction of the signing message.
197pub trait SuiVerifier {
198    fn verify_transaction(
199        &self,
200        transaction: &Transaction,
201        signature: &UserSignature,
202    ) -> Result<(), SignatureError>;
203    fn verify_personal_message(
204        &self,
205        message: &PersonalMessage<'_>,
206        signature: &UserSignature,
207    ) -> Result<(), SignatureError>;
208}
209
210impl<T: Verifier<UserSignature>> SuiVerifier for T {
211    fn verify_transaction(
212        &self,
213        transaction: &Transaction,
214        signature: &UserSignature,
215    ) -> Result<(), SignatureError> {
216        let message = transaction.signing_digest();
217        self.verify(&message, signature)
218    }
219
220    fn verify_personal_message(
221        &self,
222        message: &PersonalMessage<'_>,
223        signature: &UserSignature,
224    ) -> Result<(), SignatureError> {
225        let message = message.signing_digest();
226        self.verify(&message, signature)
227    }
228}