1use base64ct::{Base64Unpadded, Encoding as _};
13use curve25519_dalek::Scalar;
14use derive_deftly::Deftly;
15use std::fmt::{self, Debug, Display, Formatter};
16use subtle::{Choice, ConstantTimeEq};
17
18#[cfg(feature = "memquota-memcost")]
19use tor_memquota::derive_deftly_template_HasMemoryCost;
20
21use ed25519_dalek::hazmat::ExpandedSecretKey;
22use ed25519_dalek::{Signer as _, Verifier as _};
23
24use crate::util::{
25 ct::{
26 CtByteArray, derive_deftly_template_ConstantTimeEq,
27 derive_deftly_template_PartialEqFromCtEq,
28 },
29 rng::RngCompat,
30};
31
32#[derive(Clone, Copy, Debug, Eq, PartialEq)]
36pub struct Signature(pub(crate) ed25519_dalek::Signature);
37
38#[derive(Debug, Deftly)]
44#[derive_deftly(ConstantTimeEq)]
45pub struct Keypair(pub(crate) ed25519_dalek::SigningKey);
46
47#[derive(Clone, Copy, Debug, Eq, Deftly)]
51#[derive_deftly(PartialEqFromCtEq)]
52pub struct PublicKey(pub(crate) ed25519_dalek::VerifyingKey);
53
54impl<'a> From<&'a Keypair> for PublicKey {
55 fn from(value: &'a Keypair) -> Self {
56 PublicKey((&value.0).into())
57 }
58}
59
60impl ConstantTimeEq for PublicKey {
61 fn ct_eq(&self, other: &Self) -> Choice {
62 self.as_bytes().ct_eq(other.as_bytes())
63 }
64}
65
66impl PublicKey {
67 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, signature::Error> {
69 Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(bytes)?))
70 }
71
72 pub fn as_bytes(&self) -> &[u8; 32] {
74 self.0.as_bytes()
75 }
76 pub fn to_bytes(&self) -> [u8; 32] {
78 self.0.to_bytes()
79 }
80 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), signature::Error> {
84 self.0.verify(message, &signature.0)
85 }
86}
87impl Keypair {
88 pub fn generate<R: rand_core::RngCore + rand_core::CryptoRng>(csprng: &mut R) -> Self {
90 Self(ed25519_dalek::SigningKey::generate(&mut RngCompat::new(
91 csprng,
92 )))
93 }
94 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
96 Self(ed25519_dalek::SigningKey::from_bytes(bytes))
97 }
98 pub fn as_bytes(&self) -> &[u8; 32] {
100 self.0.as_bytes()
101 }
102 pub fn to_bytes(&self) -> [u8; 32] {
104 self.0.to_bytes()
105 }
106 pub fn verifying_key(&self) -> PublicKey {
108 PublicKey(*self.0.as_ref())
109 }
110 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<(), signature::Error> {
112 self.0.verify(message, &signature.0)
113 }
114 pub fn sign(&self, message: &[u8]) -> Signature {
116 Signature(self.0.sign(message))
117 }
118}
119impl Signature {
120 pub fn from_bytes(bytes: &[u8; 64]) -> Self {
122 Self(ed25519_dalek::Signature::from_bytes(bytes))
123 }
124 pub fn to_bytes(&self) -> [u8; 64] {
126 self.0.to_bytes()
127 }
128}
129impl<'a> TryFrom<&'a [u8]> for PublicKey {
130 type Error = signature::Error;
131
132 fn try_from(value: &'a [u8]) -> Result<Self, Self::Error> {
133 Ok(Self(ed25519_dalek::VerifyingKey::try_from(value)?))
134 }
135}
136impl<'a> From<&'a [u8; 32]> for Keypair {
137 fn from(value: &'a [u8; 32]) -> Self {
138 Self(ed25519_dalek::SigningKey::from(value))
139 }
140}
141impl From<[u8; 64]> for Signature {
142 fn from(value: [u8; 64]) -> Self {
143 Signature(value.into())
144 }
145}
146impl<'a> From<&'a [u8; 64]> for Signature {
147 fn from(value: &'a [u8; 64]) -> Self {
148 Signature(value.into())
149 }
150}
151
152pub const ED25519_ID_LEN: usize = 32;
154
155pub const ED25519_SIGNATURE_LEN: usize = 64;
157
158#[allow(clippy::exhaustive_structs)]
166#[derive(Deftly)]
167#[derive_deftly(ConstantTimeEq)]
168pub struct ExpandedKeypair {
169 pub(crate) secret: ExpandedSecretKey,
171 pub(crate) public: PublicKey,
178}
179
180impl ExpandedKeypair {
181 pub fn public(&self) -> &PublicKey {
183 &self.public
184 }
185
186 pub fn sign(&self, message: &[u8]) -> Signature {
192 use sha2::Sha512;
193 Signature(ed25519_dalek::hazmat::raw_sign::<Sha512>(
195 &self.secret,
196 message,
197 &self.public.0,
198 ))
199 }
200
201 pub fn to_secret_key_bytes(&self) -> [u8; 64] {
206 let mut output = [0_u8; 64];
207 output[0..32].copy_from_slice(&self.secret.scalar.to_bytes());
208 output[32..64].copy_from_slice(&self.secret.hash_prefix);
209 output
210 }
211
212 pub fn from_secret_key_bytes(bytes: [u8; 64]) -> Option<Self> {
219 let scalar = Option::from(Scalar::from_bytes_mod_order(
220 bytes[0..32].try_into().expect("wrong length on slice"),
221 ))?;
222 let hash_prefix = bytes[32..64].try_into().expect("wrong length on slice");
223 let secret = ExpandedSecretKey {
224 scalar,
225 hash_prefix,
226 };
227 let public = PublicKey((&secret).into());
228 Some(Self { secret, public })
229 }
230
231 }
235
236impl<'a> From<&'a Keypair> for ExpandedKeypair {
237 fn from(kp: &'a Keypair) -> ExpandedKeypair {
238 ExpandedKeypair {
239 secret: kp.as_bytes().into(),
240 public: kp.into(),
241 }
242 }
243}
244
245impl From<ExpandedKeypair> for PublicKey {
246 fn from(ekp: ExpandedKeypair) -> PublicKey {
247 ekp.public
248 }
249}
250
251#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq)]
264#[cfg_attr(
265 feature = "memquota-memcost",
266 derive(Deftly),
267 derive_deftly(HasMemoryCost)
268)]
269pub struct Ed25519Identity {
270 id: CtByteArray<ED25519_ID_LEN>,
272}
273
274impl Ed25519Identity {
275 pub fn new(id: [u8; 32]) -> Self {
293 Ed25519Identity { id: id.into() }
294 }
295 pub fn from_bytes(id: &[u8]) -> Option<Self> {
297 Some(Ed25519Identity::new(id.try_into().ok()?))
298 }
299 pub fn as_bytes(&self) -> &[u8] {
301 &self.id.as_ref()[..]
302 }
303}
304
305impl From<[u8; ED25519_ID_LEN]> for Ed25519Identity {
306 fn from(id: [u8; ED25519_ID_LEN]) -> Self {
307 Ed25519Identity::new(id)
308 }
309}
310
311impl From<Ed25519Identity> for [u8; ED25519_ID_LEN] {
312 fn from(value: Ed25519Identity) -> Self {
313 value.id.into()
314 }
315}
316
317impl From<PublicKey> for Ed25519Identity {
318 fn from(pk: PublicKey) -> Self {
319 (&pk).into()
320 }
321}
322
323impl From<&PublicKey> for Ed25519Identity {
324 fn from(pk: &PublicKey) -> Self {
325 Ed25519Identity::from_bytes(pk.as_bytes()).expect("Ed25519 public key had wrong length?")
328 }
329}
330
331impl TryFrom<&Ed25519Identity> for PublicKey {
332 type Error = ed25519_dalek::SignatureError;
333 fn try_from(id: &Ed25519Identity) -> Result<PublicKey, Self::Error> {
334 PublicKey::from_bytes(id.id.as_ref())
335 }
336}
337
338impl TryFrom<Ed25519Identity> for PublicKey {
339 type Error = ed25519_dalek::SignatureError;
340 fn try_from(id: Ed25519Identity) -> Result<PublicKey, Self::Error> {
341 (&id).try_into()
342 }
343}
344
345impl ConstantTimeEq for Ed25519Identity {
346 fn ct_eq(&self, other: &Self) -> Choice {
347 self.id.ct_eq(&other.id)
348 }
349}
350
351impl Display for Ed25519Identity {
352 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
353 write!(f, "{}", Base64Unpadded::encode_string(self.id.as_ref()))
354 }
355}
356
357impl Debug for Ed25519Identity {
358 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
359 write!(f, "Ed25519Identity {{ {} }}", self)
360 }
361}
362
363impl safelog::Redactable for Ed25519Identity {
364 fn display_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
367 write!(
368 f,
369 "{}…",
370 &Base64Unpadded::encode_string(self.id.as_ref())[..2]
371 )
372 }
373
374 fn debug_redacted(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375 write!(f, "Ed25519Identity {{ {} }}", self.redacted())
376 }
377}
378
379impl serde::Serialize for Ed25519Identity {
380 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
381 where
382 S: serde::Serializer,
383 {
384 if serializer.is_human_readable() {
385 serializer.serialize_str(&Base64Unpadded::encode_string(self.id.as_ref()))
386 } else {
387 serializer.serialize_bytes(&self.id.as_ref()[..])
388 }
389 }
390}
391
392impl<'de> serde::Deserialize<'de> for Ed25519Identity {
393 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
394 where
395 D: serde::Deserializer<'de>,
396 {
397 if deserializer.is_human_readable() {
398 struct EdIdentityVisitor;
400 impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
401 type Value = Ed25519Identity;
402 fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
403 fmt.write_str("base64-encoded Ed25519 public key")
404 }
405 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
406 where
407 E: serde::de::Error,
408 {
409 let bytes = Base64Unpadded::decode_vec(s).map_err(E::custom)?;
410 Ed25519Identity::from_bytes(&bytes)
411 .ok_or_else(|| E::custom("wrong length for Ed25519 public key"))
412 }
413 }
414
415 deserializer.deserialize_str(EdIdentityVisitor)
416 } else {
417 struct EdIdentityVisitor;
419 impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
420 type Value = Ed25519Identity;
421 fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
422 fmt.write_str("ed25519 public key")
423 }
424 fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
425 where
426 E: serde::de::Error,
427 {
428 Ed25519Identity::from_bytes(bytes)
429 .ok_or_else(|| E::custom("wrong length for ed25519 public key"))
430 }
431 }
432 deserializer.deserialize_bytes(EdIdentityVisitor)
433 }
434 }
435}
436
437#[derive(Clone, Debug)]
440#[cfg_attr(
441 feature = "memquota-memcost",
442 derive(Deftly),
443 derive_deftly(HasMemoryCost)
444)]
445pub struct ValidatableEd25519Signature {
446 #[cfg_attr(feature = "memquota-memcost", deftly(has_memory_cost(copy)))]
448 key: PublicKey,
449 #[cfg_attr(feature = "memquota-memcost", deftly(has_memory_cost(copy)))]
451 sig: Signature,
452 entire_text_of_signed_thing: Vec<u8>,
460}
461
462impl ValidatableEd25519Signature {
463 pub fn new(key: PublicKey, sig: Signature, text: &[u8]) -> Self {
465 ValidatableEd25519Signature {
466 key,
467 sig,
468 entire_text_of_signed_thing: text.into(),
469 }
470 }
471
472 pub(crate) fn as_parts(&self) -> (&PublicKey, &Signature, &[u8]) {
474 (&self.key, &self.sig, &self.entire_text_of_signed_thing[..])
475 }
476
477 pub fn signature(&self) -> &Signature {
479 &self.sig
480 }
481}
482
483impl super::ValidatableSignature for ValidatableEd25519Signature {
484 fn is_valid(&self) -> bool {
485 self.key
486 .verify(&self.entire_text_of_signed_thing[..], &self.sig)
487 .is_ok()
488 }
489
490 fn as_ed25519(&self) -> Option<&ValidatableEd25519Signature> {
491 Some(self)
492 }
493}
494
495pub fn validate_batch(sigs: &[&ValidatableEd25519Signature]) -> bool {
507 use crate::pk::ValidatableSignature;
508 if sigs.is_empty() {
509 true
512 } else if sigs.len() == 1 {
513 sigs[0].is_valid()
515 } else {
516 let mut ed_msgs = Vec::new();
517 let mut ed_sigs = Vec::new();
518 let mut ed_pks = Vec::new();
519 for ed_sig in sigs {
520 let (pk, sig, msg) = ed_sig.as_parts();
521 ed_sigs.push(sig.0);
522 ed_pks.push(pk.0);
523 ed_msgs.push(msg);
524 }
525 ed25519_dalek::verify_batch(&ed_msgs[..], &ed_sigs[..], &ed_pks[..]).is_ok()
526 }
527}
528
529pub trait Ed25519PublicKey {
531 fn public_key(&self) -> PublicKey;
533}
534
535impl Ed25519PublicKey for Keypair {
536 fn public_key(&self) -> PublicKey {
537 Keypair::verifying_key(self)
538 }
539}
540
541pub trait Ed25519SigningKey {
543 fn sign(&self, message: &[u8]) -> Signature;
545}
546
547impl Ed25519SigningKey for Keypair {
548 fn sign(&self, message: &[u8]) -> Signature {
549 Keypair::sign(self, message)
550 }
551}
552impl Ed25519SigningKey for ExpandedKeypair {
553 fn sign(&self, message: &[u8]) -> Signature {
554 ExpandedKeypair::sign(self, message)
555 }
556}