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