1
//! Re-exporting Ed25519 implementations, and related utilities.
2
//!
3
//! Here we re-export types from [`ed25519_dalek`] that implement the
4
//! Ed25519 signature algorithm.  (TODO: Eventually, this module
5
//! should probably be replaced with a wrapper that uses the ed25519
6
//! trait and the Signature trait.)
7
//!
8
//! We additionally provide an `Ed25519Identity` type to represent the
9
//! unvalidated Ed25519 "identity keys" that we use throughout the Tor
10
//! protocol to uniquely identify a relay.
11

            
12
use arrayref::array_ref;
13
use std::convert::{TryFrom, TryInto};
14
use std::fmt::{self, Debug, Display, Formatter};
15
use subtle::{Choice, ConstantTimeEq};
16

            
17
pub use ed25519_dalek::{ExpandedSecretKey, Keypair, PublicKey, SecretKey, Signature};
18

            
19
/// A relay's identity, as an unchecked, unvalidated Ed25519 key.
20
///
21
/// This type is distinct from an Ed25519 [`PublicKey`] for several reasons:
22
///  * We're storing it in a compact format, whereas the public key
23
///    implementation might want an expanded form for more efficient key
24
///    validation.
25
///  * This type hasn't checked whether the bytes here actually _are_ a
26
///    valid Ed25519 public key.
27
1376176
#[derive(Clone, Copy, Hash)]
28
#[allow(clippy::derive_hash_xor_eq)]
29
pub struct Ed25519Identity {
30
    /// A raw unchecked Ed25519 public key.
31
    id: [u8; 32],
32
}
33

            
34
impl Ed25519Identity {
35
    /// Construct a new Ed25519 identity from a 32-byte sequence.
36
    ///
37
    /// This might or might not actually be a valid Ed25519 public key.
38
    ///
39
    /// ```
40
    /// use tor_llcrypto::pk::ed25519::{Ed25519Identity, PublicKey};
41
    /// use std::convert::TryInto;
42
    ///
43
    /// let bytes = b"klsadjfkladsfjklsdafkljasdfsdsd!";
44
    /// let id = Ed25519Identity::new(*bytes);
45
    /// let pk: Result<PublicKey,_> = (&id).try_into();
46
    /// assert!(pk.is_ok());
47
    ///
48
    /// let bytes = b"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
49
    /// let id = Ed25519Identity::new(*bytes);
50
    /// let pk: Result<PublicKey,_> = (&id).try_into();
51
    /// assert!(pk.is_err());
52
    /// ```
53
222585
    pub fn new(id: [u8; 32]) -> Self {
54
222585
        Ed25519Identity { id }
55
222585
    }
56
    /// If `id` is of the correct length, wrap it in an Ed25519Identity.
57
142230
    pub fn from_bytes(id: &[u8]) -> Option<Self> {
58
142230
        if id.len() == 32 {
59
144474
            Some(Ed25519Identity::new(*array_ref!(id, 0, 32)))
60
        } else {
61
            None
62
        }
63
142230
    }
64
    /// Return a reference to the bytes in this key.
65
5478
    pub fn as_bytes(&self) -> &[u8] {
66
5478
        &self.id[..]
67
5478
    }
68
}
69

            
70
impl From<[u8; 32]> for Ed25519Identity {
71
80322
    fn from(id: [u8; 32]) -> Self {
72
80322
        Ed25519Identity::new(id)
73
80322
    }
74
}
75

            
76
impl From<PublicKey> for Ed25519Identity {
77
198
    fn from(pk: PublicKey) -> Self {
78
198
        (&pk).into()
79
198
    }
80
}
81

            
82
impl From<&PublicKey> for Ed25519Identity {
83
693
    fn from(pk: &PublicKey) -> Self {
84
693
        // This unwrap is safe because the public key is always 32 bytes
85
693
        // long.
86
693
        Ed25519Identity::from_bytes(pk.as_bytes()).expect("Ed25519 public key had wrong length?")
87
693
    }
88
}
89

            
90
impl TryFrom<&Ed25519Identity> for PublicKey {
91
    type Error = ed25519_dalek::SignatureError;
92
165
    fn try_from(id: &Ed25519Identity) -> Result<PublicKey, Self::Error> {
93
165
        PublicKey::from_bytes(&id.id[..])
94
165
    }
95
}
96

            
97
impl TryFrom<Ed25519Identity> for PublicKey {
98
    type Error = ed25519_dalek::SignatureError;
99
66
    fn try_from(id: Ed25519Identity) -> Result<PublicKey, Self::Error> {
100
66
        (&id).try_into()
101
66
    }
102
}
103

            
104
impl ConstantTimeEq for Ed25519Identity {
105
13816968
    fn ct_eq(&self, other: &Self) -> Choice {
106
13816968
        self.id.ct_eq(&other.id)
107
13816968
    }
108
}
109

            
110
impl PartialEq<Ed25519Identity> for Ed25519Identity {
111
13814196
    fn eq(&self, rhs: &Ed25519Identity) -> bool {
112
13814196
        self.ct_eq(rhs).unwrap_u8() == 1
113
13814196
    }
114
}
115

            
116
impl Eq for Ed25519Identity {}
117

            
118
impl Display for Ed25519Identity {
119
858
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
120
858
        write!(
121
858
            f,
122
858
            "{}",
123
858
            base64::encode_config(self.id, base64::STANDARD_NO_PAD)
124
858
        )
125
858
    }
126
}
127

            
128
impl Debug for Ed25519Identity {
129
660
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
130
660
        write!(f, "Ed25519Identity {{ {} }}", self)
131
660
    }
