1use std::fmt::{self, Display};
3use std::str::FromStr;
4
5use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
6use data_encoding::{HEXLOWER, HEXUPPER};
7use namada_macros::BorshDeserializer;
8#[cfg(feature = "migrations")]
9use namada_migrations::*;
10#[cfg(any(test, feature = "rand"))]
11use rand::{CryptoRng, RngCore};
12use serde::de::{self, Visitor};
13use serde::{Deserialize, Deserializer, Serialize, Serializer};
14use thiserror::Error;
15
16use super::{
17 ParsePublicKeyError, ParseSecretKeyError, ParseSignatureError, RefTo,
18 SchemeType, SigScheme as SigSchemeTrait, VerifySigError, ed25519,
19 secp256k1,
20};
21use crate::borsh::BorshSerializeExt;
22use crate::ethereum_events::EthAddress;
23use crate::key::{SignableBytes, StorageHasher};
24use crate::{impl_display_and_from_str_via_format, string_encoding};
25
26#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
28#[derive(
29 Clone,
30 Debug,
31 Eq,
32 PartialEq,
33 Ord,
34 PartialOrd,
35 Hash,
36 BorshSerialize,
37 BorshDeserialize,
38 BorshDeserializer,
39 BorshSchema,
40)]
41pub enum CommonPublicKey {
42 Ed25519(ed25519::PublicKey),
44 Secp256k1(secp256k1::PublicKey),
46}
47
48pub type PublicKey = CommonPublicKey;
50
51const ED25519_PK_PREFIX: &str = "ED25519_PK_PREFIX";
52const SECP256K1_PK_PREFIX: &str = "SECP256K1_PK_PREFIX";
53
54impl Serialize for PublicKey {
55 fn serialize<S>(
56 &self,
57 serializer: S,
58 ) -> std::result::Result<S::Ok, S::Error>
59 where
60 S: serde::Serializer,
61 {
62 let prefix = match self {
64 PublicKey::Ed25519(_) => ED25519_PK_PREFIX,
65 PublicKey::Secp256k1(_) => SECP256K1_PK_PREFIX,
66 };
67 let keypair_string = format!("{}{}", prefix, self);
68 Serialize::serialize(&keypair_string, serializer)
69 }
70}
71
72impl<'de> Deserialize<'de> for PublicKey {
73 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
74 where
75 D: serde::Deserializer<'de>,
76 {
77 use serde::de::Error;
78
79 let keypair_string: String =
80 serde::Deserialize::deserialize(deserializer)
81 .map_err(D::Error::custom)?;
82 if let Some(raw) = keypair_string.strip_prefix(ED25519_PK_PREFIX) {
83 PublicKey::from_str(raw).map_err(D::Error::custom)
84 } else if let Some(raw) =
85 keypair_string.strip_prefix(SECP256K1_PK_PREFIX)
86 {
87 PublicKey::from_str(raw).map_err(D::Error::custom)
88 } else {
89 Err(D::Error::custom(
90 "Could not deserialize SecretKey do to invalid prefix",
91 ))
92 }
93 }
94}
95
96impl super::PublicKey for PublicKey {
97 const TYPE: SchemeType = SigScheme::TYPE;
98
99 fn try_from_pk<PK: super::PublicKey>(
100 pk: &PK,
101 ) -> Result<Self, ParsePublicKeyError> {
102 if PK::TYPE == Self::TYPE {
103 Self::try_from_slice(pk.serialize_to_vec().as_slice())
104 .map_err(ParsePublicKeyError::InvalidEncoding)
105 } else if PK::TYPE == ed25519::PublicKey::TYPE {
106 Ok(Self::Ed25519(
107 ed25519::PublicKey::try_from_slice(
108 pk.serialize_to_vec().as_slice(),
109 )
110 .map_err(ParsePublicKeyError::InvalidEncoding)?,
111 ))
112 } else if PK::TYPE == secp256k1::PublicKey::TYPE {
113 Ok(Self::Secp256k1(
114 secp256k1::PublicKey::try_from_slice(
115 pk.serialize_to_vec().as_slice(),
116 )
117 .map_err(ParsePublicKeyError::InvalidEncoding)?,
118 ))
119 } else {
120 Err(ParsePublicKeyError::MismatchedScheme)
121 }
122 }
123}
124
125pub type DecodeError = string_encoding::DecodeError;
127
128impl string_encoding::Format for PublicKey {
129 type EncodedBytes<'a> = Vec<u8>;
130
131 const HRP: string_encoding::Hrp =
132 string_encoding::Hrp::parse_unchecked(string_encoding::COMMON_PK_HRP);
133
134 fn to_bytes(&self) -> Vec<u8> {
135 self.serialize_to_vec()
136 }
137
138 fn decode_bytes(
139 bytes: &[u8],
140 ) -> Result<Self, string_encoding::DecodeError> {
141 BorshDeserialize::try_from_slice(bytes)
142 .map_err(DecodeError::InvalidBytes)
143 }
144}
145
146impl_display_and_from_str_via_format!(PublicKey);
147
148impl From<PublicKey> for crate::tendermint::PublicKey {
149 fn from(value: PublicKey) -> Self {
150 use crate::tendermint::PublicKey as TmPK;
151 match value {
152 PublicKey::Ed25519(ed25519::PublicKey(pk)) => {
153 TmPK::from_raw_ed25519(pk.as_bytes()).unwrap()
154 }
155 PublicKey::Secp256k1(secp256k1::PublicKey(pk)) => {
156 TmPK::from_raw_secp256k1(&pk.to_sec1_bytes()).unwrap()
157 }
158 }
159 }
160}
161
162#[allow(missing_docs)]
163#[derive(Error, Debug)]
164pub enum EthAddressConvError {
165 #[error("Eth key cannot be ed25519, only secp256k1")]
166 CannotBeEd25519,
167}
168
169impl TryFrom<&PublicKey> for EthAddress {
170 type Error = EthAddressConvError;
171
172 fn try_from(value: &PublicKey) -> Result<Self, Self::Error> {
173 match value {
174 PublicKey::Ed25519(_) => Err(EthAddressConvError::CannotBeEd25519),
175 PublicKey::Secp256k1(pk) => Ok(EthAddress::from(pk)),
176 }
177 }
178}
179
180#[derive(
182 Debug,
183 Clone,
184 BorshSerialize,
185 BorshDeserialize,
186 BorshDeserializer,
187 BorshSchema,
188)]
189#[allow(clippy::large_enum_variant)]
190pub enum SecretKey {
191 Ed25519(ed25519::SecretKey),
193 Secp256k1(secp256k1::SecretKey),
195}
196
197impl Serialize for SecretKey {
198 fn serialize<S>(
199 &self,
200 serializer: S,
201 ) -> std::result::Result<S::Ok, S::Error>
202 where
203 S: serde::Serializer,
204 {
205 let prefix = match self {
207 SecretKey::Ed25519(_) => "ED25519_SK_PREFIX",
208 SecretKey::Secp256k1(_) => "SECP256K1_SK_PREFIX",
209 };
210 let keypair_string = format!("{}{}", prefix, self);
211 Serialize::serialize(&keypair_string, serializer)
212 }
213}
214
215impl<'de> Deserialize<'de> for SecretKey {
216 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
217 where
218 D: serde::Deserializer<'de>,
219 {
220 use serde::de::Error;
221
222 let keypair_string: String =
223 serde::Deserialize::deserialize(deserializer)
224 .map_err(D::Error::custom)?;
225 if let Some(raw) = keypair_string.strip_prefix("ED25519_SK_PREFIX") {
226 SecretKey::from_str(raw).map_err(D::Error::custom)
227 } else if let Some(raw) =
228 keypair_string.strip_prefix("SECP256K1_SK_PREFIX")
229 {
230 SecretKey::from_str(raw).map_err(D::Error::custom)
231 } else {
232 Err(D::Error::custom(
233 "Could not deserialize SecretKey do to invalid prefix",
234 ))
235 }
236 }
237}
238
239impl SecretKey {
240 pub fn to_public(&self) -> PublicKey {
242 self.ref_to()
243 }
244}
245
246impl super::SecretKey for SecretKey {
247 type PublicKey = PublicKey;
248
249 const TYPE: SchemeType = SigScheme::TYPE;
250
251 fn try_from_sk<SK: super::SecretKey>(
252 sk: &SK,
253 ) -> Result<Self, ParseSecretKeyError> {
254 if SK::TYPE == Self::TYPE {
255 Self::try_from_slice(sk.serialize_to_vec().as_ref())
256 .map_err(ParseSecretKeyError::InvalidEncoding)
257 } else if SK::TYPE == ed25519::SecretKey::TYPE {
258 Ok(Self::Ed25519(
259 ed25519::SecretKey::try_from_slice(
260 sk.serialize_to_vec().as_ref(),
261 )
262 .map_err(ParseSecretKeyError::InvalidEncoding)?,
263 ))
264 } else if SK::TYPE == secp256k1::SecretKey::TYPE {
265 Ok(Self::Secp256k1(
266 secp256k1::SecretKey::try_from_slice(
267 sk.serialize_to_vec().as_ref(),
268 )
269 .map_err(ParseSecretKeyError::InvalidEncoding)?,
270 ))
271 } else {
272 Err(ParseSecretKeyError::MismatchedScheme)
273 }
274 }
275}
276
277impl RefTo<PublicKey> for SecretKey {
278 fn ref_to(&self) -> PublicKey {
279 match self {
280 SecretKey::Ed25519(sk) => PublicKey::Ed25519(sk.ref_to()),
281 SecretKey::Secp256k1(sk) => PublicKey::Secp256k1(sk.ref_to()),
282 }
283 }
284}
285
286impl Display for SecretKey {
287 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
288 write!(f, "{}", HEXLOWER.encode(&self.serialize_to_vec()))
289 }
290}
291
292impl FromStr for SecretKey {
293 type Err = ParseSecretKeyError;
294
295 fn from_str(str: &str) -> Result<Self, Self::Err> {
296 let vec = HEXLOWER
297 .decode(str.as_ref())
298 .map_err(ParseSecretKeyError::InvalidHex)?;
299 Self::try_from_slice(vec.as_slice())
300 .map_err(ParseSecretKeyError::InvalidEncoding)
301 }
302}
303
304#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
306#[derive(
307 Clone,
308 Debug,
309 Eq,
310 PartialEq,
311 PartialOrd,
312 Ord,
313 Hash,
314 BorshSerialize,
315 BorshDeserialize,
316 BorshDeserializer,
317 BorshSchema,
318)]
319pub enum CommonSignature {
320 Ed25519(ed25519::Signature),
322 Secp256k1(secp256k1::Signature),
324}
325
326pub type Signature = CommonSignature;
328
329impl string_encoding::Format for Signature {
330 type EncodedBytes<'a> = Vec<u8>;
331
332 const HRP: string_encoding::Hrp =
333 string_encoding::Hrp::parse_unchecked(string_encoding::COMMON_SIG_HRP);
334
335 fn to_bytes(&self) -> Vec<u8> {
336 self.serialize_to_vec()
337 }
338
339 fn decode_bytes(
340 bytes: &[u8],
341 ) -> Result<Self, string_encoding::DecodeError> {
342 BorshDeserialize::try_from_slice(bytes)
343 .map_err(DecodeError::InvalidBytes)
344 }
345}
346
347impl Serialize for CommonSignature {
348 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
349 where
350 S: Serializer,
351 {
352 let hex_str = HEXUPPER.encode(&self.serialize_to_vec());
353 serializer.serialize_str(&hex_str)
354 }
355}
356
357impl<'de> Deserialize<'de> for CommonSignature {
359 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
360 where
361 D: Deserializer<'de>,
362 {
363 struct SignatureVisitor;
364
365 impl Visitor<'_> for SignatureVisitor {
366 type Value = CommonSignature;
367
368 fn expecting(
369 &self,
370 formatter: &mut fmt::Formatter<'_>,
371 ) -> fmt::Result {
372 formatter.write_str(
373 "a hex string representing either an Ed25519 or Secp256k1 \
374 signature",
375 )
376 }
377
378 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
379 where
380 E: de::Error,
381 {
382 let bytes =
383 HEXUPPER.decode(value.as_bytes()).map_err(E::custom)?;
384 CommonSignature::try_from_slice(&bytes)
385 .map_err(|e| E::custom(e.to_string()))
386 }
387 }
388
389 deserializer.deserialize_str(SignatureVisitor)
390 }
391}
392
393impl_display_and_from_str_via_format!(Signature);
394
395impl From<ed25519::Signature> for Signature {
396 fn from(sig: ed25519::Signature) -> Self {
397 Signature::Ed25519(sig)
398 }
399}
400
401impl From<secp256k1::Signature> for Signature {
402 fn from(sig: secp256k1::Signature) -> Self {
403 Signature::Secp256k1(sig)
404 }
405}
406
407impl super::Signature for Signature {
408 const TYPE: SchemeType = SigScheme::TYPE;
409
410 fn try_from_sig<SIG: super::Signature>(
411 sig: &SIG,
412 ) -> Result<Self, ParseSignatureError> {
413 if SIG::TYPE == Self::TYPE {
414 Self::try_from_slice(sig.serialize_to_vec().as_slice())
415 .map_err(ParseSignatureError::InvalidEncoding)
416 } else if SIG::TYPE == ed25519::Signature::TYPE {
417 Ok(Self::Ed25519(
418 ed25519::Signature::try_from_slice(
419 sig.serialize_to_vec().as_slice(),
420 )
421 .map_err(ParseSignatureError::InvalidEncoding)?,
422 ))
423 } else if SIG::TYPE == secp256k1::Signature::TYPE {
424 Ok(Self::Secp256k1(
425 secp256k1::Signature::try_from_slice(
426 sig.serialize_to_vec().as_slice(),
427 )
428 .map_err(ParseSignatureError::InvalidEncoding)?,
429 ))
430 } else {
431 Err(ParseSignatureError::MismatchedScheme)
432 }
433 }
434}
435
436#[derive(
438 Debug,
439 Clone,
440 BorshSerialize,
441 BorshDeserialize,
442 BorshDeserializer,
443 BorshSchema,
444 PartialEq,
445 Eq,
446 PartialOrd,
447 Ord,
448 Hash,
449 Serialize,
450 Deserialize,
451 Default,
452)]
453pub struct SigScheme;
454
455impl super::SigScheme for SigScheme {
456 type PublicKey = PublicKey;
457 type SecretKey = SecretKey;
458 type Signature = Signature;
459
460 const TYPE: SchemeType = SchemeType::Common;
461
462 #[cfg(any(test, feature = "rand"))]
463 fn generate<R>(_csprng: &mut R) -> SecretKey
464 where
465 R: CryptoRng + RngCore,
466 {
467 panic!(
468 "Cannot generate common signing scheme. Must convert from \
469 alternative scheme."
470 );
471 }
472
473 fn from_bytes(_seed: [u8; 32]) -> Self::SecretKey {
474 unimplemented!(
475 "Cannot generate common signing scheme. Must convert from \
476 alternative scheme."
477 );
478 }
479
480 fn sign_with_hasher<H>(
481 keypair: &SecretKey,
482 data: impl super::SignableBytes,
483 ) -> Self::Signature
484 where
485 H: 'static + StorageHasher,
486 {
487 match keypair {
488 SecretKey::Ed25519(kp) => Signature::Ed25519(
489 ed25519::SigScheme::sign_with_hasher::<H>(kp, data),
490 ),
491 SecretKey::Secp256k1(kp) => Signature::Secp256k1(
492 secp256k1::SigScheme::sign_with_hasher::<H>(kp, data),
493 ),
494 }
495 }
496
497 fn verify_signature_with_hasher<H>(
498 pk: &Self::PublicKey,
499 data: &impl SignableBytes,
500 sig: &Self::Signature,
501 ) -> Result<(), VerifySigError>
502 where
503 H: 'static + StorageHasher,
504 {
505 match (pk, sig) {
506 (PublicKey::Ed25519(pk), Signature::Ed25519(sig)) => {
507 ed25519::SigScheme::verify_signature_with_hasher::<H>(
508 pk, data, sig,
509 )
510 }
511 (PublicKey::Secp256k1(pk), Signature::Secp256k1(sig)) => {
512 secp256k1::SigScheme::verify_signature_with_hasher::<H>(
513 pk, data, sig,
514 )
515 }
516 _ => Err(VerifySigError::MismatchedScheme),
517 }
518 }
519
520 fn mock(keypair: &SecretKey) -> Self::Signature {
521 match keypair {
522 SecretKey::Ed25519(kp) => {
523 Signature::Ed25519(ed25519::SigScheme::mock(kp))
524 }
525 SecretKey::Secp256k1(kp) => {
526 Signature::Secp256k1(secp256k1::SigScheme::mock(kp))
527 }
528 }
529 }
530}
531
532#[cfg(test)]
533mod tests {
534 use super::*;
535
536 #[test]
539 fn gen_ed25519_keypair() {
540 let secret_key =
541 SecretKey::Ed25519(crate::key::testing::gen_keypair::<
542 ed25519::SigScheme,
543 >());
544 let public_key = secret_key.to_public();
545 println!("Public key: {}", public_key);
546 println!("Secret key: {}", secret_key);
547 }
548}