1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#[cfg(all(feature = "rand", feature = "std"))]
use rand::{CryptoRng, OsRng, RngCore};
#[cfg(feature = "encoding")]
use subtle_encoding::Encoding;
use zeroize::Zeroize;
#[cfg(feature = "encoding")]
use encoding::Decode;
#[cfg(all(feature = "alloc", feature = "encoding"))]
use encoding::Encode;
use error::Error;
#[allow(unused_imports)]
use prelude::*;
pub const SEED_SIZE: usize = 32;
pub const KEYPAIR_SIZE: usize = 64;
#[derive(Clone)]
pub struct Seed(pub [u8; SEED_SIZE]);
impl Seed {
pub fn new(bytes: [u8; SEED_SIZE]) -> Self {
Seed(bytes)
}
#[cfg(all(feature = "rand", feature = "std"))]
pub fn generate() -> Self {
let mut csprng = OsRng::new().expect("RNG initialization failure!");
Self::generate_from_rng::<OsRng>(&mut csprng)
}
#[cfg(feature = "rand")]
pub fn generate_from_rng<R: CryptoRng + RngCore>(csprng: &mut R) -> Self {
let mut bytes = [0u8; SEED_SIZE];
csprng.fill_bytes(&mut bytes[..]);
Self::new(bytes)
}
pub fn from_bytes<B>(bytes: B) -> Result<Self, Error>
where
B: AsRef<[u8]>,
{
ensure!(
bytes.as_ref().len() == SEED_SIZE,
KeyInvalid,
"expected {}-byte seed (got {})",
SEED_SIZE,
bytes.as_ref().len()
);
let mut seed = [0u8; SEED_SIZE];
seed.copy_from_slice(bytes.as_ref());
Ok(Seed::new(seed))
}
pub fn from_keypair(keypair: &[u8]) -> Result<Self, Error> {
ensure!(
keypair.len() == KEYPAIR_SIZE,
KeyInvalid,
"invalid {}-byte keypair (expected {})",
keypair.len(),
KEYPAIR_SIZE
);
Self::from_bytes(&keypair[..SEED_SIZE])
}
#[cfg(feature = "encoding")]
pub fn decode_keypair<E: Encoding>(
encoded_keypair: &[u8],
encoding: &E,
) -> Result<Self, Error> {
let mut decoded_keypair = [0u8; SEED_SIZE * 2];
let decoded_len = encoding.decode_to_slice(encoded_keypair, &mut decoded_keypair)?;
ensure!(
decoded_len == SEED_SIZE * 2,
KeyInvalid,
"malformed keypair (incorrect length)"
);
Self::from_keypair(&decoded_keypair)
}
pub fn as_secret_slice(&self) -> &[u8] {
self.0.as_ref()
}
}
#[cfg(feature = "encoding")]
impl Decode for Seed {
fn decode<E: Encoding>(encoded_seed: &[u8], encoding: &E) -> Result<Self, Error> {
let mut decoded_seed = [0u8; SEED_SIZE];
let decoded_len = encoding.decode_to_slice(encoded_seed, &mut decoded_seed)?;
ensure!(
decoded_len == SEED_SIZE,
KeyInvalid,
"invalid {}-byte seed (expected {})",
decoded_len,
SEED_SIZE
);
Ok(Self::new(decoded_seed))
}
}
#[cfg(all(feature = "encoding", feature = "alloc"))]
impl Encode for Seed {
fn encode<E: Encoding>(&self, encoding: &E) -> Vec<u8> {
encoding.encode(self.as_secret_slice())
}
}
impl Drop for Seed {
fn drop(&mut self) {
self.0.zeroize();
}
}
impl From<[u8; 32]> for Seed {
fn from(bytes: [u8; SEED_SIZE]) -> Self {
Seed::new(bytes)
}
}