1use base64ct::{Base64Unpadded, Encoding as _};
13use curve25519_dalek::Scalar;
14use std::fmt::{self, Debug, Display, Formatter};
15use subtle::{Choice, ConstantTimeEq};
16
17#[cfg(feature = "memquota-memcost")]
18use {derive_deftly::Deftly, tor_memquota::derive_deftly_template_HasMemoryCost};
19
20use ed25519_dalek::hazmat::ExpandedSecretKey;
21use ed25519_dalek::{Signer as _, Verifier as _};
22
23use crate::util::{ct::CtByteArray, rng::RngCompat};
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
29pub struct Signature(pub(crate) ed25519_dalek::Signature);
30
31#[derive(Debug)]
37pub struct Keypair(pub(crate) ed25519_dalek::SigningKey);
38
39#[derive(Clone, Copy, Debug, Eq, PartialEq)]
43pub struct PublicKey(pub(crate) ed25519_dalek::VerifyingKey);
44
45impl<'a> From<&'a Keypair> for PublicKey {
46 fn from(value: &'a Keypair) -> Self {
47 PublicKey((&value.0).into())
48 }
49}
50
51impl PublicKey {
52 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, signature::Error> {
54 Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(bytes)?))
55 }
56
57 pub fn as_bytes(&self) -> &[u8; 32] {
59 self.0.as_bytes()
60 }
61 pub fn to_bytes(&self) -> [u8; 32] {
63 self.0.to_bytes()
64 }
65 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), signature::Error> {
69 self.0.verify(message, &signature.0)
70 }
71}
72impl Keypair {
73 pub fn generate<R: rand_core::RngCore + rand_core::CryptoRng>(csprng: &mut R) -> Self {
75 Self(ed25519_dalek::SigningKey::generate(&mut RngCompat::new(
76 csprng,
77 )))
78 }
79 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
81 Self(ed25519_dalek::SigningKey::from_bytes(bytes))
82 }
83 pub fn as_bytes(&self) -> &[u8; 32] {
85 self.0.as_bytes()
86 }
87 pub fn to_bytes(&self) -> [u8; 32] {
89 self.0.to_bytes()
90 }
91 pub fn verifying_key(&self) -> PublicKey {
93 PublicKey(*self.0.as_ref())
94 }
95 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), signature::Error> {
97 self.0.verify(message, &signature.0)
98 }
99 pub fn sign(&self, message: &[u8]) -> Signature {
101 Signature(self.0.sign(message))
102 }
103}
104impl Signature {
105 pub fn from_bytes(bytes: &[u8; 64]) -> Self {
107 Self(ed25519_dalek::Signature::from_bytes(bytes))
108 }
109 pub fn to_bytes(&self) -> [u8; 64] {
111 self.0.to_bytes()
112 }
113}
114impl<'a> TryFrom<&'a [u8]> for PublicKey {
115 type Error = signature::Error;
116
117 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
118 Ok(Self(ed25519_dalek::VerifyingKey::try_from(value)?))
119 }
120}
121impl<'a> From<&'a [u8; 32]> for Keypair {
122 fn from(value: &'a [u8; 32]) -> Self {
123 Self(ed25519_dalek::SigningKey::from(value))
124 }
125}
126impl From<[u8; 64]> for Signature {
127 fn from(value: [u8; 64]) -> Self {
128 Signature(value.into())
129 }
130}
131impl<'a> From<&'a [u8; 64]> for Signature {
132 fn from(value: &'a [u8; 64]) -> Self {
133 Signature(value.into())
134 }
135}
136
137pub const ED25519_ID_LEN: usize = 32;
139
140pub const ED25519_SIGNATURE_LEN: usize = 64;
142
143#[allow(clippy::exhaustive_structs)]
151pub struct ExpandedKeypair {
152 pub(crate) secret: ExpandedSecretKey,
154 pub(crate) public: PublicKey,
161}
162
163impl ExpandedKeypair {
164 pub fn public(&self) -> &PublicKey {
166 &self.public
167 }
168
169 pub fn sign(&self, message: &[u8]) -> Signature {
175 use sha2::Sha512;
176 Signature(ed25519_dalek::hazmat::raw_sign::<Sha512>(
178 &self.secret,
179 message,
180 &self.public.0,
181 ))
182 }
183
184 pub fn to_secret_key_bytes(&self) -> [u8; 64] {
189 let mut output = [0_u8; 64];
190 output[0..32].copy_from_slice(&self.secret.scalar.to_bytes());
191 output[32..64].copy_from_slice(&self.secret.hash_prefix);
192 output
193 }
194
195 pub fn from_secret_key_bytes(bytes: [u8; 64]) -> Option<Self> {
202 let scalar = Option::from(Scalar::from_bytes_mod_order(
203 bytes[0..32].try_into().expect("wrong length on slice"),
204 ))?;
205 let hash_prefix = bytes[32..64].try_into().expect("wrong length on slice");
206 let secret = ExpandedSecretKey {
207 scalar,
208 hash_prefix,
209 };
210 let public = PublicKey((&secret).into());
211 Some(Self { secret, public })
212 }
213
214 }
218
219impl<'a> From<&'a Keypair> for ExpandedKeypair {
220 fn from(kp: &'a Keypair) -> ExpandedKeypair {
221 ExpandedKeypair {
222 secret: kp.as_bytes().into(),
223 public: kp.into(),
224 }
225 }
226}
227
228impl From<ExpandedKeypair> for PublicKey {
229 fn from(ekp: ExpandedKeypair) -> PublicKey {
230 ekp.public
231 }
232}
233
234#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
247#[cfg_attr(
248 feature = "memquota-memcost",
249 derive(Deftly),
250 derive_deftly(HasMemoryCost)
251)]
252pub struct Ed25519Identity {
253 id: CtByteArray<ED25519_ID_LEN>,
255}
256
257impl Ed25519Identity {
258 pub fn new(id: [u8; 32]) -> Self {
276 Ed25519Identity { id: id.into() }
277 }
278 pub fn from_bytes(id: &[u8]) -> Option<Self> {
280 Some(Ed25519Identity::new(id.try_into().ok()?))
281 }
282 pub fn as_bytes(&self) -> &[u8] {
284 &self.id.as_ref()[..]
285 }
286}
287
288impl From<[u8; ED25519_ID_LEN]> for Ed25519Identity {
289 fn from(id: [u8; ED25519_ID_LEN]) -> Self {
290 Ed25519Identity::new(id)
291 }
292}
293
294impl From<Ed25519Identity> for [u8; ED25519_ID_LEN] {
295 fn from(value: Ed25519Identity) -> Self {
296 value.id.into()
297 }
298}
299
300impl From<PublicKey> for Ed25519Identity {
301 fn from(pk: PublicKey) -> Self {
302 (&pk).into()
303 }
304}
305
306impl From<&PublicKey> for Ed25519Identity {
307 fn from(pk: &PublicKey) -> Self {
308 Ed25519Identity::from_bytes(pk.as_bytes()).expect("Ed25519 public key had wrong length?")
311 }
312}
313
314impl TryFrom<&Ed25519Identity> for PublicKey {
315 type Error = ed25519_dalek::SignatureError;
316 fn try_from(id: &Ed25519Identity) -> Result<PublicKey, Self::Error> {
317 PublicKey::from_bytes(id.id.as_ref())
318 }
319}
320
321impl TryFrom<Ed25519Identity> for PublicKey {
322 type Error = ed25519_dalek::SignatureError;
323 fn try_from(id: Ed25519Identity) -> Result<PublicKey, Self::Error> {
324 (&id).try_into()
325 }
326}
327
328impl ConstantTimeEq for Ed25519Identity {
329 fn ct_eq(&self, other: &Self) -> Choice {
330 self.id.ct_eq(&other.id)
331 }
332}
333
334impl Display for Ed25519Identity {
335 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
336 write!(f, "{}", Base64Unpadded::encode_string(self.id.as_ref()))
337 }
338}
339
340impl Debug for Ed25519Identity {
341 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
342 write!(f, "Ed25519Identity {{ {} }}", self)
343 }
344}
345
346impl safelog::Redactable for Ed25519Identity {
347 fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
350 write!(
351 f,
352 "{}…",
353 &Base64Unpadded::encode_string(self.id.as_ref())[..2]
354 )
355 }
356
357 fn debug_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358 write!(f, "Ed25519Identity {{ {} }}", self.redacted())
359 }
360}
361
362impl serde::Serialize for Ed25519Identity {
363 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
364 where
365 S: serde::Serializer,
366 {
367 if serializer.is_human_readable() {
368 serializer.serialize_str(&Base64Unpadded::encode_string(self.id.as_ref()))
369 } else {
370 serializer.serialize_bytes(&self.id.as_ref()[..])
371 }
372 }
373}
374
375impl<'de> serde::Deserialize<'de> for Ed25519Identity {
376 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
377 where
378 D: serde::Deserializer<'de>,
379 {
380 if deserializer.is_human_readable() {
381 struct EdIdentityVisitor;
383 impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
384 type Value = Ed25519Identity;
385 fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
386 fmt.write_str("base64-encoded Ed25519 public key")
387 }
388 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
389 where
390 E: serde::de::Error,
391 {
392 let bytes = Base64Unpadded::decode_vec(s).map_err(E::custom)?;
393 Ed25519Identity::from_bytes(&bytes)
394 .ok_or_else(|| E::custom("wrong length for Ed25519 public key"))
395 }
396 }
397
398 deserializer.deserialize_str(EdIdentityVisitor)
399 } else {
400 struct EdIdentityVisitor;
402 impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
403 type Value = Ed25519Identity;
404 fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
405 fmt.write_str("ed25519 public key")
406 }
407 fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
408 where
409 E: serde::de::Error,
410 {
411 Ed25519Identity::from_bytes(bytes)
412 .ok_or_else(|| E::custom("wrong length for ed25519 public key"))
413 }
414 }
415 deserializer.deserialize_bytes(EdIdentityVisitor)
416 }
417 }
418}
419
420#[derive(Clone, Debug)]
423#[cfg_attr(
424 feature = "memquota-memcost",
425 derive(Deftly),
426 derive_deftly(HasMemoryCost)
427)]
428pub struct ValidatableEd25519Signature {
429 #[cfg_attr(feature = "memquota-memcost", deftly(has_memory_cost(copy)))]
431 key: PublicKey,
432 #[cfg_attr(feature = "memquota-memcost", deftly(has_memory_cost(copy)))]
434 sig: Signature,
435 entire_text_of_signed_thing: Vec<u8>,
443}
444
445impl ValidatableEd25519Signature {
446 pub fn new(key: PublicKey, sig: Signature, text: &[u8]) -> Self {
448 ValidatableEd25519Signature {
449 key,
450 sig,
451 entire_text_of_signed_thing: text.into(),
452 }
453 }
454
455 pub(crate) fn as_parts(&self) -> (&PublicKey, &Signature, &[u8]) {
457 (&self.key, &self.sig, &self.entire_text_of_signed_thing[..])
458 }
459
460 pub fn signature(&self) -> &Signature {
462 &self.sig
463 }
464}
465
466impl super::ValidatableSignature for ValidatableEd25519Signature {
467 fn is_valid(&self) -> bool {
468 self.key
469 .verify(&self.entire_text_of_signed_thing[..], &self.sig)
470 .is_ok()
471 }
472
473 fn as_ed25519(&self) -> Option<&ValidatableEd25519Signature> {
474 Some(self)
475 }
476}
477
478pub fn validate_batch(sigs: &[&ValidatableEd25519Signature]) -> bool {
490 use crate::pk::ValidatableSignature;
491 if sigs.is_empty() {
492 true
495 } else if sigs.len() == 1 {
496 sigs[0].is_valid()
498 } else {
499 let mut ed_msgs = Vec::new();
500 let mut ed_sigs = Vec::new();
501 let mut ed_pks = Vec::new();
502 for ed_sig in sigs {
503 let (pk, sig, msg) = ed_sig.as_parts();
504 ed_sigs.push(sig.0);
505 ed_pks.push(pk.0);
506 ed_msgs.push(msg);
507 }
508 ed25519_dalek::verify_batch(&ed_msgs[..], &ed_sigs[..], &ed_pks[..]).is_ok()
509 }
510}
511
512pub trait Ed25519PublicKey {
514 fn public_key(&self) -> PublicKey;
516}
517
518impl Ed25519PublicKey for Keypair {
519 fn public_key(&self) -> PublicKey {
520 Keypair::verifying_key(self)
521 }
522}
523
524pub trait Ed25519SigningKey {
526 fn sign(&self, message: &[u8]) -> Signature;
528}
529
530impl Ed25519SigningKey for Keypair {
531 fn sign(&self, message: &[u8]) -> Signature {
532 Keypair::sign(self, message)
533 }
534}
535impl Ed25519SigningKey for ExpandedKeypair {
536 fn sign(&self, message: &[u8]) -> Signature {
537 ExpandedKeypair::sign(self, message)
538 }
539}