blob: d11a5eab4f3b098c11f84b209660f88fbda32375 [file] [log] [blame]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use ed25519_dalek::Signer;
use crypto_provider::ed25519::{
InvalidBytes, RawPrivateKey, RawPublicKey, RawSignature, Signature as _, SignatureError,
PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH,
};
pub struct Ed25519;
impl crypto_provider::ed25519::Ed25519Provider for Ed25519 {
type KeyPair = KeyPair;
type PublicKey = PublicKey;
type Signature = Signature;
}
pub struct KeyPair(ed25519_dalek::SigningKey);
impl crypto_provider::ed25519::KeyPair for KeyPair {
type PublicKey = PublicKey;
type Signature = Signature;
fn private_key(&self) -> [u8; PRIVATE_KEY_LENGTH] {
self.0.to_bytes()
}
fn from_private_key(bytes: &RawPrivateKey) -> Self {
Self(ed25519_dalek::SigningKey::from_bytes(bytes))
}
#[allow(clippy::expect_used)]
fn sign(&self, msg: &[u8]) -> Self::Signature {
Self::Signature::from_bytes(&self.0.sign(msg).to_bytes())
}
//TODO: allow providing a crypto rng and make it a no-op for openssl if the need arises to
// improve perf of keypair generation
#[cfg(feature = "std")]
fn generate() -> Self {
let mut csprng = rand::rngs::ThreadRng::default();
Self(ed25519_dalek::SigningKey::generate(&mut csprng))
}
fn public(&self) -> Self::PublicKey {
PublicKey(self.0.verifying_key())
}
}
pub struct Signature(ed25519_dalek::Signature);
impl crypto_provider::ed25519::Signature for Signature {
fn from_bytes(bytes: &RawSignature) -> Self {
Self(ed25519_dalek::Signature::from_bytes(bytes))
}
fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
self.0.to_bytes()
}
}
pub struct PublicKey(ed25519_dalek::VerifyingKey);
impl crypto_provider::ed25519::PublicKey for PublicKey {
type Signature = Signature;
fn from_bytes(bytes: &RawPublicKey) -> Result<Self, InvalidBytes>
where
Self: Sized,
{
ed25519_dalek::VerifyingKey::from_bytes(bytes).map(PublicKey).map_err(|_| InvalidBytes)
}
fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
self.0.to_bytes()
}
fn verify_strict(
&self,
message: &[u8],
signature: &Self::Signature,
) -> Result<(), SignatureError> {
self.0.verify_strict(message, &signature.0).map_err(|_| SignatureError)
}
}
#[cfg(test)]
mod tests {
use crypto_provider_test::ed25519::{run_rfc_test_vectors, run_wycheproof_test_vectors};
use crate::ed25519::Ed25519;
#[test]
fn wycheproof_test_ed25519_rustcrypto() {
run_wycheproof_test_vectors::<Ed25519>()
}
#[test]
fn rfc_test_ed25519_rustcrypto() {
run_rfc_test_vectors::<Ed25519>()
}
}