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