elastic_elgamal/keys/
mod.rs1use base64ct::{Base64UrlUnpadded, Encoding};
4use rand_core::{CryptoRng, RngCore};
5use zeroize::Zeroize;
6
7use core::{fmt, ops};
8
9use crate::{
10 alloc::{vec, Vec},
11 group::Group,
12};
13
14mod impls;
15
16pub struct SecretKey<G: Group>(G::Scalar);
19
20impl<G: Group> fmt::Debug for SecretKey<G> {
21 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22 formatter
23 .debug_struct("SecretKey")
24 .field("public", &PublicKey::from(self))
25 .finish()
26 }
27}
28
29impl<G: Group> Clone for SecretKey<G> {
30 fn clone(&self) -> Self {
31 SecretKey(self.0)
32 }
33}
34
35impl<G: Group> Zeroize for SecretKey<G> {
36 fn zeroize(&mut self) {
37 self.0.zeroize();
38 }
39}
40
41impl<G: Group> Drop for SecretKey<G> {
42 fn drop(&mut self) {
43 self.0.zeroize();
44 }
45}
46
47impl<G: Group> SecretKey<G> {
48 pub(crate) fn new(scalar: G::Scalar) -> Self {
49 SecretKey(scalar)
50 }
51
52 pub fn generate<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
54 SecretKey(G::generate_scalar(rng))
55 }
56
57 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
60 if bytes.len() != G::SCALAR_SIZE {
61 return None;
62 }
63 G::deserialize_scalar(bytes).map(SecretKey)
64 }
65
66 pub fn expose_scalar(&self) -> &G::Scalar {
68 &self.0
69 }
70}
71
72impl<G: Group> ops::Add for SecretKey<G> {
73 type Output = Self;
74
75 fn add(self, rhs: Self) -> Self {
76 Self(self.0 + rhs.0)
77 }
78}
79
80impl<G: Group> ops::AddAssign for SecretKey<G> {
81 fn add_assign(&mut self, rhs: Self) {
82 self.0 = self.0 + rhs.0;
83 }
84}
85
86impl<G: Group> ops::Sub for SecretKey<G> {
87 type Output = Self;
88
89 fn sub(self, rhs: Self) -> Self {
90 Self(self.0 - rhs.0)
91 }
92}
93
94impl<G: Group> ops::SubAssign for SecretKey<G> {
95 fn sub_assign(&mut self, rhs: Self) {
96 self.0 = self.0 - rhs.0;
97 }
98}
99
100impl<G: Group> ops::Mul<&G::Scalar> for SecretKey<G> {
101 type Output = Self;
102
103 fn mul(self, &k: &G::Scalar) -> Self {
104 Self(self.0 * k)
105 }
106}
107
108impl<G: Group> ops::Mul<&G::Scalar> for &SecretKey<G> {
109 type Output = SecretKey<G>;
110
111 fn mul(self, &k: &G::Scalar) -> SecretKey<G> {
112 SecretKey(self.0 * k)
113 }
114}
115
116pub struct PublicKey<G: Group> {
124 bytes: Vec<u8>,
125 element: G::Element,
126}
127
128impl<G: Group> Clone for PublicKey<G> {
129 fn clone(&self) -> Self {
130 PublicKey {
131 bytes: self.bytes.clone(),
132 element: self.element,
133 }
134 }
135}
136
137impl<G: Group> fmt::Debug for PublicKey<G> {
138 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
139 formatter
140 .debug_tuple("PublicKey")
141 .field(&Base64UrlUnpadded::encode_string(&self.bytes))
142 .finish()
143 }
144}
145
146impl<G> PartialEq for PublicKey<G>
147where
148 G: Group,
149{
150 fn eq(&self, other: &Self) -> bool {
151 self.bytes == other.bytes
152 }
153}
154
155impl<G: Group> PublicKey<G> {
156 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PublicKeyConversionError> {
163 if bytes.len() != G::ELEMENT_SIZE {
164 return Err(PublicKeyConversionError::InvalidByteSize);
165 }
166
167 let element =
168 G::deserialize_element(bytes).ok_or(PublicKeyConversionError::InvalidGroupElement)?;
169 if G::is_identity(&element) {
170 Err(PublicKeyConversionError::IdentityKey)
171 } else {
172 Ok(Self {
173 bytes: bytes.to_vec(),
174 element,
175 })
176 }
177 }
178
179 pub(crate) fn from_element(element: G::Element) -> Self {
180 let mut element_bytes = vec![0_u8; G::ELEMENT_SIZE];
181 G::serialize_element(&element, &mut element_bytes);
182 PublicKey {
183 element,
184 bytes: element_bytes,
185 }
186 }
187
188 pub fn as_bytes(&self) -> &[u8] {
190 &self.bytes
191 }
192
193 pub fn as_element(&self) -> G::Element {
195 self.element
196 }
197}
198
199impl<G: Group> From<&SecretKey<G>> for PublicKey<G> {
200 fn from(secret_key: &SecretKey<G>) -> Self {
201 let element = G::mul_generator(&secret_key.0);
202 Self::from_element(element)
203 }
204}
205
206#[derive(Debug, Clone)]
208#[non_exhaustive]
209pub enum PublicKeyConversionError {
210 InvalidByteSize,
212 InvalidGroupElement,
214 IdentityKey,
216}
217
218impl fmt::Display for PublicKeyConversionError {
219 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
220 formatter.write_str(match self {
221 Self::InvalidByteSize => "invalid size of the byte buffer",
222 Self::InvalidGroupElement => {
223 "byte buffer has correct size, but does not represent a group element"
224 }
225 Self::IdentityKey => "underlying group element is the group identity",
226 })
227 }
228}
229
230#[cfg(feature = "std")]
231impl std::error::Error for PublicKeyConversionError {}
232
233impl<G: Group> ops::Add<Self> for PublicKey<G> {
234 type Output = Self;
235
236 fn add(self, rhs: Self) -> Self {
237 let element = self.element + rhs.element;
238 Self::from_element(element)
239 }
240}
241
242impl<G: Group> ops::Mul<&G::Scalar> for PublicKey<G> {
243 type Output = Self;
244
245 fn mul(self, k: &G::Scalar) -> Self {
246 let element = self.element * k;
247 Self::from_element(element)
248 }
249}
250
251impl<G: Group> ops::Mul<u64> for PublicKey<G> {
252 type Output = Self;
253
254 fn mul(self, k: u64) -> Self {
255 self * &G::Scalar::from(k)
256 }
257}
258
259pub struct Keypair<G: Group> {
262 secret: SecretKey<G>,
263 public: PublicKey<G>,
264}
265
266impl<G: Group> fmt::Debug for Keypair<G> {
267 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
268 formatter
269 .debug_struct("Keypair")
270 .field("public", &self.public)
271 .finish_non_exhaustive()
272 }
273}
274
275impl<G: Group> Clone for Keypair<G> {
276 fn clone(&self) -> Self {
277 Keypair {
278 secret: self.secret.clone(),
279 public: self.public.clone(),
280 }
281 }
282}
283
284impl<G: Group> Keypair<G> {
285 pub fn generate<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
287 let secret = SecretKey::generate(rng);
288 Keypair {
289 public: PublicKey::from(&secret),
290 secret,
291 }
292 }
293
294 pub fn public(&self) -> &PublicKey<G> {
296 &self.public
297 }
298
299 pub fn secret(&self) -> &SecretKey<G> {
301 &self.secret
302 }
303
304 pub fn into_tuple(self) -> (PublicKey<G>, SecretKey<G>) {
306 (self.public, self.secret)
307 }
308}
309
310impl<G: Group> From<SecretKey<G>> for Keypair<G> {
311 fn from(secret: SecretKey<G>) -> Self {
312 Self {
313 public: PublicKey::from(&secret),
314 secret,
315 }
316 }
317}
318
319impl<G: Group> ops::Mul<&G::Scalar> for Keypair<G> {
320 type Output = Self;
321
322 fn mul(self, k: &G::Scalar) -> Self {
323 Keypair {
324 secret: self.secret * k,
325 public: self.public * k,
326 }
327 }
328}