1 | use super::{Curve, ELEM_MAX_BYTES, SEED_MAX_BYTES}; |
2 | use crate::{cpu, error, rand}; |
3 | |
4 | pub struct KeyPair { |
5 | seed: Seed, |
6 | public_key: PublicKey, |
7 | } |
8 | |
9 | impl KeyPair { |
10 | pub(super) fn derive( |
11 | seed: Seed, |
12 | cpu_features: cpu::Features, |
13 | ) -> Result<Self, error::Unspecified> { |
14 | let public_key: PublicKey = seed.compute_public_key(cpu_features)?; |
15 | Ok(Self { seed, public_key }) |
16 | } |
17 | |
18 | pub fn public_key(&self) -> &PublicKey { |
19 | &self.public_key |
20 | } |
21 | pub fn split(self) -> (Seed, PublicKey) { |
22 | (self.seed, self.public_key) |
23 | } |
24 | } |
25 | |
26 | pub struct Seed { |
27 | bytes: [u8; SEED_MAX_BYTES], |
28 | curve: &'static Curve, |
29 | } |
30 | |
31 | impl Seed { |
32 | pub(crate) fn generate( |
33 | curve: &'static Curve, |
34 | rng: &dyn rand::SecureRandom, |
35 | cpu: cpu::Features, |
36 | ) -> Result<Self, error::Unspecified> { |
37 | let mut r = Self { |
38 | bytes: [0u8; SEED_MAX_BYTES], |
39 | curve, |
40 | }; |
41 | (curve.generate_private_key)(rng, &mut r.bytes[..curve.elem_scalar_seed_len], cpu)?; |
42 | Ok(r) |
43 | } |
44 | |
45 | pub(crate) fn from_bytes( |
46 | curve: &'static Curve, |
47 | bytes: untrusted::Input, |
48 | cpu: cpu::Features, |
49 | ) -> Result<Self, error::Unspecified> { |
50 | let bytes = bytes.as_slice_less_safe(); |
51 | if curve.elem_scalar_seed_len != bytes.len() { |
52 | return Err(error::Unspecified); |
53 | } |
54 | (curve.check_private_key_bytes)(bytes, cpu)?; |
55 | let mut r = Self { |
56 | bytes: [0; SEED_MAX_BYTES], |
57 | curve, |
58 | }; |
59 | r.bytes[..curve.elem_scalar_seed_len].copy_from_slice(bytes); |
60 | Ok(r) |
61 | } |
62 | |
63 | pub fn bytes_less_safe(&self) -> &[u8] { |
64 | &self.bytes[..self.curve.elem_scalar_seed_len] |
65 | } |
66 | |
67 | pub(crate) fn compute_public_key( |
68 | &self, |
69 | cpu_features: cpu::Features, |
70 | ) -> Result<PublicKey, error::Unspecified> { |
71 | let mut public_key = PublicKey { |
72 | bytes: [0u8; PUBLIC_KEY_MAX_LEN], |
73 | len: self.curve.public_key_len, |
74 | }; |
75 | (self.curve.public_from_private)( |
76 | &mut public_key.bytes[..public_key.len], |
77 | self, |
78 | cpu_features, |
79 | )?; |
80 | Ok(public_key) |
81 | } |
82 | } |
83 | |
84 | #[derive (Copy, Clone)] |
85 | pub struct PublicKey { |
86 | bytes: [u8; PUBLIC_KEY_MAX_LEN], |
87 | len: usize, |
88 | } |
89 | |
90 | impl AsRef<[u8]> for PublicKey { |
91 | fn as_ref(&self) -> &[u8] { |
92 | &self.bytes[..self.len] |
93 | } |
94 | } |
95 | |
96 | /// The maximum length, in bytes, of an encoded public key. |
97 | pub const PUBLIC_KEY_MAX_LEN: usize = 1 + (2 * ELEM_MAX_BYTES); |
98 | |