solana_core/
gen_keys.rs

1//! The `gen_keys` module makes lots of keypairs
2
3use {
4    rand::{Rng, SeedableRng},
5    rand_chacha::ChaChaRng,
6    rayon::prelude::*,
7    solana_keypair::{keypair_from_seed, Keypair},
8};
9
10pub struct GenKeys {
11    generator: ChaChaRng,
12}
13
14impl GenKeys {
15    pub fn new(seed: [u8; 32]) -> GenKeys {
16        let generator = ChaChaRng::from_seed(seed);
17        GenKeys { generator }
18    }
19
20    fn gen_seed(&mut self) -> [u8; 32] {
21        let mut seed = [0u8; 32];
22        self.generator.fill(&mut seed);
23        seed
24    }
25
26    fn gen_n_seeds(&mut self, n: u64) -> Vec<[u8; 32]> {
27        (0..n).map(|_| self.gen_seed()).collect()
28    }
29
30    pub fn gen_keypair(&mut self) -> Keypair {
31        let mut seed = [0u8; Keypair::SECRET_KEY_LENGTH];
32        self.generator.fill(&mut seed[..]);
33        keypair_from_seed(&seed).unwrap()
34    }
35
36    pub fn gen_n_keypairs(&mut self, n: u64) -> Vec<Keypair> {
37        self.gen_n_seeds(n)
38            .into_par_iter()
39            .map(|seed| {
40                let mut keypair_seed = [0u8; Keypair::SECRET_KEY_LENGTH];
41                ChaChaRng::from_seed(seed).fill(&mut keypair_seed[..]);
42                keypair_from_seed(&keypair_seed).unwrap()
43            })
44            .collect()
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    pub use solana_pubkey::Pubkey;
51    use {super::*, solana_signer::Signer, std::collections::HashSet};
52
53    #[test]
54    fn test_new_key_is_deterministic() {
55        let seed = [0u8; 32];
56        let mut gen0 = GenKeys::new(seed);
57        let mut gen1 = GenKeys::new(seed);
58
59        for _ in 0..100 {
60            assert_eq!(gen0.gen_seed().to_vec(), gen1.gen_seed().to_vec());
61        }
62    }
63
64    #[test]
65    fn test_gen_keypair_is_deterministic() {
66        let seed = [0u8; 32];
67        let mut gen0 = GenKeys::new(seed);
68        let mut gen1 = GenKeys::new(seed);
69        assert_eq!(
70            gen0.gen_keypair().to_bytes().to_vec(),
71            gen1.gen_keypair().to_bytes().to_vec()
72        );
73    }
74
75    fn gen_n_pubkeys(seed: [u8; 32], n: u64) -> HashSet<Pubkey> {
76        GenKeys::new(seed)
77            .gen_n_keypairs(n)
78            .into_iter()
79            .map(|x| x.pubkey())
80            .collect()
81    }
82
83    #[test]
84    fn test_gen_n_pubkeys_deterministic() {
85        let seed = [0u8; 32];
86        assert_eq!(gen_n_pubkeys(seed, 50), gen_n_pubkeys(seed, 50));
87    }
88}