libcrux_ed25519/
impl_hacl.rs1#[cfg(feature = "codec")]
2use tls_codec::{TlsDeserialize, TlsSerialize, TlsSize};
3
4#[cfg(feature = "codec")]
5extern crate std;
6
7#[cfg(feature = "codec")]
8use std::format;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum Error {
12 SigningError,
13 InvalidSignature,
14 KeyGen,
15}
16
17#[derive(Default, Clone, Copy)]
19#[cfg_attr(feature = "codec", derive(TlsSerialize, TlsDeserialize, TlsSize))]
20pub struct VerificationKey {
21 value: [u8; 32],
22}
23
24impl VerificationKey {
25 pub fn into_bytes(self) -> [u8; 32] {
27 self.value
28 }
29
30 pub fn from_bytes(value: [u8; 32]) -> Self {
32 Self { value }
33 }
34}
35
36impl AsRef<[u8; 32]> for VerificationKey {
37 fn as_ref(&self) -> &[u8; 32] {
38 &self.value
39 }
40}
41
42#[derive(Default)]
44pub struct SigningKey {
45 value: [u8; 32],
46}
47
48impl SigningKey {
49 pub fn into_bytes(self) -> [u8; 32] {
51 self.value
52 }
53
54 pub fn from_bytes(value: [u8; 32]) -> Self {
56 Self { value }
57 }
58}
59
60impl AsRef<[u8; 32]> for SigningKey {
61 fn as_ref(&self) -> &[u8; 32] {
62 &self.value
63 }
64}
65
66#[inline(always)]
75pub fn sign(payload: &[u8], private_key: &[u8; 32]) -> Result<[u8; 64], Error> {
76 let mut signature = [0u8; 64];
77 crate::hacl::ed25519::sign(
78 &mut signature,
79 private_key,
80 payload.len().try_into().map_err(|_| Error::SigningError)?,
81 payload,
82 );
83
84 Ok(signature)
85}
86
87#[inline(always)]
96pub fn verify(payload: &[u8], public_key: &[u8; 32], signature: &[u8; 64]) -> Result<(), Error> {
97 if crate::hacl::ed25519::verify(
98 public_key,
99 payload.len().try_into().map_err(|_| Error::SigningError)?,
100 payload,
101 signature,
102 ) {
103 Ok(())
104 } else {
105 Err(Error::InvalidSignature)
106 }
107}
108
109#[inline(always)]
113pub fn secret_to_public(pk: &mut [u8; 32], sk: &[u8; 32]) {
114 crate::hacl::ed25519::secret_to_public(pk, sk)
115}
116
117#[cfg(feature = "rand")]
118pub fn generate_key_pair(
119 rng: &mut impl rand_core::CryptoRng,
120) -> Result<(SigningKey, VerificationKey), Error> {
121 use rand_core::TryRngCore;
122
123 const LIMIT: usize = 100;
124 let mut sk = [0u8; 32];
125 let mut pk = [0u8; 32];
126
127 for _ in 0..LIMIT {
128 rng.try_fill_bytes(&mut sk).map_err(|_| Error::KeyGen)?;
129
130 if sk.iter().all(|&b| b == 0) {
132 sk = [0u8; 32];
133 continue;
134 }
135
136 break;
137 }
138
139 secret_to_public(&mut pk, &sk);
140
141 Ok((SigningKey { value: sk }, VerificationKey { value: pk }))
142}