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, eyre::Report> {
137 let bytes = Base64Wrapper::decode(value).map_err(|e| eyre!("{}", e.to_string()))?;
138 match bytes.first() {
139 Some(x) => {
140 if x == &SignatureScheme::ED25519.flag() {
141 let pk: Ed25519PublicKey = Ed25519PublicKey::from_bytes(
142 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
143 )?;
144 Ok(Self::Ed25519((&pk).into()))
145 } else if x == &SignatureScheme::Secp256k1.flag() {
146 let pk = Secp256k1PublicKey::from_bytes(
147 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
148 )?;
149 Ok(Self::Secp256k1((&pk).into()))
150 } else if x == &SignatureScheme::Secp256r1.flag() {
151 let pk = Secp256r1PublicKey::from_bytes(
152 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
153 )?;
154 Ok(Self::Secp256r1((&pk).into()))
155 } else {
156 Err(eyre!("Invalid flag byte"))
157 }
158 }
159 _ => Err(eyre!("Invalid bytes")),
160 }
161 }
162}
163
164impl PublicKey {
165 pub fn to_sui_address(&self) -> SuiAddress {
170 let mut hasher = DefaultHash::default();
171 hasher.update([self.flag()]);
172 hasher.update(self);
173 let g_arr = hasher.finalize();
174 SuiAddress::new(g_arr.digest)
175 }
176
177 pub const fn flag(&self) -> u8 {
178 self.scheme().flag()
179 }
180
181 pub fn try_from_bytes(curve: SignatureScheme, key_bytes: &[u8]) -> Result<Self, eyre::Report> {
182 match curve {
183 SignatureScheme::ED25519 => Ok(Self::Ed25519(
184 (&Ed25519PublicKey::from_bytes(key_bytes)?).into(),
185 )),
186 SignatureScheme::Secp256k1 => Ok(Self::Secp256k1(
187 (&Secp256k1PublicKey::from_bytes(key_bytes)?).into(),
188 )),
189 SignatureScheme::Secp256r1 => Ok(Self::Secp256r1(
190 (&Secp256r1PublicKey::from_bytes(key_bytes)?).into(),
191 )),
192 _ => Err(eyre!("Unsupported curve")),
193 }
194 }
195
196 pub const fn scheme(&self) -> SignatureScheme {
197 match self {
198 Self::Ed25519(_) => Ed25519SuiSignature::SCHEME,
199 Self::Secp256k1(_) => Secp256k1SuiSignature::SCHEME,
200 Self::Secp256r1(_) => Secp256r1SuiSignature::SCHEME,
201 Self::ZkLogin(_) => SignatureScheme::ZkLoginAuthenticator,
202 }
203 }
204}
205#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
208pub struct ZkLoginPublicIdentifier(pub Vec<u8>);
209
210#[enum_dispatch]
216#[derive(Clone, Debug, PartialEq, Eq, Hash)]
217pub enum Signature {
218 Ed25519SuiSignature,
219 Secp256k1SuiSignature,
220 Secp256r1SuiSignature,
221}
222
223impl Signature {
224 pub fn new_hashed(hashed_msg: &[u8], secret: &dyn Signer<Self>) -> Self {
226 Signer::sign(secret, hashed_msg)
227 }
228
229 pub fn new_secure<T>(value: &IntentMessage<T>, secret: &dyn Signer<Self>) -> Self
230 where
231 T: Serialize,
232 {
233 let mut hasher = DefaultHash::default();
234 hasher.update(bcs::to_bytes(&value).expect("Message serialization should not fail"));
235 Signer::sign(secret, &hasher.finalize().digest)
236 }
237
238 pub fn to_compressed(&self) -> Result<CompressedSignature, Error> {
239 let bytes = self.signature_bytes();
240 match self.scheme() {
241 SignatureScheme::ED25519 => Ok(CompressedSignature::Ed25519(
242 (&Ed25519Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
243 error: "Cannot parse ed25519 sig".to_string(),
244 })?)
245 .into(),
246 )),
247 SignatureScheme::Secp256k1 => Ok(CompressedSignature::Secp256k1(
248 (&Secp256k1Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
249 error: "Cannot parse secp256k1 sig".to_string(),
250 })?)
251 .into(),
252 )),
253 SignatureScheme::Secp256r1 => Ok(CompressedSignature::Secp256r1(
254 (&Secp256r1Signature::from_bytes(bytes).map_err(|_| Error::InvalidSignature {
255 error: "Cannot parse secp256r1 sig".to_string(),
256 })?)
257 .into(),
258 )),
259 _ => Err(Error::UnsupportedFeatureError {
260 error: "Unsupported signature scheme".to_string(),
261 }),
262 }
263 }
264
265 pub fn to_public_key(&self) -> Result<PublicKey, Error> {
266 let bytes = self.public_key_bytes();
267 match self.scheme() {
268 SignatureScheme::ED25519 => Ok(PublicKey::Ed25519(
269 (&Ed25519PublicKey::from_bytes(bytes).map_err(|_| {
270 Error::KeyConversionError("Cannot parse ed25519 pk".to_string())
271 })?)
272 .into(),
273 )),
274 SignatureScheme::Secp256k1 => Ok(PublicKey::Secp256k1(
275 (&Secp256k1PublicKey::from_bytes(bytes).map_err(|_| {
276 Error::KeyConversionError("Cannot parse secp256k1 pk".to_string())
277 })?)
278 .into(),
279 )),
280 SignatureScheme::Secp256r1 => Ok(PublicKey::Secp256r1(
281 (&Secp256r1PublicKey::from_bytes(bytes).map_err(|_| {
282 Error::KeyConversionError("Cannot parse secp256r1 pk".to_string())
283 })?)
284 .into(),
285 )),
286 _ => Err(Error::UnsupportedFeatureError {
287 error: "Unsupported signature scheme in Signature".to_string(),
288 }),
289 }
290 }
291}
292
293impl Serialize for Signature {
294 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
295 where
296 S: Serializer,
297 {
298 let bytes = self.as_ref();
299
300 if serializer.is_human_readable() {
301 let s = Base64Wrapper::encode(bytes);
302 serializer.serialize_str(&s)
303 } else {
304 serializer.serialize_bytes(bytes)
305 }
306 }
307}
308
309impl<'de> Deserialize<'de> for Signature {
310 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
311 where
312 D: Deserializer<'de>,
313 {
314 use serde::de::Error;
315
316 let bytes = if deserializer.is_human_readable() {
317 let s = String::deserialize(deserializer)?;
318 Base64Wrapper::decode(&s).map_err(|e| Error::custom(e.to_string()))?
319 } else {
320 let data: Vec<u8> = Vec::deserialize(deserializer)?;
321 data
322 };
323
324 Self::from_bytes(&bytes).map_err(|e| Error::custom(e.to_string()))
325 }
326}
327
328impl AsRef<[u8]> for Signature {
329 fn as_ref(&self) -> &[u8] {
330 match self {
331 Self::Ed25519SuiSignature(sig) => sig.as_ref(),
332 Self::Secp256k1SuiSignature(sig) => sig.as_ref(),
333 Self::Secp256r1SuiSignature(sig) => sig.as_ref(),
334 }
335 }
336}
337impl AsMut<[u8]> for Signature {
338 fn as_mut(&mut self) -> &mut [u8] {
339 match self {
340 Self::Ed25519SuiSignature(sig) => sig.as_mut(),
341 Self::Secp256k1SuiSignature(sig) => sig.as_mut(),
342 Self::Secp256r1SuiSignature(sig) => sig.as_mut(),
343 }
344 }
345}
346
347impl ToFromBytes for Signature {
348 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
349 match bytes.first() {
350 Some(x) => {
351 if x == &Ed25519SuiSignature::SCHEME.flag() {
352 Ok(<Ed25519SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
353 } else if x == &Secp256k1SuiSignature::SCHEME.flag() {
354 Ok(<Secp256k1SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
355 } else if x == &Secp256r1SuiSignature::SCHEME.flag() {
356 Ok(<Secp256r1SuiSignature as ToFromBytes>::from_bytes(bytes)?.into())
357 } else {
358 Err(FastCryptoError::InvalidInput)
359 }
360 }
361 _ => Err(FastCryptoError::InvalidInput),
362 }
363 }
364}
365
366impl From<Signature> for af_sui_types::UserSignature {
367 fn from(value: Signature) -> Self {
368 Self::from_bytes(value.as_bytes()).expect("Compatible")
369 }
370}
371
372#[derive(Clone, Copy, Deserialize, Serialize, Debug, EnumString, strum::Display)]
377#[strum(serialize_all = "lowercase")]
378pub enum SignatureScheme {
379 ED25519,
380 Secp256k1,
381 Secp256r1,
382 BLS12381, MultiSig,
384 ZkLoginAuthenticator,
385}
386
387impl SignatureScheme {
388 pub const fn flag(&self) -> u8 {
389 match self {
390 Self::ED25519 => 0x00,
391 Self::Secp256k1 => 0x01,
392 Self::Secp256r1 => 0x02,
393 Self::MultiSig => 0x03,
394 Self::BLS12381 => 0x04, Self::ZkLoginAuthenticator => 0x05,
396 }
397 }
398
399 pub fn from_flag(flag: &str) -> Result<Self, Error> {
400 let byte_int = flag
401 .parse::<u8>()
402 .map_err(|_| Error::KeyConversionError("Invalid key scheme".to_string()))?;
403 Self::from_flag_byte(&byte_int)
404 }
405
406 pub fn from_flag_byte(byte_int: &u8) -> Result<Self, Error> {
407 match byte_int {
408 0x00 => Ok(Self::ED25519),
409 0x01 => Ok(Self::Secp256k1),
410 0x02 => Ok(Self::Secp256r1),
411 0x03 => Ok(Self::MultiSig),
412 0x04 => Ok(Self::BLS12381),
413 0x05 => Ok(Self::ZkLoginAuthenticator),
414 _ => Err(Error::KeyConversionError("Invalid key scheme".to_string())),
415 }
416 }
417}
418
419#[allow(clippy::large_enum_variant)]
424#[derive(Debug, derive_more::From, PartialEq, Eq)]
425pub enum SuiKeyPair {
426 Ed25519(Ed25519KeyPair),
427 Secp256k1(Secp256k1KeyPair),
428 Secp256r1(Secp256r1KeyPair),
429}
430
431impl SuiKeyPair {
432 pub fn public(&self) -> PublicKey {
433 match self {
434 Self::Ed25519(kp) => PublicKey::Ed25519(kp.public().into()),
435 Self::Secp256k1(kp) => PublicKey::Secp256k1(kp.public().into()),
436 Self::Secp256r1(kp) => PublicKey::Secp256r1(kp.public().into()),
437 }
438 }
439}
440
441impl Signer<Signature> for SuiKeyPair {
442 fn sign(&self, msg: &[u8]) -> Signature {
443 match self {
444 Self::Ed25519(kp) => kp.sign(msg),
445 Self::Secp256k1(kp) => kp.sign(msg),
446 Self::Secp256r1(kp) => kp.sign(msg),
447 }
448 }
449}
450
451impl EncodeDecodeBase64 for SuiKeyPair {
452 fn encode_base64(&self) -> String {
453 Base64Wrapper::encode(self.to_bytes())
454 }
455
456 fn decode_base64(value: &str) -> Result<Self, eyre::Report> {
457 let bytes = Base64Wrapper::decode(value).map_err(|e| eyre!("{}", e.to_string()))?;
458 Self::from_bytes(&bytes)
459 }
460}
461impl SuiKeyPair {
462 pub fn to_bytes(&self) -> Vec<u8> {
463 let mut bytes: Vec<u8> = Vec::new();
464 bytes.push(self.public().flag());
465
466 match self {
467 Self::Ed25519(kp) => {
468 bytes.extend_from_slice(kp.as_bytes());
469 }
470 Self::Secp256k1(kp) => {
471 bytes.extend_from_slice(kp.as_bytes());
472 }
473 Self::Secp256r1(kp) => {
474 bytes.extend_from_slice(kp.as_bytes());
475 }
476 }
477 bytes
478 }
479
480 pub fn from_bytes(bytes: &[u8]) -> Result<Self, eyre::Report> {
481 match SignatureScheme::from_flag_byte(bytes.first().ok_or_else(|| eyre!("Invalid length"))?)
482 {
483 Ok(x) => match x {
484 SignatureScheme::ED25519 => Ok(Self::Ed25519(Ed25519KeyPair::from_bytes(
485 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
486 )?)),
487 SignatureScheme::Secp256k1 => Ok(Self::Secp256k1(Secp256k1KeyPair::from_bytes(
488 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
489 )?)),
490 SignatureScheme::Secp256r1 => Ok(Self::Secp256r1(Secp256r1KeyPair::from_bytes(
491 bytes.get(1..).ok_or_else(|| eyre!("Invalid length"))?,
492 )?)),
493 _ => Err(eyre!("Invalid flag byte")),
494 },
495 _ => Err(eyre!("Invalid bytes")),
496 }
497 }
498 pub fn encode(&self) -> Result<String, eyre::Report> {
500 Bech32::encode(self.to_bytes(), SUI_PRIV_KEY_PREFIX)
501 }
502
503 pub fn decode(value: &str) -> Result<Self, eyre::Report> {
505 let bytes = Bech32::decode(value, SUI_PRIV_KEY_PREFIX)?;
506 Self::from_bytes(&bytes)
507 }
508}
509
510impl Serialize for SuiKeyPair {
511 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
512 where
513 S: Serializer,
514 {
515 let s = self.encode_base64();
516 serializer.serialize_str(&s)
517 }
518}
519
520impl<'de> Deserialize<'de> for SuiKeyPair {
521 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
522 where
523 D: Deserializer<'de>,
524 {
525 use serde::de::Error;
526 let s = String::deserialize(deserializer)?;
527 Self::decode_base64(&s).map_err(|e| Error::custom(e.to_string()))
528 }
529}
530
531#[serde_as]
536#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
537#[as_ref(forward)]
538#[as_mut(forward)]
539pub struct Ed25519SuiSignature(
540 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
541 [u8; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1],
542);
543
544impl Default for Ed25519SuiSignature {
546 fn default() -> Self {
547 Self([0; Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1])
548 }
549}
550
551impl SuiSignatureInner for Ed25519SuiSignature {
552 type Sig = Ed25519Signature;
553 type PubKey = Ed25519PublicKey;
554 type KeyPair = Ed25519KeyPair;
555 const LENGTH: usize = Ed25519PublicKey::LENGTH + Ed25519Signature::LENGTH + 1;
556}
557
558impl SuiPublicKey for Ed25519PublicKey {
559 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::ED25519;
560}
561
562impl ToFromBytes for Ed25519SuiSignature {
563 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
564 if bytes.len() != Self::LENGTH {
565 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
566 }
567 let mut sig_bytes = [0; Self::LENGTH];
568 sig_bytes.copy_from_slice(bytes);
569 Ok(Self(sig_bytes))
570 }
571}
572
573impl Signer<Signature> for Ed25519KeyPair {
574 fn sign(&self, msg: &[u8]) -> Signature {
575 Ed25519SuiSignature::new(self, msg).into()
576 }
577}
578
579#[serde_as]
584#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
585#[as_ref(forward)]
586#[as_mut(forward)]
587pub struct Secp256k1SuiSignature(
588 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
589 [u8; Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1],
590);
591
592impl SuiSignatureInner for Secp256k1SuiSignature {
593 type Sig = Secp256k1Signature;
594 type PubKey = Secp256k1PublicKey;
595 type KeyPair = Secp256k1KeyPair;
596 const LENGTH: usize = Secp256k1PublicKey::LENGTH + Secp256k1Signature::LENGTH + 1;
597}
598
599impl SuiPublicKey for Secp256k1PublicKey {
600 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256k1;
601}
602
603impl ToFromBytes for Secp256k1SuiSignature {
604 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
605 if bytes.len() != Self::LENGTH {
606 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
607 }
608 let mut sig_bytes = [0; Self::LENGTH];
609 sig_bytes.copy_from_slice(bytes);
610 Ok(Self(sig_bytes))
611 }
612}
613
614impl Signer<Signature> for Secp256k1KeyPair {
615 fn sign(&self, msg: &[u8]) -> Signature {
616 Secp256k1SuiSignature::new(self, msg).into()
617 }
618}
619
620#[serde_as]
625#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, AsRef, AsMut)]
626#[as_ref(forward)]
627#[as_mut(forward)]
628pub struct Secp256r1SuiSignature(
629 #[serde_as(as = "IfIsHumanReadable<Base64, Bytes>")]
630 [u8; Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1],
631);
632
633impl SuiSignatureInner for Secp256r1SuiSignature {
634 type Sig = Secp256r1Signature;
635 type PubKey = Secp256r1PublicKey;
636 type KeyPair = Secp256r1KeyPair;
637 const LENGTH: usize = Secp256r1PublicKey::LENGTH + Secp256r1Signature::LENGTH + 1;
638}
639
640impl SuiPublicKey for Secp256r1PublicKey {
641 const SIGNATURE_SCHEME: SignatureScheme = SignatureScheme::Secp256r1;
642}
643
644impl ToFromBytes for Secp256r1SuiSignature {
645 fn from_bytes(bytes: &[u8]) -> Result<Self, FastCryptoError> {
646 if bytes.len() != Self::LENGTH {
647 return Err(FastCryptoError::InputLengthWrong(Self::LENGTH));
648 }
649 let mut sig_bytes = [0; Self::LENGTH];
650 sig_bytes.copy_from_slice(bytes);
651 Ok(Self(sig_bytes))
652 }
653}
654
655impl Signer<Signature> for Secp256r1KeyPair {
656 fn sign(&self, msg: &[u8]) -> Signature {
657 Secp256r1SuiSignature::new(self, msg).into()
658 }
659}
660
661pub trait SuiSignatureInner: Sized + ToFromBytes + PartialEq + Eq + Hash {
666 type Sig: Authenticator<PubKey = Self::PubKey>;
667 type PubKey: VerifyingKey<Sig = Self::Sig> + SuiPublicKey;
668 type KeyPair: KeypairTraits<PubKey = Self::PubKey, Sig = Self::Sig>;
669
670 const LENGTH: usize = Self::Sig::LENGTH + Self::PubKey::LENGTH + 1;
671 const SCHEME: SignatureScheme = Self::PubKey::SIGNATURE_SCHEME;
672
673 fn get_verification_inputs(&self) -> Result<(Self::Sig, Self::PubKey), Error> {
675 let pk = Self::PubKey::from_bytes(self.public_key_bytes())
676 .map_err(|_| Error::KeyConversionError("Invalid public key".to_string()))?;
677
678 let signature =
680 Self::Sig::from_bytes(self.signature_bytes()).map_err(|_| Error::InvalidSignature {
681 error: "Fail to get pubkey and sig".to_string(),
682 })?;
683
684 Ok((signature, pk))
685 }
686
687 fn new(kp: &Self::KeyPair, message: &[u8]) -> Self {
688 let sig = Signer::sign(kp, message);
689
690 let mut signature_bytes: Vec<u8> = Vec::new();
691 signature_bytes
692 .extend_from_slice(&[<Self::PubKey as SuiPublicKey>::SIGNATURE_SCHEME.flag()]);
693 signature_bytes.extend_from_slice(sig.as_ref());
694 signature_bytes.extend_from_slice(kp.public().as_ref());
695 Self::from_bytes(&signature_bytes[..])
696 .expect("Serialized signature did not have expected size")
697 }
698}
699
700#[enum_dispatch(Signature)]
701pub trait SuiSignature: Sized + ToFromBytes {
702 fn signature_bytes(&self) -> &[u8];
703 fn public_key_bytes(&self) -> &[u8];
704 fn scheme(&self) -> SignatureScheme;
705
706 fn verify_secure<T>(
707 &self,
708 value: &IntentMessage<T>,
709 author: SuiAddress,
710 scheme: SignatureScheme,
711 ) -> Result<(), Error>
712 where
713 T: Serialize;
714}
715
716impl<S: SuiSignatureInner + Sized> SuiSignature for S {
717 fn signature_bytes(&self) -> &[u8] {
718 &self.as_ref()[1..1 + S::Sig::LENGTH]
721 }
722
723 fn public_key_bytes(&self) -> &[u8] {
724 &self.as_ref()[S::Sig::LENGTH + 1..]
727 }
728
729 fn scheme(&self) -> SignatureScheme {
730 S::PubKey::SIGNATURE_SCHEME
731 }
732
733 fn verify_secure<T>(
734 &self,
735 value: &IntentMessage<T>,
736 author: SuiAddress,
737 scheme: SignatureScheme,
738 ) -> Result<(), Error>
739 where
740 T: Serialize,
741 {
742 let mut hasher = DefaultHash::default();
743 hasher.update(bcs::to_bytes(&value).expect("Message serialization should not fail"));
744 let digest = hasher.finalize().digest;
745
746 let (sig, pk) = &self.get_verification_inputs()?;
747 match scheme {
748 SignatureScheme::ZkLoginAuthenticator => {} _ => {
750 let address = pk.to_sui_address();
751 if author != address {
752 return Err(Error::IncorrectSigner {
753 error: format!(
754 "Incorrect signer, expected {:?}, got {:?}",
755 author, address
756 ),
757 });
758 }
759 }
760 }
761
762 pk.verify(&digest, sig)
763 .map_err(|e| Error::InvalidSignature {
764 error: format!("Fail to verify user sig {}", e),
765 })
766 }
767}
768
769pub trait SuiPublicKey: VerifyingKey {
774 const SIGNATURE_SCHEME: SignatureScheme;
775
776 fn to_sui_address(&self) -> SuiAddress {
781 let mut hasher = DefaultHash::default();
782 hasher.update([Self::SIGNATURE_SCHEME.flag()]);
783 hasher.update(self);
784 let g_arr = hasher.finalize();
785 SuiAddress::new(g_arr.digest)
786 }
787}