diff --git a/archiver-lib/src/archiver.rs b/archiver-lib/src/archiver.rs index 39fb3289b..ba4f2109f 100644 --- a/archiver-lib/src/archiver.rs +++ b/archiver-lib/src/archiver.rs @@ -1,6 +1,5 @@ use crate::result::ArchiverError; use crossbeam_channel::unbounded; -use ed25519_dalek; use rand::{thread_rng, Rng, SeedableRng}; use rand_chacha::ChaChaRng; use solana_archiver_utils::sample_file; @@ -88,11 +87,11 @@ struct ArchiverMeta { } fn get_slot_from_signature( - signature: &ed25519_dalek::Signature, + signature: &Signature, storage_turn: u64, slots_per_segment: u64, ) -> u64 { - let signature_vec = signature.to_bytes(); + let signature_vec = signature.as_ref(); let mut segment_index = u64::from(signature_vec[0]) | (u64::from(signature_vec[1]) << 8) | (u64::from(signature_vec[1]) << 16) @@ -438,13 +437,13 @@ impl Archiver { return Err(e); } }; - let signature = storage_keypair.sign(segment_blockhash.as_ref()); + let signature = storage_keypair.sign_message(segment_blockhash.as_ref()); let slot = get_slot_from_signature(&signature, segment_slot, slots_per_segment); info!("replicating slot: {}", slot); slot_sender.send(slot)?; meta.slot = slot; meta.slots_per_segment = slots_per_segment; - meta.signature = Signature::new(&signature.to_bytes()); + meta.signature = signature; meta.blockhash = segment_blockhash; let mut repair_slot_range = RepairSlotRange::default(); diff --git a/bench-exchange/src/cli.rs b/bench-exchange/src/cli.rs index 1c9537912..3f115d65f 100644 --- a/bench-exchange/src/cli.rs +++ b/bench-exchange/src/cli.rs @@ -1,7 +1,7 @@ use clap::{crate_description, crate_name, value_t, App, Arg, ArgMatches}; use solana_core::gen_keys::GenKeys; use solana_faucet::faucet::FAUCET_PORT; -use solana_sdk::signature::{read_keypair_file, Keypair, KeypairUtil}; +use solana_sdk::signature::{read_keypair_file, Keypair}; use std::net::SocketAddr; use std::process::exit; use std::time::Duration; diff --git a/bench-tps/src/cli.rs b/bench-tps/src/cli.rs index 01d19fea9..609eacf94 100644 --- a/bench-tps/src/cli.rs +++ b/bench-tps/src/cli.rs @@ -1,7 +1,7 @@ use clap::{crate_description, crate_name, App, Arg, ArgMatches}; use solana_faucet::faucet::FAUCET_PORT; use solana_sdk::fee_calculator::FeeCalculator; -use solana_sdk::signature::{read_keypair_file, Keypair, KeypairUtil}; +use solana_sdk::signature::{read_keypair_file, Keypair}; use std::{net::SocketAddr, process::exit, time::Duration}; const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::LAMPORTS_PER_SOL; diff --git a/chacha-cuda/src/chacha_cuda.rs b/chacha-cuda/src/chacha_cuda.rs index b49c9228e..301c85230 100644 --- a/chacha-cuda/src/chacha_cuda.rs +++ b/chacha-cuda/src/chacha_cuda.rs @@ -118,7 +118,7 @@ mod tests { use solana_ledger::entry::create_ticks; use solana_ledger::get_tmp_ledger_path; use solana_sdk::clock::DEFAULT_SLOTS_PER_SEGMENT; - use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_sdk::signature::Keypair; use std::fs::{remove_dir_all, remove_file}; use std::path::Path; diff --git a/clap-utils/src/keypair.rs b/clap-utils/src/keypair.rs index 34cf248fe..ee802d59d 100644 --- a/clap-utils/src/keypair.rs +++ b/clap-utils/src/keypair.rs @@ -2,12 +2,9 @@ use crate::ArgConstant; use bip39::{Language, Mnemonic, Seed}; use clap::values_t; use rpassword::prompt_password_stderr; -use solana_sdk::{ - pubkey::Pubkey, - signature::{ - keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair, - KeypairUtil, - }, +use solana_sdk::signature::{ + keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair, + KeypairUtil, }; use std::{ error, @@ -87,7 +84,7 @@ pub fn keypair_from_seed_phrase( }; if confirm_pubkey { - let pubkey = Pubkey::new(keypair.public.as_ref()); + let pubkey = keypair.pubkey(); print!("Recovered pubkey `{:?}`. Continue? (y/n): ", pubkey); let _ignored = stdout().flush(); let mut input = String::new(); diff --git a/cli/src/cli.rs b/cli/src/cli.rs index 66e58192b..5039ffb55 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -1912,10 +1912,6 @@ impl FaucetKeypair { } impl KeypairUtil for FaucetKeypair { - fn new() -> Self { - unimplemented!(); - } - /// Return the public key of the keypair used to sign votes fn pubkey(&self) -> Pubkey { self.transaction.message().account_keys[0] diff --git a/client/src/rpc_client.rs b/client/src/rpc_client.rs index 98080069f..936b365a4 100644 --- a/client/src/rpc_client.rs +++ b/client/src/rpc_client.rs @@ -1129,9 +1129,7 @@ mod tests { use serde_json::Number; use solana_logger; use solana_sdk::{ - instruction::InstructionError, - signature::{Keypair, KeypairUtil}, - system_transaction, + instruction::InstructionError, signature::Keypair, system_transaction, transaction::TransactionError, }; use std::{sync::mpsc::channel, thread}; diff --git a/core/src/cluster_info.rs b/core/src/cluster_info.rs index c40339d66..ee5e1ecd4 100644 --- a/core/src/cluster_info.rs +++ b/core/src/cluster_info.rs @@ -39,7 +39,7 @@ use solana_perf::packet::{to_packets_with_destination, Packets, PacketsRecycler} use solana_sdk::{ clock::{Slot, DEFAULT_MS_PER_SLOT}, pubkey::Pubkey, - signature::{Keypair, KeypairUtil, Signable, Signature}, + signature::{Keypair, Signable, Signature}, timing::{duration_as_ms, timestamp}, transaction::Transaction, }; diff --git a/core/src/storage_stage.rs b/core/src/storage_stage.rs index 85c5f44c5..81f86871f 100644 --- a/core/src/storage_stage.rs +++ b/core/src/storage_stage.rs @@ -376,7 +376,7 @@ impl StorageStage { total_proofs: usize, ) -> Result<()> { let mut seed = [0u8; 32]; - let signature = storage_keypair.sign(&blockhash.as_ref()); + let signature = storage_keypair.sign_message(&blockhash.as_ref()); let ix = storage_instruction::advertise_recent_blockhash( &storage_keypair.pubkey(), @@ -385,7 +385,7 @@ impl StorageStage { ); instruction_sender.send(ix)?; - seed.copy_from_slice(&signature.to_bytes()[..32]); + seed.copy_from_slice(&signature.as_ref()[..32]); let mut rng = ChaChaRng::from_seed(seed); @@ -406,7 +406,7 @@ impl StorageStage { return Ok(()); } // TODO: what if the validator does not have this segment - let segment = signature.to_bytes()[0] as usize % num_segments; + let segment = signature.as_ref()[0] as usize % num_segments; debug!( "storage verifying: segment: {} identities: {}", diff --git a/faucet/src/faucet_mock.rs b/faucet/src/faucet_mock.rs index 1815b3c39..81760338e 100644 --- a/faucet/src/faucet_mock.rs +++ b/faucet/src/faucet_mock.rs @@ -1,9 +1,5 @@ use solana_sdk::{ - hash::Hash, - pubkey::Pubkey, - signature::{Keypair, KeypairUtil}, - system_transaction, - transaction::Transaction, + hash::Hash, pubkey::Pubkey, signature::Keypair, system_transaction, transaction::Transaction, }; use std::{ io::{Error, ErrorKind}, diff --git a/keygen/src/keygen.rs b/keygen/src/keygen.rs index 8aafc9ea5..499861572 100644 --- a/keygen/src/keygen.rs +++ b/keygen/src/keygen.rs @@ -21,7 +21,7 @@ use solana_sdk::{ pubkey::{write_pubkey_file, Pubkey}, signature::{ keypair_from_seed, read_keypair, read_keypair_file, write_keypair, write_keypair_file, - Keypair, KeypairUtil, Signature, + Keypair, KeypairUtil, }, }; use std::{ @@ -613,7 +613,7 @@ fn main() -> Result<(), Box> { ("verify", Some(matches)) => { let keypair = get_keypair_from_matches(matches, config)?; let test_data = b"test"; - let signature = Signature::new(&keypair.sign(test_data).to_bytes()); + let signature = keypair.sign_message(test_data); let pubkey_bs58 = matches.value_of("pubkey").unwrap(); let pubkey = bs58::decode(pubkey_bs58).into_vec().unwrap(); if signature.verify(&pubkey, test_data) { diff --git a/ledger/src/blockstore_processor.rs b/ledger/src/blockstore_processor.rs index 12e071b46..b90ce33f6 100644 --- a/ledger/src/blockstore_processor.rs +++ b/ledger/src/blockstore_processor.rs @@ -23,7 +23,7 @@ use solana_sdk::{ clock::{Slot, MAX_RECENT_BLOCKHASHES}, genesis_config::GenesisConfig, hash::Hash, - signature::{Keypair, KeypairUtil}, + signature::Keypair, timing::duration_as_ms, transaction::{Result, Transaction, TransactionError}, }; diff --git a/ledger/src/leader_schedule_cache.rs b/ledger/src/leader_schedule_cache.rs index 1bcfa54b3..fd5bff6ed 100644 --- a/ledger/src/leader_schedule_cache.rs +++ b/ledger/src/leader_schedule_cache.rs @@ -265,7 +265,7 @@ mod tests { EpochSchedule, DEFAULT_LEADER_SCHEDULE_SLOT_OFFSET, DEFAULT_SLOTS_PER_EPOCH, MINIMUM_SLOTS_PER_EPOCH, }; - use solana_sdk::signature::{Keypair, KeypairUtil}; + use solana_sdk::signature::Keypair; use std::{sync::mpsc::channel, sync::Arc, thread::Builder}; #[test] diff --git a/ledger/src/sigverify_shreds.rs b/ledger/src/sigverify_shreds.rs index 1eec929cd..69781a4a9 100644 --- a/ledger/src/sigverify_shreds.rs +++ b/ledger/src/sigverify_shreds.rs @@ -301,9 +301,9 @@ fn sign_shred_cpu(keypair: &Keypair, packet: &mut Packet) { packet.meta.size >= msg_end, "packet is not large enough for a signature" ); - let signature = keypair.sign(&packet.data[msg_start..msg_end]); + let signature = keypair.sign_message(&packet.data[msg_start..msg_end]); trace!("signature {:?}", signature); - packet.data[0..sig_end].copy_from_slice(&signature.to_bytes()); + packet.data[0..sig_end].copy_from_slice(&signature.as_ref()); } pub fn sign_shreds_cpu(keypair: &Keypair, batches: &mut [Packets]) { @@ -323,7 +323,7 @@ pub fn sign_shreds_cpu(keypair: &Keypair, batches: &mut [Packets]) { pub fn sign_shreds_gpu_pinned_keypair(keypair: &Keypair, cache: &RecyclerCache) -> PinnedVec { let mut vec = cache.buffer().allocate("pinned_keypair"); let pubkey = keypair.pubkey().to_bytes(); - let secret = keypair.secret.to_bytes(); + let secret = keypair.secret().to_bytes(); let mut hasher = Sha512::default(); hasher.input(&secret); let mut result = hasher.result(); diff --git a/runtime/src/transaction_batch.rs b/runtime/src/transaction_batch.rs index 365bc83eb..61c9fda2b 100644 --- a/runtime/src/transaction_batch.rs +++ b/runtime/src/transaction_batch.rs @@ -57,11 +57,7 @@ impl<'a, 'b> Drop for TransactionBatch<'a, 'b> { mod tests { use super::*; use crate::genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo}; - use solana_sdk::{ - pubkey::Pubkey, - signature::{Keypair, KeypairUtil}, - system_transaction, - }; + use solana_sdk::{pubkey::Pubkey, signature::Keypair, system_transaction}; #[test] fn test_transaction_batch() { diff --git a/sdk/src/signature.rs b/sdk/src/signature.rs index 4f92787dd..eb620ed9d 100644 --- a/sdk/src/signature.rs +++ b/sdk/src/signature.rs @@ -5,7 +5,7 @@ use bs58; use ed25519_dalek; use generic_array::{typenum::U64, GenericArray}; use hmac::Hmac; -use rand::rngs::OsRng; +use rand::{rngs::OsRng, CryptoRng, RngCore}; use serde_json; use std::{ borrow::{Borrow, Cow}, @@ -17,7 +17,35 @@ use std::{ str::FromStr, }; -pub type Keypair = ed25519_dalek::Keypair; +#[derive(Debug, Default)] +pub struct Keypair(ed25519_dalek::Keypair); + +impl Keypair { + pub fn generate(csprng: &mut R) -> Self + where + R: CryptoRng + RngCore, + { + Self(ed25519_dalek::Keypair::generate(csprng)) + } + + /// Return a new ED25519 keypair + pub fn new() -> Self { + let mut rng = OsRng::new().unwrap(); + Self::generate(&mut rng) + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + ed25519_dalek::Keypair::from_bytes(bytes).map(Self) + } + + pub fn to_bytes(&self) -> [u8; 64] { + self.0.to_bytes() + } + + pub fn secret(&self) -> &ed25519_dalek::SecretKey { + &self.0.secret + } +} #[repr(transparent)] #[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] @@ -103,33 +131,26 @@ impl FromStr for Signature { } pub trait KeypairUtil { - fn new() -> Self; fn pubkey(&self) -> Pubkey; fn sign_message(&self, message: &[u8]) -> Signature; } impl KeypairUtil for Keypair { - /// Return a new ED25519 keypair - fn new() -> Self { - let mut rng = OsRng::new().unwrap(); - Keypair::generate(&mut rng) - } - /// Return the public key for the given keypair fn pubkey(&self) -> Pubkey { - Pubkey::new(self.public.as_ref()) + Pubkey::new(self.0.public.as_ref()) } fn sign_message(&self, message: &[u8]) -> Signature { - Signature::new(&self.sign(message).to_bytes()) + Signature::new(&self.0.sign(message).to_bytes()) } } pub fn read_keypair(reader: &mut R) -> Result> { let bytes: Vec = serde_json::from_reader(reader)?; - let keypair = Keypair::from_bytes(&bytes) + let dalek_keypair = ed25519_dalek::Keypair::from_bytes(&bytes) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?; - Ok(keypair) + Ok(Keypair(dalek_keypair)) } pub fn read_keypair_file(path: &str) -> Result> { @@ -142,7 +163,7 @@ pub fn write_keypair( keypair: &Keypair, writer: &mut W, ) -> Result> { - let keypair_bytes = keypair.to_bytes(); + let keypair_bytes = keypair.0.to_bytes(); let serialized = serde_json::to_string(&keypair_bytes.to_vec())?; writer.write_all(&serialized.clone().into_bytes())?; Ok(serialized) @@ -183,8 +204,8 @@ pub fn keypair_from_seed(seed: &[u8]) -> Result> let secret = ed25519_dalek::SecretKey::from_bytes(&seed[..ed25519_dalek::SECRET_KEY_LENGTH]) .map_err(|e| e.to_string())?; let public = ed25519_dalek::PublicKey::from(&secret); - let keypair = Keypair { secret, public }; - Ok(keypair) + let dalek_keypair = ed25519_dalek::Keypair { secret, public }; + Ok(Keypair(dalek_keypair)) } pub fn keypair_from_seed_phrase_and_passphrase( @@ -228,7 +249,7 @@ mod tests { assert!(Path::new(&outfile).exists()); assert_eq!( keypair_vec, - read_keypair_file(&outfile).unwrap().to_bytes().to_vec() + read_keypair_file(&outfile).unwrap().0.to_bytes().to_vec() ); #[cfg(unix)]