defuse_crypto/curve/
ed25519.rs

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