1use std::cmp::Ordering;
25use std::ops::Deref;
26
27use crate::*;
28
29impl MultiDisplay<Encoding> for ec25519::x25519::PublicKey {
33 type Display = String;
34 fn display_fmt(&self, f: &Encoding) -> String { f.encode(self.as_slice()) }
35}
36
37impl EcPk for ec25519::x25519::PublicKey {
38 const COMPRESSED_LEN: usize = 32;
39 const CURVE_NAME: &'static str = "Curve25519";
40 type Compressed = [u8; 32];
41
42 fn base_point() -> Self { ec25519::x25519::PublicKey::base_point() }
43
44 fn to_pk_compressed(&self) -> Self::Compressed { *self.deref() }
45
46 fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
47 Ok(ec25519::x25519::PublicKey::new(pk))
48 }
49
50 fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
51 if slice.len() != Self::COMPRESSED_LEN {
52 return Err(EcPkInvalid {});
53 }
54 let mut buf = [0u8; 32];
55 buf.copy_from_slice(slice);
56 Self::from_pk_compressed(buf)
57 }
58}
59
60impl EcSk for ec25519::x25519::SecretKey {
61 type Pk = ec25519::x25519::PublicKey;
62
63 fn generate_keypair() -> (Self, Self::Pk)
64 where Self: Sized {
65 let pair = ec25519::x25519::KeyPair::generate();
66 (pair.sk, pair.pk)
67 }
68
69 fn to_pk(&self) -> Result<Self::Pk, EcSkInvalid> {
70 self.recover_public_key().map_err(EcSkInvalid::from)
71 }
72}
73
74#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)]
78#[wrapper(Deref)]
79pub struct SharedSecret([u8; 32]);
80
81impl AsRef<[u8]> for SharedSecret {
82 fn as_ref(&self) -> &[u8] { &self.0 }
83}
84
85impl SharedSecret {
86 pub fn empty() -> Self { SharedSecret([0u8; 32]) }
87
88 pub fn is_empty(self) -> bool { self == Self::empty() }
89}
90
91#[derive(Wrapper, Copy, Clone, PartialEq, Eq, Hash, Debug, From)]
92#[wrapper(Deref)]
93pub struct PublicKey(#[from] ec25519::x25519::PublicKey);
100
101impl PartialOrd for PublicKey {
102 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
103 self.0.as_ref().partial_cmp(other.0.as_ref())
104 }
105}
106
107impl Ord for PublicKey {
108 fn cmp(&self, other: &Self) -> Ordering { self.0.as_ref().cmp(other.0.as_ref()) }
109}
110
111impl EcPk for PublicKey {
112 const COMPRESSED_LEN: usize = 32;
113 const CURVE_NAME: &'static str = "Curve25519";
114 type Compressed = [u8; 32];
115
116 fn base_point() -> Self { Self(ec25519::x25519::PublicKey::base_point()) }
117
118 fn to_pk_compressed(&self) -> Self::Compressed { self.0.to_pk_compressed() }
119
120 fn from_pk_compressed(pk: Self::Compressed) -> Result<Self, EcPkInvalid> {
121 ec25519::x25519::PublicKey::from_pk_compressed(pk).map(Self)
122 }
123
124 fn from_pk_compressed_slice(slice: &[u8]) -> Result<Self, EcPkInvalid> {
125 ec25519::x25519::PublicKey::from_pk_compressed_slice(slice).map(Self)
126 }
127}
128
129impl MultiDisplay<Encoding> for PublicKey {
130 type Display = String;
131 fn display_fmt(&self, f: &Encoding) -> Self::Display { self.0.display_fmt(f) }
132}
133
134#[derive(Wrapper, Clone, PartialEq, Eq, Hash, Debug, From)]
135#[wrapper(Deref)]
136pub struct PrivateKey(#[from] ec25519::x25519::SecretKey);
137
138impl PartialOrd for PrivateKey {
139 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
140}
141
142impl Ord for PrivateKey {
143 fn cmp(&self, other: &Self) -> Ordering { self.0.cmp(&other.0) }
144}
145
146impl EcSk for PrivateKey {
147 type Pk = PublicKey;
148
149 fn generate_keypair() -> (Self, Self::Pk)
150 where Self: Sized {
151 let (sk, pk) = ec25519::x25519::SecretKey::generate_keypair();
152 (sk.into(), pk.into())
153 }
154
155 fn to_pk(&self) -> Result<PublicKey, EcSkInvalid> { self.0.to_pk().map(PublicKey::from) }
156}
157
158impl Ecdh for ec25519::x25519::SecretKey {
162 type SharedSecret = [u8; 32];
163
164 fn ecdh(&self, pk: &Self::Pk) -> Result<Self::SharedSecret, EcdhError> { Ok(*pk.dh(self)?) }
165}
166
167impl Ecdh for PrivateKey {
168 type SharedSecret = SharedSecret;
169
170 fn ecdh(&self, pk: &PublicKey) -> Result<SharedSecret, EcdhError> {
171 self.0.ecdh(&pk.0).map(SharedSecret::from)
172 }
173}