defuse_crypto/curve/
ed25519.rs

1use core::fmt::{self, Debug, Display};
2use std::str::FromStr;
3
4use ed25519_dalek::VerifyingKey;
5use near_sdk::{
6    env, near,
7    serde_with::{DeserializeFromStr, SerializeDisplay},
8};
9
10use crate::{Curve, CurveType, ParseCurveError, TypedCurve};
11
12pub struct Ed25519;
13
14impl Curve for Ed25519 {
15    type PublicKey = [u8; ed25519_dalek::PUBLIC_KEY_LENGTH];
16    type Signature = [u8; ed25519_dalek::SIGNATURE_LENGTH];
17
18    type Message = [u8];
19    type VerifyingKey = Self::PublicKey;
20
21    #[inline]
22    fn verify(
23        signature: &Self::Signature,
24        message: &Self::Message,
25        public_key: &Self::VerifyingKey,
26    ) -> Option<Self::PublicKey> {
27        if VerifyingKey::from_bytes(public_key).ok()?.is_weak() {
28            // prevent using weak (i.e. low order) public keys, see
29            // https://github.com/dalek-cryptography/ed25519-dalek#weak-key-forgery-and-verify_strict
30            return None;
31        }
32
33        env::ed25519_verify(signature, message, public_key)
34            .then_some(public_key)
35            .copied()
36    }
37}
38
39impl TypedCurve for Ed25519 {
40    const CURVE_TYPE: CurveType = CurveType::Ed25519;
41}
42
43#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
44#[near(serializers = [borsh])]
45#[derive(
46    Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, SerializeDisplay, DeserializeFromStr,
47)]
48#[serde_with(crate = "::near_sdk::serde_with")]
49#[repr(transparent)]
50pub struct Ed25519PublicKey(pub <Ed25519 as Curve>::PublicKey);
51
52impl Debug for Ed25519PublicKey {
53    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54        Display::fmt(self, f)
55    }
56}
57
58impl Display for Ed25519PublicKey {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        f.write_str(&<Ed25519 as TypedCurve>::to_base58(self.0))
61    }
62}
63
64impl FromStr for Ed25519PublicKey {
65    type Err = ParseCurveError;
66
67    fn from_str(s: &str) -> Result<Self, Self::Err> {
68        Ed25519::parse_base58(s).map(Self)
69    }
70}
71
72#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
73#[near(serializers = [borsh])]
74#[derive(
75    Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, SerializeDisplay, DeserializeFromStr,
76)]
77#[serde_with(crate = "::near_sdk::serde_with")]
78#[repr(transparent)]
79pub struct Ed25519Signature(pub <Ed25519 as Curve>::Signature);
80
81impl Debug for Ed25519Signature {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        Display::fmt(self, f)
84    }
85}
86
87impl Display for Ed25519Signature {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        f.write_str(&<Ed25519 as TypedCurve>::to_base58(self.0))
90    }
91}
92
93impl FromStr for Ed25519Signature {
94    type Err = ParseCurveError;
95
96    fn from_str(s: &str) -> Result<Self, Self::Err> {
97        Ed25519::parse_base58(s).map(Self)
98    }
99}