embedded_td/crypto/
ed25519.rs1use curve25519_dalek_ng::{constants, scalar::Scalar};
2use rand_core::{CryptoRng, RngCore};
3use sha2::{Digest, Sha512};
4
5use super::define_as_ref_u8_array;
6
7#[derive(Debug, Clone)]
8pub struct SecretKey(pub [u8; 64]);
9define_as_ref_u8_array!(SecretKey);
10
11#[derive(Debug, Clone)]
12pub struct PublicKey(pub [u8; 32]);
13define_as_ref_u8_array!(PublicKey);
14
15impl SecretKey {
16 pub fn generate(rng: impl RngCore + CryptoRng) -> Self {
17 let mut rng = rng;
18
19 let mut sk = [0u8; 64];
20
21 rng.fill_bytes(&mut sk[..32]);
22
23 let mut h = Sha512::new();
26 let mut hash: [u8; 64] = [0u8; 64];
27 let mut digest: [u8; 32] = [0u8; 32];
28
29 h.update(&sk[..32]);
30 hash.copy_from_slice(&h.finalize());
31
32 digest.copy_from_slice(&hash[..32]);
33
34 {
36 let mut bits = digest;
37
38 bits[0] &= 248;
39 bits[31] &= 127;
40 bits[31] |= 64;
41
42 let point = &Scalar::from_bits(bits) * &constants::ED25519_BASEPOINT_TABLE;
43 let compressed = point.compress();
44
45 let pk = &mut sk[32..];
46
47 pk.copy_from_slice(&compressed.0);
48 }
49
50 Self(sk)
51 }
52
53 pub fn public_key(&self) -> PublicKey {
54 let mut pk = [0u8; 32];
55
56 pk.copy_from_slice(&self.0[32..]);
57 PublicKey(pk)
58 }
59}