1use std::hash::Hash;
2
3use derive_more::{AsMut, AsRef};
4use enum_dispatch::enum_dispatch;
5use eyre::eyre;
6use fastcrypto::ed25519::{
7 Ed25519KeyPair,
8 Ed25519PublicKey,
9 Ed25519PublicKeyAsBytes,
10 Ed25519Signature,
11 Ed25519SignatureAsBytes,
12};
13use fastcrypto::encoding::{Base64 as Base64Wrapper, Bech32, Encoding as _};
14use fastcrypto::error::FastCryptoError;
15use fastcrypto::hash::{Blake2b256, HashFunction as _};
16use fastcrypto::secp256k1::{
17 Secp256k1KeyPair,
18 Secp256k1PublicKey,
19 Secp256k1PublicKeyAsBytes,
20 Secp256k1Signature,
21 Secp256k1SignatureAsBytes,
22};
23use fastcrypto::secp256r1::{
24 Secp256r1KeyPair,
25 Secp256r1PublicKey,
26 Secp256r1PublicKeyAsBytes,
27 Secp256r1Signature,
28 Secp256r1SignatureAsBytes,
29};
30use fastcrypto::traits::{
31 Authenticator,
32 EncodeDecodeBase64,
33 KeyPair as KeypairTraits,
34 Signer,
35 ToFromBytes,
36 VerifyingKey,
37};
38use serde::{Deserialize, Deserializer, Serialize, Serializer};
39use serde_with::base64::Base64;
40use serde_with::{Bytes, IfIsHumanReadable, serde_as};
41use strum::EnumString;
42use sui_sdk_types::Address as SuiAddress;
43use sui_sdk_types::bcs::ToBcs;
44
45use crate::intent::IntentMessage;
46
47pub type DefaultHash = Blake2b256;
48
49pub const SUI_PRIV_KEY_PREFIX: &str = "suiprivkey";
50
51#[derive(
53 Eq,
54 PartialEq,
55 Clone,
56 Debug,
57 Serialize,
58 Deserialize,
59 thiserror::Error,
60 Hash,
61 strum::AsRefStr,
62 strum::IntoStaticStr,
63)]
64pub enum Error {
65 #[error("Signature key generation error: {0}")]
66 SignatureKeyGenError(String),
67 #[error("Key Conversion Error: {0}")]
68 KeyConversionError(String),
69 #[error("Invalid Private Key provided")]
70 InvalidPrivateKey,
71 #[error("Signature is not valid: {}", error)]
72 InvalidSignature { error: String },
73 #[error("Value was not signed by the correct sender: {}", error)]
74 IncorrectSigner { error: String },
75 #[error("Use of disabled feature: {:?}", error)]
76 UnsupportedFeatureError { error: String },
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
85pub enum CompressedSignature {
86 Ed25519(Ed25519SignatureAsBytes),
87 Secp256k1(Secp256k1SignatureAsBytes),
88 Secp256r1(Secp256r1SignatureAsBytes),
89 ZkLogin(ZkLoginAuthenticatorAsBytes),
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
93pub struct ZkLoginAuthenticatorAsBytes(pub Vec<u8>);
94
95impl AsRef<[u8]> for CompressedSignature {
96 fn as_ref(&self) -> &[u8] {
97 match self {
98 Self::Ed25519(sig) => &sig.0,
99 Self::Secp256k1(sig) => &sig.0,
100 Self::Secp256r1(sig) => &sig.0,
101 Self::ZkLogin(sig) => &sig.0,
102 }
103 }
104}
105
106#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
111pub enum PublicKey {
112 Ed25519(Ed25519PublicKeyAsBytes),
113 Secp256k1(Secp256k1PublicKeyAsBytes),
114 Secp256r1(Secp256r1PublicKeyAsBytes),
115 ZkLogin(ZkLoginPublicIdentifier),
116}
117
118impl AsRef<[u8]> for PublicKey {
119 fn as_ref(&self) -> &[u8] {
120 match self {
121 Self::Ed25519(pk) => &pk.0,
122 Self::Secp256k1(pk) => &pk.0,
123 Self::Secp256r1(pk) => &pk.0,
124 Self::ZkLogin(z) => &z.0,
125 }
126 }
127}
128
129impl EncodeDecodeBase64 for PublicKey {
130 fn encode_base64(&self) -> String {
131 let mut bytes: Vec<u8> = Vec::new();
132 bytes.extend_from_slice(&[self.flag()]);
133 bytes.extend_from_slice(self.as_ref());
134 Base64Wrapper::encode(&bytes[..])
135 }
136
137 fn decode_base64(value: &str) -> Result<Self, FastCryptoError> {
138 let bytes = Base64Wrapper::decode(value)?;
139 match bytes.first() {
140 Some(x) => {
141 if x == &SignatureScheme::ED25519.flag() {
142 let pk: Ed25519PublicKey = Ed25519PublicKey::from_bytes(
143 bytes
144 .get(1..)
145 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
146 )?;
147 Ok(Self::Ed25519((&pk).into()))
148 } else if x == &SignatureScheme::Secp256k1.flag() {
149 let pk = Secp256k1PublicKey::from_bytes(
150 bytes
151 .get(1..)
152 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
153 )?;
154 Ok(Self::Secp256k1((&pk).into()))
155 } else if x == &SignatureScheme::Secp256r1.flag() {
156 let pk = Secp256r1PublicKey::from_bytes(
157 bytes
158 .get(1..)
159 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
160 )?;
161 Ok(Self::Secp256r1((&pk).into()))
162 } else {
163 Err(FastCryptoError::GeneralError(
164 "Invalid flag byte".to_string(),
165 ))
166 }
167 }
168 _ => Err(FastCryptoError::InvalidInput),
169 }
170 }
171}
172
173impl PublicKey {
174 pub fn to_sui_address(&self) -> SuiAddress {
179 let mut hasher = DefaultHash::default();
180 hasher.update([self.flag()]);
181 hasher.update(self);
182 let g_arr = hasher.finalize();
183 SuiAddress::new(g_arr.digest)
184 }
185
186 pub const fn flag(&self) -> u8 {
187 self.scheme().flag()
188 }
189
190 pub fn try_from_bytes(curve: SignatureScheme, key_bytes: &[u8]) -> Result<Self, eyre::Report> {
191 match curve {
192 SignatureScheme::ED25519 => Ok(Self::Ed25519(
193 (&Ed25519PublicKey::from_bytes(key_bytes)?).into(),
194 )),
195 SignatureScheme::Secp256k1 => Ok(Self::Secp256k1(
196 (&Secp256k1PublicKey::from_bytes(key_bytes)?).into(),
197 )),
198 SignatureScheme::Secp256r1 => Ok(Self::Secp256r1(
199 (&Secp256r1PublicKey::from_bytes(key_bytes)?).into(),
200 )),
201 _ => Err(eyre!("Unsupported curve")),
202 }
203 }
204
205 pub const fn scheme(&self) -> SignatureScheme {
206 match self {
207 Self::Ed25519(_) => Ed25519SuiSignature::SCHEME,
208 Self::Secp256k1(_) => Secp256k1SuiSignature::SCHEME,
209 Self::Secp256r1(_) => Secp256r1SuiSignature::SCHEME,
210 Self::ZkLogin(_) => SignatureScheme::ZkLoginAuthenticator,
211 }
212 }
213}
214#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
217pub struct ZkLoginPublicIdentifier(pub Vec<u8>);
218
219#[enum_dispatch]
225#[derive(Clone, Debug, PartialEq, Eq, Hash)]
226pub enum Signature {
227 Ed25519SuiSignature,
228 Secp256k1SuiSignature,
229 Secp256r1SuiSignature,
230}
231
232impl Signature {
233 pub fn new_hashed(hashed_msg: &[u8], secret: &dyn Signer<Self>) -> Self {
235 Signer::sign(secret, hashed_msg)
236 }
237
238 pub fn new_secure<T>(value: &IntentMessage<T>, secret: &dyn Signer<Self>) -> Self
239 where
240 T: Serialize,
241 {
242 let mut hasher = DefaultHash::default();
243 hasher.update(
244 value
245 .to_bcs()
246 .expect("Message serialization should not fail"),
247 );
248 Signer::sign(secret, &hasher.finalize().digest)
249 }
250
251 pub fn to_compressed(&self) -> Result<CompressedSignature, Error> {
252 let bytes = self.signature_bytes();
253 match self.scheme() {
254 SignatureScheme::ED25519 => Ok(CompressedSignature::Ed25519(
255 (&Ed25519Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
256 error: "Cannot parse ed25519 sig".to_string(),
257 })?)
258 .into(),
259 )),
260 SignatureScheme::Secp256k1 => Ok(CompressedSignature::Secp256k1(
261 (&Secp256k1Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
262 error: "Cannot parse secp256k1 sig".to_string(),
263 })?)
264 .into(),
265 )),
266 SignatureScheme::Secp256r1 => Ok(CompressedSignature::Secp256r1(
267 (&Secp256r1Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
268 error: "Cannot parse secp256r1 sig".to_string(),
269 })?)
270 .into(),
271 )),
272 _ => Err(Error::UnsupportedFeatureError {
273 error: "Unsupported signature scheme".to_string(),
274 }),
275 }
276 }
277
278 pub fn to_public_key(&self) -> Result<PublicKey, Error> {
279 let bytes = self.public_key_bytes();
280 match self.scheme() {
281 SignatureScheme::ED25519 => Ok(PublicKey::Ed25519(
282 (&Ed25519PublicKey::from_bytes(bytes).map_err(|_| {
283 Error::KeyConversionError("Cannot parse ed25519 pk".to_string())
284 })?)
285 .into(),
286 )),
287 SignatureScheme::Secp256k1 => Ok(PublicKey::Secp256k1(
288 (&Secp256k1PublicKey::from_bytes(bytes).map_err(|_| {
289 Error::KeyConversionError("Cannot parse secp256k1 pk".to_string())
290 })?)
291 .into(),
292 )),
293 SignatureScheme::Secp256r1 => Ok(PublicKey::Secp256r1(
294 (&Secp256r1PublicKey::from_bytes(bytes).map_err(|_| {
295 Error::KeyConversionError("Cannot parse secp256r1 pk".to_string())
296 })?)
297 .into(),
298 )),
299 _ => Err(Error::UnsupportedFeatureError {
300 error: "Unsupported signature scheme in Signature".to_string(),
301 }),
302 }
303 }
304}
305
306impl Serialize for Signature {
307 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
308 where
309 S: Serializer,
310 {
311 let bytes = self.as_ref();
312
313 if serializer.is_human_readable() {
314 let s = Base64Wrapper::encode(bytes);
315 serializer.serialize_str(&s)
316 } else {
317 serializer.serialize_bytes(bytes)
318 }
319 }
320}
321
322impl<'de> Deserialize<'de> for Signature {
323 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
324 where
325 D: Deserializer<'de>,
326 {
327 use serde::de::Error;
328
329 let bytes = if deserializer.is_human_readable() {
330 let s = String::deserialize(deserializer)?;
331 Base64Wrapper::decode(&s).map_err(|e| Error::custom(e.to_string()))?
332 } else {
333 let data: Vec<u8> = Vec::deserialize(deserializer)?;
334 data
335 };
336
337 Self::from_bytes(&bytes).map_err(|e| Error::custom(e.to_string()))
338 }
339}
340
341impl AsRef<[u8]> for Signature {
342 fn as_ref(&self) -> &[u8] {
343 match self {
344 Self::Ed25519SuiSignature(sig) => sig.as_ref(),
345 Self::Secp256k1SuiSignature(sig) => sig.as_ref(),
346 Self::Secp256r1SuiSignature(sig) => sig.as_ref(),
347 }
348 }
349}
350impl AsMut<[u8]> for Signature {
351 fn as_mut(&mut self) -> &mut [u8] {
352 match self {
353 Self::Ed25519SuiSignature(sig) => sig.as_mut(),
354 Self::Secp256k1SuiSignature(sig) => sig.as_mut(),
355 Self::Secp256r1SuiSignature(sig) => sig.as_mut(),
356 }
357 }
358}
359
360impl ToFromBytes for Signature {
361 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
362 match bytes.first() {
363 Some(x) => {
364 if x == &Ed25519SuiSignature::SCHEME.flag() {
365 Ok(<Ed25519SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
366 } else if x == &Secp256k1SuiSignature::SCHEME.flag() {
367 Ok(<Secp256k1SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
368 } else if x == &Secp256r1SuiSignature::SCHEME.flag() {
369 Ok(<Secp256r1SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
370 } else {
371 Err(FastCryptoError::InvalidInput)
372 }
373 }
374 _ => Err(FastCryptoError::InvalidInput),
375 }
376 }
377}
378
379impl From<Signature> for sui_sdk_types::UserSignature {
380 fn from(value: Signature) -> Self {
381 Self::from_bytes(value.as_bytes()).expect("Compatible")
382 }
383}
384
385#[derive(Clone, Copy, Deserialize, Serialize, Debug, EnumString, strum::Display)]
390#[strum(serialize_all = "lowercase")]
391pub enum SignatureScheme {
392 ED25519,
393 Secp256k1,
394 Secp256r1,
395 BLS12381, MultiSig,
397 ZkLoginAuthenticator,
398}
399
400impl SignatureScheme {
401 pub const fn flag(&self) -> u8 {
402 match self {
403 Self::ED25519 => 0x00,
404 Self::Secp256k1 => 0x01,
405 Self::Secp256r1 => 0x02,
406 Self::MultiSig => 0x03,
407 Self::BLS12381 => 0x04, Self::ZkLoginAuthenticator => 0x05,
409 }
410 }
411
412 pub fn from_flag(flag: &str) -> Result<Self, Error> {
413 let byte_int = flag
414 .parse::<u8>()
415 .map_err(|_| Error::KeyConversionError("Invalid key scheme".to_string()))?;
416 Self::from_flag_byte(&byte_int)
417 }
418
419 pub fn from_flag_byte(byte_int: &u8) -> Result<Self, Error> {
420 match byte_int {
421 0x00 => Ok(Self::ED25519),
422 0x01 => Ok(Self::Secp256k1),
423 0x02 => Ok(Self::Secp256r1),
424 0x03 => Ok(Self::MultiSig),
425 0x04 => Ok(Self::BLS12381),
426 0x05 => Ok(Self::ZkLoginAuthenticator),
427 _ => Err(Error::KeyConversionError("Invalid key scheme".to_string())),
428 }
429 }
430}
431
432#[allow(clippy::large_enum_variant)]
437#[derive(Debug, derive_more::From, PartialEq, Eq)]
438pub enum SuiKeyPair {
439 Ed25519(Ed25519KeyPair),
440 Secp256k1(Secp256k1KeyPair),
441 Secp256r1(Secp256r1KeyPair),
442}
443
444impl SuiKeyPair {
445 pub fn public(&self) -> PublicKey {
446 match self {
447 Self::Ed25519(kp) => PublicKey::Ed25519(kp.public().into()),
448 Self::Secp256k1(kp) => PublicKey::Secp256k1(kp.public().into()),
449 Self::Secp256r1(kp) => PublicKey::Secp256r1(kp.public().into()),
450 }
451 }
452}
453
454impl Signer<Signature> for SuiKeyPair {
455 fn sign(&self, msg: &[u8]) -> Signature {
456 match self {
457 Self::Ed25519(kp) => kp.sign(msg),
458 Self::Secp256k1(kp) => kp.sign(msg),
459 Self::Secp256r1(kp) => kp.sign(msg),
460 }
461 }
462}
463
464impl EncodeDecodeBase64 for SuiKeyPair {
465 fn encode_base64(&self) -> String {
466 Base64Wrapper::encode(self.to_bytes())
467 }
468
469 fn decode_base64(value: &str) -> Result<Self, FastCryptoError> {
470 let bytes = Base64Wrapper::decode(value)?;
471 Self::from_bytes(&bytes)
472 }
473}
474impl SuiKeyPair {
475 pub fn to_bytes(&self) -> Vec<u8> {
476 let mut bytes: Vec<u8> = Vec::new();
477 bytes.push(self.public().flag());
478
479 match self {
480 Self::Ed25519(kp) => {
481 bytes.extend_from_slice(kp.as_bytes());
482 }
483 Self::Secp256k1(kp) => {
484 bytes.extend_from_slice(kp.as_bytes());
485 }
486 Self::Secp256r1(kp) => {
487 bytes.extend_from_slice(kp.as_bytes());
488 }
489 }
490 bytes
491 }
492
493 pub fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
494 match SignatureScheme::from_flag_byte(
495 bytes
496 .first()
497 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
498 ) {
499 Ok(x) => match x {
500 SignatureScheme::ED25519 => Ok(Self::Ed25519(Ed25519KeyPair::from_bytes(
501 bytes
502 .get(1..)
503 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
504 )?)),
505 SignatureScheme::Secp256k1 => Ok(Self::Secp256k1(Secp256k1KeyPair::from_bytes(
506 bytes
507 .get(1..)
508 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
509 )?)),
510 SignatureScheme::Secp256r1 => Ok(Self::Secp256r1(Secp256r1KeyPair::from_bytes(
511 bytes
512 .get(1..)
513 .ok_or(FastCryptoError::InputLengthWrong(bytes.len()))?,
514 )?)),
515 _ => Err(FastCryptoError::GeneralError(
516 "Invalid flag byte".to_string(),
517 )),
518 },
519 _ => Err(FastCryptoError::InvalidInput),
520 }
521 }
522 pub fn encode(&self) -> Result<String, FastCryptoError> {
524 Bech32::encode(self.to_bytes(), SUI_PRIV_KEY_PREFIX)
525 }
526
527 pub fn decode(value: &str) -> Result<Self, FastCryptoError> {
529 let bytes = Bech32::decode(value, SUI_PRIV_KEY_PREFIX)?;
530 Self::from_bytes(&bytes)
531 }
532}
533
534impl Serialize for SuiKeyPair {
535 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
536 where
537 S: Serializer,
538 {
539 let s = self.encode_base64();
540 serializer.serialize_str(&s)
541 }
542}
543
544impl<'de> Deserialize<'de> for SuiKeyPair {
545 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
546 where
547 D: Deserializer<'de>,
548 {
549 use serde::de::Error;
550 let s = String::deserialize(deserializer)?;
551 Self::decode_base64(&s).map_err(|e| Error::custom(e.to_string()))
552 }
553}
554
555#[serde_as]
560#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
561#[as_ref(forward)]
562#[as_mut(forward)]
563pub struct Ed25519SuiSignature(
564 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
565 [u8; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1],
566);
567
568impl Default for Ed25519SuiSignature {
570 fn default() -> Self {
571 Self([0; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1])
572 }
573}
574
575impl SuiSignatureInner for Ed25519SuiSignature {
576 type Sig = Ed25519Signature;
577 type PubKey = Ed25519PublicKey;
578 type KeyPair = Ed25519KeyPair;
579 const LENGTH: usize = Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1;
580}
581
582impl SuiPublicKey for Ed25519PublicKey {
583 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::ED25519;
584}
585
586impl ToFromBytes for Ed25519SuiSignature {
587 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
588 if bytes.len() != Self::LENGTH {
589 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
590 }
591 let mut sig_bytes = [0; Self::LENGTH];
592 sig_bytes.copy_from_slice(bytes);
593 Ok(Self(sig_bytes))
594 }
595}
596
597impl Signer<Signature> for Ed25519KeyPair {
598 fn sign(&self, msg: &[u8]) -> Signature {
599 Ed25519SuiSignature::new(self, msg).into()
600 }
601}
602
603#[serde_as]
608#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
609#[as_ref(forward)]
610#[as_mut(forward)]
611pub struct Secp256k1SuiSignature(
612 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
613 [u8; Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1],
614);
615
616impl SuiSignatureInner for Secp256k1SuiSignature {
617 type Sig = Secp256k1Signature;
618 type PubKey = Secp256k1PublicKey;
619 type KeyPair = Secp256k1KeyPair;
620 const LENGTH: usize = Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1;
621}
622
623impl SuiPublicKey for Secp256k1PublicKey {
624 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256k1;
625}
626
627impl ToFromBytes for Secp256k1SuiSignature {
628 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
629 if bytes.len() != Self::LENGTH {
630 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
631 }
632 let mut sig_bytes = [0; Self::LENGTH];
633 sig_bytes.copy_from_slice(bytes);
634 Ok(Self(sig_bytes))
635 }
636}
637
638impl Signer<Signature> for Secp256k1KeyPair {
639 fn sign(&self, msg: &[u8]) -> Signature {
640 Secp256k1SuiSignature::new(self, msg).into()
641 }
642}
643
644#[serde_as]
649#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
650#[as_ref(forward)]
651#[as_mut(forward)]
652pub struct Secp256r1SuiSignature(
653 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
654 [u8; Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1],
655);
656
657impl SuiSignatureInner for Secp256r1SuiSignature {
658 type Sig = Secp256r1Signature;
659 type PubKey = Secp256r1PublicKey;
660 type KeyPair = Secp256r1KeyPair;
661 const LENGTH: usize = Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1;
662}
663
664impl SuiPublicKey for Secp256r1PublicKey {
665 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256r1;
666}
667
668impl ToFromBytes for Secp256r1SuiSignature {
669 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
670 if bytes.len() != Self::LENGTH {
671 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
672 }
673 let mut sig_bytes = [0; Self::LENGTH];
674 sig_bytes.copy_from_slice(bytes);
675 Ok(Self(sig_bytes))
676 }
677}
678
679impl Signer<Signature> for Secp256r1KeyPair {
680 fn sign(&self, msg: &[u8]) -> Signature {
681 Secp256r1SuiSignature::new(self, msg).into()
682 }
683}
684
685pub trait SuiSignatureInner: Sized + ToFromBytes + PartialEq + Eq + Hash {
690 type Sig: Authenticator<PubKey = Self::PubKey>;
691 type PubKey: VerifyingKey<Sig = Self::Sig> + SuiPublicKey;
692 type KeyPair: KeypairTraits<PubKey = Self::PubKey, Sig = Self::Sig>;
693
694 const LENGTH: usize = Self::Sig::LENGTH + Self::PubKey::LENGTH + 1;
695 const SCHEME: SignatureScheme = Self::PubKey::SIGNATURE_SCHEME;
696
697 fn get_verification_inputs(&self) -> Result<(Self::Sig, Self::PubKey), Error> {
699 let pk = Self::PubKey::from_bytes(self.public_key_bytes())
700 .map_err(|_| Error::KeyConversionError("Invalid public key".to_string()))?;
701
702 let signature =
704 Self::Sig::from_bytes(self.signature_bytes()).map_err(|_| Error::InvalidSignature {
705 error: "Fail to get pubkey and sig".to_string(),
706 })?;
707
708 Ok((signature, pk))
709 }
710
711 fn new(kp: &Self::KeyPair, message: &[u8]) -> Self {
712 let sig = Signer::sign(kp, message);
713
714 let mut signature_bytes: Vec<u8> = Vec::new();
715 signature_bytes
716 .extend_from_slice(&[<Self::PubKey as SuiPublicKey>::SIGNATURE_SCHEME.flag()]);
717 signature_bytes.extend_from_slice(sig.as_ref());
718 signature_bytes.extend_from_slice(kp.public().as_ref());
719 Self::from_bytes(&signature_bytes[..])
720 .expect("Serialized signature did not have expected size")
721 }
722}
723
724#[enum_dispatch(Signature)]
725pub trait SuiSignature: Sized + ToFromBytes {
726 fn signature_bytes(&self) -> &[u8];
727 fn public_key_bytes(&self) -> &[u8];
728 fn scheme(&self) -> SignatureScheme;
729
730 fn verify_secure<T>(
731 &self,
732 value: &IntentMessage<T>,
733 author: SuiAddress,
734 scheme: SignatureScheme,
735 ) -> Result<(), Error>
736 where
737 T: Serialize;
738}
739
740impl<S: SuiSignatureInner + Sized> SuiSignature for S {
741 fn signature_bytes(&self) -> &[u8] {
742 &self.as_ref()[1..1 + S::Sig::LENGTH]
745 }
746
747 fn public_key_bytes(&self) -> &[u8] {
748 &self.as_ref()[S::Sig::LENGTH + 1..]
751 }
752
753 fn scheme(&self) -> SignatureScheme {
754 S::PubKey::SIGNATURE_SCHEME
755 }
756
757 fn verify_secure<T>(
758 &self,
759 value: &IntentMessage<T>,
760 author: SuiAddress,
761 scheme: SignatureScheme,
762 ) -> Result<(), Error>
763 where
764 T: Serialize,
765 {
766 let mut hasher = DefaultHash::default();
767 hasher.update(
768 value
769 .to_bcs()
770 .expect("Message serialization should not fail"),
771 );
772 let digest = hasher.finalize().digest;
773
774 let (sig, pk) = &self.get_verification_inputs()?;
775 match scheme {
776 SignatureScheme::ZkLoginAuthenticator => {} _ => {
778 let address = pk.to_sui_address();
779 if author != address {
780 return Err(Error::IncorrectSigner {
781 error: format!(
782 "Incorrect signer, expected {:?}, got {:?}",
783 author, address
784 ),
785 });
786 }
787 }
788 }
789
790 pk.verify(&digest, sig)
791 .map_err(|e| Error::InvalidSignature {
792 error: format!("Fail to verify user sig {}", e),
793 })
794 }
795}
796
797pub trait SuiPublicKey: VerifyingKey {
802 const SIGNATURE_SCHEME: SignatureScheme;
803
804 fn to_sui_address(&self) -> SuiAddress {
809 let mut hasher = DefaultHash::default();
810 hasher.update([Self::SIGNATURE_SCHEME.flag()]);
811 hasher.update(self);
812 let g_arr = hasher.finalize();
813 SuiAddress::new(g_arr.digest)
814 }
815}