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