defuse_crypto/curve/
mod.rs1mod ed25519;
2mod p256;
3mod secp256k1;
4
5pub use self::{ed25519::*, p256::*, secp256k1::*};
6
7use near_sdk::bs58;
8use strum::{Display, EnumString, IntoStaticStr};
9use thiserror::Error as ThisError;
10
11pub trait Curve {
12 type PublicKey;
13 type Signature;
14
15 type Message: AsRef<[u8]> + ?Sized;
17
18 type VerifyingKey;
20
21 fn verify(
22 signature: &Self::Signature,
23 message: &Self::Message,
24 verifying_key: &Self::VerifyingKey,
25 ) -> Option<Self::PublicKey>;
26}
27
28#[derive(Display, IntoStaticStr, EnumString)]
29#[strum(serialize_all = "snake_case", ascii_case_insensitive)]
30pub enum CurveType {
31 Ed25519,
32 Secp256k1,
33 P256,
34}
35
36pub trait TypedCurve: Curve {
37 const CURVE_TYPE: CurveType;
38
39 #[inline]
40 fn to_base58(bytes: impl AsRef<[u8]>) -> String {
41 format!(
42 "{}:{}",
43 Self::CURVE_TYPE,
44 bs58::encode(bytes.as_ref()).into_string()
45 )
46 }
47
48 fn parse_base58<const N: usize>(s: impl AsRef<str>) -> Result<[u8; N], ParseCurveError> {
49 let s = s.as_ref();
50 let data = if let Some((curve, data)) = s.split_once(':') {
51 if !curve.eq_ignore_ascii_case(Self::CURVE_TYPE.into()) {
52 return Err(ParseCurveError::WrongCurveType);
53 }
54 data
55 } else {
56 s
57 };
58 bs58::decode(data.as_bytes())
59 .into_array_const()
60 .map_err(Into::into)
61 }
62}
63
64#[derive(Debug, ThisError)]
65pub enum ParseCurveError {
66 #[error("wrong curve type")]
67 WrongCurveType,
68 #[error("base58: {0}")]
69 Base58(#[from] bs58::decode::Error),
70}