• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 ed25519_dalek::Signer;
16 
17 use crypto_provider::ed25519::{
18     InvalidPublicKeyBytes, RawPrivateKey, RawPrivateKeyPermit, RawPublicKey, RawSignature,
19     SignatureError, SignatureImpl, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH,
20 };
21 
22 pub struct Ed25519;
23 
24 impl crypto_provider::ed25519::Ed25519Provider for Ed25519 {
25     type KeyPair = KeyPair;
26     type PublicKey = PublicKey;
27     type Signature = Signature;
28 }
29 
30 pub struct KeyPair(ed25519_dalek::SigningKey);
31 
32 impl crypto_provider::ed25519::KeyPairImpl for KeyPair {
33     type PublicKey = PublicKey;
34     type Signature = Signature;
35 
raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> [u8; PRIVATE_KEY_LENGTH]36     fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> [u8; PRIVATE_KEY_LENGTH] {
37         self.0.to_bytes()
38     }
39 
from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self40     fn from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self {
41         Self(ed25519_dalek::SigningKey::from_bytes(bytes))
42     }
43 
44     #[allow(clippy::expect_used)]
sign(&self, msg: &[u8]) -> Self::Signature45     fn sign(&self, msg: &[u8]) -> Self::Signature {
46         Self::Signature::from_bytes(&self.0.sign(msg).to_bytes())
47     }
48 
49     //TODO: allow providing a crypto rng and make it a no-op for openssl if the need arises to
50     // improve perf of keypair generation
51     #[cfg(feature = "std")]
generate() -> Self52     fn generate() -> Self {
53         let mut csprng = rand::rngs::ThreadRng::default();
54         Self(ed25519_dalek::SigningKey::generate(&mut csprng))
55     }
56 
public_key(&self) -> Self::PublicKey57     fn public_key(&self) -> Self::PublicKey {
58         PublicKey(self.0.verifying_key())
59     }
60 }
61 
62 pub struct Signature(ed25519_dalek::Signature);
63 
64 impl crypto_provider::ed25519::SignatureImpl for Signature {
from_bytes(bytes: &RawSignature) -> Self65     fn from_bytes(bytes: &RawSignature) -> Self {
66         Self(ed25519_dalek::Signature::from_bytes(bytes))
67     }
68 
to_bytes(&self) -> [u8; SIGNATURE_LENGTH]69     fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
70         self.0.to_bytes()
71     }
72 }
73 
74 pub struct PublicKey(ed25519_dalek::VerifyingKey);
75 
76 impl crypto_provider::ed25519::PublicKeyImpl for PublicKey {
77     type Signature = Signature;
78 
from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes> where Self: Sized,79     fn from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidPublicKeyBytes>
80     where
81         Self: Sized,
82     {
83         ed25519_dalek::VerifyingKey::from_bytes(bytes)
84             .map(PublicKey)
85             .map_err(|_| InvalidPublicKeyBytes)
86     }
87 
to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH]88     fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
89         self.0.to_bytes()
90     }
91 
verify_strict( &self, message: &[u8], signature: &Self::Signature, ) -> Result<(), SignatureError>92     fn verify_strict(
93         &self,
94         message: &[u8],
95         signature: &Self::Signature,
96     ) -> Result<(), SignatureError> {
97         self.0.verify_strict(message, &signature.0).map_err(|_| SignatureError)
98     }
99 }
100 
101 #[cfg(test)]
102 mod tests {
103     use crypto_provider_test::ed25519::{run_rfc_test_vectors, run_wycheproof_test_vectors};
104 
105     use crate::ed25519::Ed25519;
106 
107     #[test]
wycheproof_test_ed25519_rustcrypto()108     fn wycheproof_test_ed25519_rustcrypto() {
109         run_wycheproof_test_vectors::<Ed25519>()
110     }
111 
112     #[test]
rfc_test_ed25519_rustcrypto()113     fn rfc_test_ed25519_rustcrypto() {
114         run_rfc_test_vectors::<Ed25519>()
115     }
116 }
117