@@ -4,11 +4,12 @@ pub use cli::{KeygenSubcommands, Keysplit, Manual, Onchain};
44use error:: KeysplitError ;
55use global_config:: GlobalConfig ;
66use openssl:: { pkey:: Public , rsa:: Rsa } ;
7+ use rayon:: prelude:: * ;
78use tracing:: info;
89use types:: { PublicKey , SecretKey } ;
910
1011use crate :: {
11- crypto:: { encrypt_keyshares, split_keys } ,
12+ crypto:: { encrypt_keyshares, split_key } ,
1213 output:: OutputData ,
1314 split:: { manual_split, onchain_split} ,
1415 util:: read_password,
@@ -17,19 +18,19 @@ use crate::{
1718mod cli;
1819mod crypto;
1920mod error;
20- mod output;
21+ pub mod output;
2122mod split;
2223mod util;
2324
2425// A specific operators keyshare
25- pub ( crate ) struct KeyShare {
26+ pub struct KeyShare {
2627 id : u64 ,
2728 public_key : Rsa < Public > ,
2829 keyshare : SecretKey ,
2930}
3031
3132// A keyshare where the secretkey has been encrypted with the operators public key
32- pub ( crate ) struct EncryptedKeyShare {
33+ pub struct EncryptedKeyShare {
3334 id : u64 ,
3435 public_key : Rsa < Public > ,
3536 share_public_key : PublicKey ,
@@ -40,53 +41,63 @@ pub fn run_keysplitter(
4041 keysplit : Keysplit ,
4142 global_config : GlobalConfig ,
4243) -> Result < ( ) , KeysplitError > {
43- let shared = keysplit. get_shared ( ) . clone ( ) ;
44+ let shared = keysplit. get_shared ( ) ;
4445 info ! ( "----- Anchor Keysplitter -----" ) ;
4546
46- // 1) Read in the keystore file and parse it into a usable format
47- info ! (
48- "Reading in validator keystore file from {}..." ,
49- shared. keystore_path
50- ) ;
51- let keystore = eth2_keystore:: Keystore :: from_json_file ( & shared. keystore_path )
52- . map_err ( |e| KeysplitError :: Keystore ( format ! ( "Failed to read keystore file: {e:?}" ) ) ) ?;
53- info ! ( "Successfully read in validator keystore file" ) ;
47+ // 1) Read in the keystore files and parse them into a usable format
48+ let keystores = shared
49+ . keystore_paths
50+ . iter ( )
51+ . map ( |path| {
52+ info ! ( "Reading in validator keystore file from {path}..." , ) ;
53+ eth2_keystore:: Keystore :: from_json_file ( path) . map_err ( |e| {
54+ KeysplitError :: Keystore ( format ! ( "Failed to read keystore file: {e:?}" ) )
55+ } )
56+ } )
57+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
58+ info ! ( "Successfully read in validator keystore file(s)" ) ;
5459
5560 // 2) Extract the validator keys from the keystore file
56- info ! ( "Extracting keys from keystore file..." ) ;
57- let keys = keystore
58- . decrypt_keypair (
59- read_password ( shared. password_file . as_deref ( ) )
60- . map_err ( |e| KeysplitError :: Keystore ( format ! ( "Unable to get password: {e}" ) ) ) ?
61- . as_bytes ( ) ,
62- )
63- . map_err ( |e| KeysplitError :: Keystore ( format ! ( "Failed to decrypt keystore file: {e:?}" ) ) ) ?;
64- info ! ( "Successfully extracted keys from keystore file" ) ;
61+ info ! ( "Extracting keys from keystore file(s)..." ) ;
62+ let password = read_password ( shared. password_file . as_deref ( ) )
63+ . map_err ( |e| KeysplitError :: Keystore ( format ! ( "Unable to get password: {e}" ) ) ) ?;
64+ let keys = keystores
65+ . into_par_iter ( )
66+ . map ( |keystore| {
67+ keystore. decrypt_keypair ( password. as_bytes ( ) ) . map_err ( |e| {
68+ KeysplitError :: Keystore ( format ! ( "Failed to decrypt keystore file: {e:?}" ) )
69+ } )
70+ } )
71+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
72+ info ! ( "Successfully extracted keys from keystore file(s)" ) ;
6573
6674 // 3) Split the key into keyshares and group together relevant information
6775 info ! (
68- "Splitting validator key into {} shares..." ,
76+ "Splitting validator key(s) into {} shares..." ,
6977 shared. operators. 0 . len( )
7078 ) ;
71- let ( keyshares , nonce ) = match keysplit. subcommand {
72- KeygenSubcommands :: Manual ( manual) => manual_split ( manual, keys. sk . clone ( ) ) ,
79+ let splits = match keysplit. subcommand {
80+ KeygenSubcommands :: Manual ( manual) => manual_split ( manual, keys. iter ( ) . map ( |k| & k . sk ) ) ,
7381 KeygenSubcommands :: Onchain ( onchain) => {
74- onchain_split ( onchain, global_config, keys. sk . clone ( ) )
82+ onchain_split ( onchain, global_config, keys. iter ( ) . map ( |k| & k . sk ) )
7583 }
7684 } ?;
7785 info ! ( "Successfully split validator key into shares" ) ;
7886
7987 // 4) Encrypt the keyshares with the operators public keys
8088 info ! ( "Encrypting keyshares..." ) ;
81- let encrypted_keyshares = encrypt_keyshares ( keyshares) ?;
89+ let encrypted_keyshares = splits
90+ . into_par_iter ( )
91+ . map ( encrypt_keyshares)
92+ . collect :: < Result < Vec < _ > , _ > > ( ) ?;
8293 info ! ( "Encrypted all keyshares!" ) ;
8394
8495 // 5) Construct the payload and turn data into proper output format.
8596 info ! (
8697 "Constructing output and writing to file {}..." ,
8798 shared. output_path
8899 ) ;
89- let output = OutputData :: new ( encrypted_keyshares, shared. clone ( ) , keys, nonce ) ;
100+ let output = OutputData :: new ( encrypted_keyshares, & shared, keys) ? ;
90101
91102 // 6) Write output data to file
92103 let json_data = serde_json:: to_string_pretty ( & output) . map_err ( |e| {
0 commit comments