132
}
133

            
134
impl serde::Serialize for Ed25519Identity {
135
26
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136
26
    where
137
26
        S: serde::Serializer,
138
26
    {
139
26
        if serializer.is_human_readable() {
140
25
            serializer.serialize_str(&base64::encode_config(self.id, base64::STANDARD_NO_PAD))
141
        } else {
142
1
            serializer.serialize_bytes(&self.id[..])
143
        }
144
26
    }
145
}
146

            
147
impl<'de> serde::Deserialize<'de> for Ed25519Identity {
148
28
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
149
28
    where
150
28
        D: serde::Deserializer<'de>,
151
28
    {
152
28
        if deserializer.is_human_readable() {
153
            /// Helper for deserialization
154
            struct EdIdentityVisitor;
155
            impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
156
                type Value = Ed25519Identity;
157
                fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
158
                    fmt.write_str("base64-encoded Ed25519 public key")
159
                }
160
26
                fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
161
26
                where
162
26
                    E: serde::de::Error,
163
26
                {
164
26
                    let bytes =
165
26
                        base64::decode_config(s, base64::STANDARD_NO_PAD).map_err(E::custom)?;
166
26
                    Ed25519Identity::from_bytes(&bytes)
167
26
                        .ok_or_else(|| E::custom("wrong length for Ed25519 public key"))
168
26
                }
169
            }
170

            
171
26
            deserializer.deserialize_str(EdIdentityVisitor)
172
        } else {
173
            /// Helper for deserialization
174
            struct EdIdentityVisitor;
175
            impl<'de> serde::de::Visitor<'de> for EdIdentityVisitor {
176
                type Value = Ed25519Identity;
177
                fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> fmt::Result {
178
                    fmt.write_str("ed25519 public key")
179
                }
180
2
                fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
181
2
                where
182
2
                    E: serde::de::Error,
183
2
                {
184
2
                    Ed25519Identity::from_bytes(bytes)
185
2
                        .ok_or_else(|| E::custom("wrong length for ed25519 public key"))
186
2
                }
187
            }
188
2
            deserializer.deserialize_bytes(EdIdentityVisitor)
189
        }
190
28
    }
191
}
192

            
193
/// An ed25519 signature, plus the document that it signs and its
194
/// public key.
195
pub struct ValidatableEd25519Signature {
196
    /// The key that allegedly produced the signature
197
    key: PublicKey,
198
    /// The alleged signature
199
    sig: Signature,
200
    /// The entire body of text that is allegedly signed here.
201
    ///
202
    /// TODO: It's not so good to have this included here; it
203
    /// would be better to have a patch to ed25519_dalek to allow
204
    /// us to pre-hash the signed thing, and just store a digest.
205
    /// We can't use that with the 'prehash' variant of ed25519,
206
    /// since that has different constants.
207
    entire_text_of_signed_thing: Vec<u8>,
208
}
209

            
210
impl ValidatableEd25519Signature {
211
    /// Create a new ValidatableEd25519Signature
212
1025
    pub fn new(key: PublicKey, sig: Signature, text: &[u8]) -> Self {
213
1025
        ValidatableEd25519Signature {
214
1025
            key,
215
1025
            sig,
216
1025
            entire_text_of_signed_thing: text.into(),
217
1025
        }
218
1025
    }
219

            
220
    /// View the interior of this signature object.
221
891
    pub(crate) fn as_parts(&self) -> (&PublicKey, &Signature, &[u8]) {
222
891
        (&self.key, &self.sig, &self.entire_text_of_signed_thing[..])
223
891
    }
224
}
225

            
226
impl super::ValidatableSignature for ValidatableEd25519Signature {
227
35
    fn is_valid(&self) -> bool {
228
35
        use signature::Verifier;
229
35
        self.key
230
35
            .verify(&self.entire_text_of_signed_thing[..], &self.sig)
231
35
            .is_ok()
232
35
    }
233

            
234
99
    fn as_ed25519(&self) -> Option<&ValidatableEd25519Signature> {
235
99
        Some(self)
236
99
    }
237
}
238

            
239
/// Perform a batch verification operation on the provided signatures
240
///
241
/// Return `true` if _every_ signature is valid; otherwise return `false`.
242
///
243
/// Note that the mathematics for batch validation are slightly
244
/// different than those for normal one-signature validation.  Because
245
/// of this, it is possible for an ostensible signature that passes
246
/// one validation algorithm might fail the other.  (Well-formed
247
/// signatures generated by a correct Ed25519 implementation will
248
/// always pass both kinds of validation, and an attacker should not
249
/// be able to forge a signature that passes either kind.)
250
924
pub fn validate_batch(sigs: &[&ValidatableEd25519Signature]) -> bool {
251
924
    use crate::pk::ValidatableSignature;
252
924
    if sigs.is_empty() {
253
        // ed25519_dalek has nonzero cost for a batch-verification of
254
        // zero sigs.
255
528
        true
256
396
    } else if sigs.len() == 1 {
257
        // Validating one signature in the traditional way is faster.
258
33
        sigs[0].is_valid()
259
    } else {
260
363
        let mut ed_msgs = Vec::new();
261
363
        let mut ed_sigs = Vec::new();
262
363
        let mut ed_pks = Vec::new();
263
1287
        for ed_sig in sigs {
264
924
            let (pk, sig, msg) = ed_sig.as_parts();
265
924
            ed_sigs.push(*sig);
266
924
            ed_pks.push(*pk);
267
924
            ed_msgs.push(msg);
268
924
        }
269
396
        ed25519_dalek::verify_batch(&ed_msgs[..], &ed_sigs[..], &ed_pks[..]).is_ok()
270
    }
271
957
}