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