1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use core::fmt::Debug;
16 
17 // User-facing, crypto-provider independent structs
18 
19 /// The length of a ed25519 `Signature`, in bytes.
20 pub const SIGNATURE_LENGTH: usize = 64;
21 
22 /// The length of an ed25519 `PrivateKey`, in bytes.
23 pub const PRIVATE_KEY_LENGTH: usize = 32;
24 
25 /// The length of an ed25519 `PrivateKey`, in bytes.
26 pub const PUBLIC_KEY_LENGTH: usize = 32;
27 
28 /// A byte buffer the size of a ed25519 `Signature`.
29 pub type RawSignature = [u8; SIGNATURE_LENGTH];
30 
31 /// A byte buffer the size of a ed25519 `PublicKey`.
32 pub type RawPublicKey = [u8; PUBLIC_KEY_LENGTH];
33 
34 /// A byte buffer the size of a ed25519 `PrivateKey`.
35 pub type RawPrivateKey = [u8; PRIVATE_KEY_LENGTH];
36 
37 /// A permission token which may be supplied to methods which allow
38 /// converting private keys to/from raw bytes.
39 ///
40 /// In general, operations of this kind should only be done in
41 /// development-tools, tests, or in credential storage layers
42 /// to prevent accidental exposure of the private key.
43 pub struct RawPrivateKeyPermit {
44     _marker: (),
45 }
46 
47 impl RawPrivateKeyPermit {
new() -> Self48     pub(crate) fn new() -> Self {
49         Self { _marker: () }
50     }
51 }
52 
53 #[cfg(feature = "raw_private_key_permit")]
54 impl core::default::Default for RawPrivateKeyPermit {
default() -> Self55     fn default() -> Self {
56         Self::new()
57     }
58 }
59 
60 /// A crypto-provider-independent representation of the private
61 /// key of an ed25519 key-pair, kept in such a way that
62 /// it does not permit de-structuring it into raw bytes,
63 /// nor constructing one from raw bytes.
64 ///
65 /// Useful for when you want a data-structure to be
66 /// crypto-provider independent and contain a private key.
67 #[derive(Clone)]
68 pub struct PrivateKey(RawPrivateKey);
69 
70 impl PrivateKey {
71     /// Derives the public key corresponding to this private key.
derive_public_key<E: Ed25519Provider>(&self) -> PublicKey72     pub fn derive_public_key<E: Ed25519Provider>(&self) -> PublicKey {
73         let key_pair = E::KeyPair::from_private_key(self);
74         key_pair.public_key().to_external()
75     }
76     /// Sign the given message and return a digital signature
sign<E: Ed25519Provider>(&self, msg: &[u8]) -> Signature77     pub fn sign<E: Ed25519Provider>(&self, msg: &[u8]) -> Signature {
78         let key_pair = E::KeyPair::from_private_key(self);
79         key_pair.sign(msg).to_external()
80     }
81     /// Generate an ed25519 private key from a CSPRNG
82     /// generate is not available in `no-std`.
83     #[cfg(feature = "std")]
generate<E: Ed25519Provider>() -> Self84     pub fn generate<E: Ed25519Provider>() -> Self {
85         let key_pair = E::KeyPair::generate();
86         key_pair.private_key()
87     }
88 
89     /// Returns the raw bytes of this private key.
90     /// This operation is only possible while holding a [`RawPrivateKeyPermit`].
raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey91     pub fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey {
92         self.0
93     }
94     /// Constructs a private key from the raw bytes of the key.
95     /// This operation is only possible while holding a [`RawPrivateKeyPermit`].
from_raw_private_key(wrapped: RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self96     pub fn from_raw_private_key(wrapped: RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self {
97         PrivateKey(wrapped)
98     }
99 }
100 
101 /// error returned when bad bytes are provided to generate keypair
102 #[derive(Debug)]
103 pub struct InvalidPublicKeyBytes;
104 
105 /// Error returned if the verification on the signature + message fails
106 #[derive(Debug)]
107 pub struct SignatureError;
108 
109 /// A crypto-provider-independent representation of a valid
110 /// public key for an ed25519 key-pair in the Edwards Y-format.
111 ///
112 /// Useful for when you want a data-structure to be crypto-provider
113 /// independent and contain a public key.
114 #[derive(Clone, Debug, PartialEq, Eq)]
115 pub struct PublicKey(RawPublicKey);
116 
117 impl PublicKey {
118     /// Attempts to parse a public key from an array of bytes.
119     /// If the input is not in the Edwards Y-format, this method
120     /// will yield an `InvalidPublicKeyBytes` error.
from_bytes<E: Ed25519Provider>( wrapped: RawPublicKey, ) -> Result<Self, InvalidPublicKeyBytes>121     pub fn from_bytes<E: Ed25519Provider>(
122         wrapped: RawPublicKey,
123     ) -> Result<Self, InvalidPublicKeyBytes> {
124         // Simply verify that we can construct the crypto-provider-dependent variant.
125         let _ = <E::PublicKey as PublicKeyImpl>::from_bytes(&wrapped)?;
126         Ok(PublicKey(wrapped))
127     }
128     /// Converts this public-key into the raw bytes of this public-key.
into_bytes(self) -> RawPublicKey129     pub fn into_bytes(self) -> RawPublicKey {
130         self.0
131     }
132 
133     /// Converts this crypto-provider-independent public key to a crypto-provider's internal rep.
134     #[allow(clippy::expect_used)]
as_internal<E: Ed25519Provider>(&self) -> E::PublicKey135     fn as_internal<E: Ed25519Provider>(&self) -> E::PublicKey {
136         <E::PublicKey as PublicKeyImpl>::from_bytes(&self.0)
137             .expect("Public key bytes validated upon construction.")
138     }
139 
140     /// Succeeds if the signature on the given message is verified
141     /// by this public key.
verify_strict<E: Ed25519Provider>( &self, message: &[u8], signature: Signature, ) -> Result<(), SignatureError>142     pub fn verify_strict<E: Ed25519Provider>(
143         &self,
144         message: &[u8],
145         signature: Signature,
146     ) -> Result<(), SignatureError> {
147         let public_key = self.as_internal::<E>();
148         let signature = signature.as_internal::<E>();
149         public_key.verify_strict(message, &signature)
150     }
151 }
152 
153 /// A crypto-provider-independent representation of an Ed25519 signature.
154 /// The underlying representation here can be any arbitrary bytes - verifying
155 /// code handles determining whether/not the signature actually corresponds
156 /// to a real Ed25519 signature and matches the given public key.
157 #[derive(Clone)]
158 pub struct Signature(RawSignature);
159 
160 impl From<RawSignature> for Signature {
from(wrapped: RawSignature) -> Self161     fn from(wrapped: RawSignature) -> Self {
162         Signature(wrapped)
163     }
164 }
165 
166 impl Signature {
167     /// Constructs a signature from raw bytes.
new(wrapped: RawSignature) -> Self168     pub fn new(wrapped: RawSignature) -> Self {
169         Signature(wrapped)
170     }
171     /// Transforms this signature back into raw bytes.
to_bytes(self) -> RawSignature172     pub fn to_bytes(self) -> RawSignature {
173         self.0
174     }
175     /// Converts this crypto-provider-independent signature to a crypto-provider's internal rep.
as_internal<E: Ed25519Provider>(&self) -> E::Signature176     fn as_internal<E: Ed25519Provider>(&self) -> E::Signature {
177         <E::Signature as SignatureImpl>::from_bytes(&self.0)
178     }
179 }
180 
181 // Implementor-facing crypto-provider-internal traits.
182 
183 /// Collection of types used to provide an implementation of ed25519, the Edwards-curve Digital
184 /// Signature Algorithm scheme using sha-512 (sha2) and Curve25519
185 pub trait Ed25519Provider {
186     /// The internal representation of a keypair which includes both public and secret halves of an asymmetric key.
187     type KeyPair: KeyPairImpl<PublicKey = Self::PublicKey, Signature = Self::Signature>;
188     /// The internal representation of an ed25519 public key, used when verifying a message
189     type PublicKey: PublicKeyImpl<Signature = Self::Signature>;
190     /// The internal representation of an ed25519 signature which is the result of signing a message
191     type Signature: SignatureImpl;
192 }
193 
194 /// The keypair which includes both public and secret halves of an asymmetric key.
195 pub trait KeyPairImpl: Sized {
196     /// The ed25519 public key, used when verifying a message
197     type PublicKey: PublicKeyImpl;
198 
199     /// The ed25519 signature returned when signing a message
200     type Signature: SignatureImpl;
201 
202     /// Returns the private key bytes of the `KeyPair`.
203     /// This operation is only possible while holding a [`RawPrivateKeyPermit`].
raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey204     fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey;
205 
206     /// Builds a key-pair from a `RawPrivateKey` array of bytes.
207     /// This operation is only possible while holding a [`RawPrivateKeyPermit`].
from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self where Self: Sized208     fn from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self
209     where
210         Self: Sized;
211 
212     /// Returns the private key of the `KeyPair` in an opaque form.
private_key(&self) -> PrivateKey213     fn private_key(&self) -> PrivateKey {
214         // We're okay to reach in and grab the bytes of the private key,
215         // since the way that we're exposing it would require a valid
216         // [`RawPrivateKeyPermit`] to extract them again.
217         let wrapped = self.raw_private_key(&RawPrivateKeyPermit::new());
218         PrivateKey(wrapped)
219     }
220 
221     /// Builds a key-pair from a [`PrivateKey`], given in an opaque form.
from_private_key(private_key: &PrivateKey) -> Self where Self: Sized,222     fn from_private_key(private_key: &PrivateKey) -> Self
223     where
224         Self: Sized,
225     {
226         // We're okay to reach in and construct an instance from
227         // the bytes of the private key, since the way that they
228         // were originally expressed would still require a valid
229         // [`RawPrivateKeyPermit`] to access them.
230         let raw_private_key = &private_key.0;
231         Self::from_raw_private_key(raw_private_key, &RawPrivateKeyPermit::new())
232     }
233 
234     /// Sign the given message and return a digital signature
sign(&self, msg: &[u8]) -> Self::Signature235     fn sign(&self, msg: &[u8]) -> Self::Signature;
236 
237     /// Generate an ed25519 keypair from a CSPRNG
238     /// generate is not available in `no-std`
239     #[cfg(feature = "std")]
generate() -> Self240     fn generate() -> Self;
241 
242     /// getter function for the Public Key of the key pair
public_key(&self) -> Self::PublicKey243     fn public_key(&self) -> Self::PublicKey;
244 }
245 
246 /// An ed25519 signature
247 pub trait SignatureImpl: Sized {
248     /// Create a new signature from a fixed size byte array. This represents a container for the
249     /// byte serialization of an Ed25519 signature, and does not necessarily represent well-formed
250     /// field or curve elements.
251     ///
252     /// Signature verification libraries are expected to reject invalid field
253     /// elements at the time a signature is verified (not constructed).
from_bytes(bytes: &RawSignature) -> Self254     fn from_bytes(bytes: &RawSignature) -> Self;
255 
256     /// Returns a slice of the signature bytes
to_bytes(&self) -> RawSignature257     fn to_bytes(&self) -> RawSignature;
258 
259     /// Returns a crypto-provider-independent `Signature` from this implementation-specific struct.
to_external(&self) -> Signature260     fn to_external(&self) -> Signature {
261         let wrapped = self.to_bytes();
262         Signature(wrapped)
263     }
264 }
265 
266 /// An ed25519 public key
267 pub trait PublicKeyImpl {
268     /// the signature type being used by verify
269     type Signature: SignatureImpl;
270 
271     /// Builds this public key from an array of bytes in
272     /// the format yielded by `to_bytes`.
from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes> where Self: Sized273     fn from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes>
274     where
275         Self: Sized;
276 
277     /// Yields the bytes of the public key
to_bytes(&self) -> RawPublicKey278     fn to_bytes(&self) -> RawPublicKey;
279 
280     /// Returns a crypto-provider-independent `PublicKey` from this implementation-specific struct.
to_external(&self) -> PublicKey281     fn to_external(&self) -> PublicKey {
282         let wrapped = self.to_bytes();
283         PublicKey(wrapped)
284     }
285 
286     /// Succeeds if the signature was a valid signature created by this Keypair on the prehashed_message.
verify_strict( &self, message: &[u8], signature: &Self::Signature, ) -> Result<(), SignatureError>287     fn verify_strict(
288         &self,
289         message: &[u8],
290         signature: &Self::Signature,
291     ) -> Result<(), SignatureError>;
292 }
293