Wrap ed25519_dalek::Keypair (#8247)

This commit is contained in:
Greg Fitzgerald 2020-02-12 14:15:12 -07:00 committed by GitHub
parent ecb055a252
commit 127553ce4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 63 additions and 60 deletions

View File

@ -1,6 +1,5 @@
use crate::result::ArchiverError; use crate::result::ArchiverError;
use crossbeam_channel::unbounded; use crossbeam_channel::unbounded;
use ed25519_dalek;
use rand::{thread_rng, Rng, SeedableRng}; use rand::{thread_rng, Rng, SeedableRng};
use rand_chacha::ChaChaRng; use rand_chacha::ChaChaRng;
use solana_archiver_utils::sample_file; use solana_archiver_utils::sample_file;
@ -88,11 +87,11 @@ struct ArchiverMeta {
} }
fn get_slot_from_signature( fn get_slot_from_signature(
signature: &ed25519_dalek::Signature, signature: &Signature,
storage_turn: u64, storage_turn: u64,
slots_per_segment: u64, slots_per_segment: u64,
) -> u64 { ) -> u64 {
let signature_vec = signature.to_bytes(); let signature_vec = signature.as_ref();
let mut segment_index = u64::from(signature_vec[0]) let mut segment_index = u64::from(signature_vec[0])
| (u64::from(signature_vec[1]) << 8) | (u64::from(signature_vec[1]) << 8)
| (u64::from(signature_vec[1]) << 16) | (u64::from(signature_vec[1]) << 16)
@ -438,13 +437,13 @@ impl Archiver {
return Err(e); 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); let slot = get_slot_from_signature(&signature, segment_slot, slots_per_segment);
info!("replicating slot: {}", slot); info!("replicating slot: {}", slot);
slot_sender.send(slot)?; slot_sender.send(slot)?;
meta.slot = slot; meta.slot = slot;
meta.slots_per_segment = slots_per_segment; meta.slots_per_segment = slots_per_segment;
meta.signature = Signature::new(&signature.to_bytes()); meta.signature = signature;
meta.blockhash = segment_blockhash; meta.blockhash = segment_blockhash;
let mut repair_slot_range = RepairSlotRange::default(); let mut repair_slot_range = RepairSlotRange::default();

View File

@ -1,7 +1,7 @@
use clap::{crate_description, crate_name, value_t, App, Arg, ArgMatches}; use clap::{crate_description, crate_name, value_t, App, Arg, ArgMatches};
use solana_core::gen_keys::GenKeys; use solana_core::gen_keys::GenKeys;
use solana_faucet::faucet::FAUCET_PORT; 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::net::SocketAddr;
use std::process::exit; use std::process::exit;
use std::time::Duration; use std::time::Duration;

View File

@ -1,7 +1,7 @@
use clap::{crate_description, crate_name, App, Arg, ArgMatches}; use clap::{crate_description, crate_name, App, Arg, ArgMatches};
use solana_faucet::faucet::FAUCET_PORT; use solana_faucet::faucet::FAUCET_PORT;
use solana_sdk::fee_calculator::FeeCalculator; 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}; use std::{net::SocketAddr, process::exit, time::Duration};
const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::LAMPORTS_PER_SOL; const NUM_LAMPORTS_PER_ACCOUNT_DEFAULT: u64 = solana_sdk::native_token::LAMPORTS_PER_SOL;

View File

@ -118,7 +118,7 @@ mod tests {
use solana_ledger::entry::create_ticks; use solana_ledger::entry::create_ticks;
use solana_ledger::get_tmp_ledger_path; use solana_ledger::get_tmp_ledger_path;
use solana_sdk::clock::DEFAULT_SLOTS_PER_SEGMENT; 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::fs::{remove_dir_all, remove_file};
use std::path::Path; use std::path::Path;

View File

@ -2,12 +2,9 @@ use crate::ArgConstant;
use bip39::{Language, Mnemonic, Seed}; use bip39::{Language, Mnemonic, Seed};
use clap::values_t; use clap::values_t;
use rpassword::prompt_password_stderr; use rpassword::prompt_password_stderr;
use solana_sdk::{ use solana_sdk::signature::{
pubkey::Pubkey, keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair,
signature::{ KeypairUtil,
keypair_from_seed, keypair_from_seed_phrase_and_passphrase, read_keypair_file, Keypair,
KeypairUtil,
},
}; };
use std::{ use std::{
error, error,
@ -87,7 +84,7 @@ pub fn keypair_from_seed_phrase(
}; };
if confirm_pubkey { if confirm_pubkey {
let pubkey = Pubkey::new(keypair.public.as_ref()); let pubkey = keypair.pubkey();
print!("Recovered pubkey `{:?}`. Continue? (y/n): ", pubkey); print!("Recovered pubkey `{:?}`. Continue? (y/n): ", pubkey);
let _ignored = stdout().flush(); let _ignored = stdout().flush();
let mut input = String::new(); let mut input = String::new();

View File

@ -1912,10 +1912,6 @@ impl FaucetKeypair {
} }
impl KeypairUtil for FaucetKeypair { impl KeypairUtil for FaucetKeypair {
fn new() -> Self {
unimplemented!();
}
/// Return the public key of the keypair used to sign votes /// Return the public key of the keypair used to sign votes
fn pubkey(&self) -> Pubkey { fn pubkey(&self) -> Pubkey {
self.transaction.message().account_keys[0] self.transaction.message().account_keys[0]

View File

@ -1129,9 +1129,7 @@ mod tests {
use serde_json::Number; use serde_json::Number;
use solana_logger; use solana_logger;
use solana_sdk::{ use solana_sdk::{
instruction::InstructionError, instruction::InstructionError, signature::Keypair, system_transaction,
signature::{Keypair, KeypairUtil},
system_transaction,
transaction::TransactionError, transaction::TransactionError,
}; };
use std::{sync::mpsc::channel, thread}; use std::{sync::mpsc::channel, thread};

View File

@ -39,7 +39,7 @@ use solana_perf::packet::{to_packets_with_destination, Packets, PacketsRecycler}
use solana_sdk::{ use solana_sdk::{
clock::{Slot, DEFAULT_MS_PER_SLOT}, clock::{Slot, DEFAULT_MS_PER_SLOT},
pubkey::Pubkey, pubkey::Pubkey,
signature::{Keypair, KeypairUtil, Signable, Signature}, signature::{Keypair, Signable, Signature},
timing::{duration_as_ms, timestamp}, timing::{duration_as_ms, timestamp},
transaction::Transaction, transaction::Transaction,
}; };

View File

@ -376,7 +376,7 @@ impl StorageStage {
total_proofs: usize, total_proofs: usize,
) -> Result<()> { ) -> Result<()> {
let mut seed = [0u8; 32]; 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( let ix = storage_instruction::advertise_recent_blockhash(
&storage_keypair.pubkey(), &storage_keypair.pubkey(),
@ -385,7 +385,7 @@ impl StorageStage {
); );
instruction_sender.send(ix)?; 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); let mut rng = ChaChaRng::from_seed(seed);
@ -406,7 +406,7 @@ impl StorageStage {
return Ok(()); return Ok(());
} }
// TODO: what if the validator does not have this segment // 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!( debug!(
"storage verifying: segment: {} identities: {}", "storage verifying: segment: {} identities: {}",

View File

@ -1,9 +1,5 @@
use solana_sdk::{ use solana_sdk::{
hash::Hash, hash::Hash, pubkey::Pubkey, signature::Keypair, system_transaction, transaction::Transaction,
pubkey::Pubkey,
signature::{Keypair, KeypairUtil},
system_transaction,
transaction::Transaction,
}; };
use std::{ use std::{
io::{Error, ErrorKind}, io::{Error, ErrorKind},

View File

@ -21,7 +21,7 @@ use solana_sdk::{
pubkey::{write_pubkey_file, Pubkey}, pubkey::{write_pubkey_file, Pubkey},
signature::{ signature::{
keypair_from_seed, read_keypair, read_keypair_file, write_keypair, write_keypair_file, keypair_from_seed, read_keypair, read_keypair_file, write_keypair, write_keypair_file,
Keypair, KeypairUtil, Signature, Keypair, KeypairUtil,
}, },
}; };
use std::{ use std::{
@ -613,7 +613,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
("verify", Some(matches)) => { ("verify", Some(matches)) => {
let keypair = get_keypair_from_matches(matches, config)?; let keypair = get_keypair_from_matches(matches, config)?;
let test_data = b"test"; 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 = matches.value_of("pubkey").unwrap();
let pubkey = bs58::decode(pubkey_bs58).into_vec().unwrap(); let pubkey = bs58::decode(pubkey_bs58).into_vec().unwrap();
if signature.verify(&pubkey, test_data) { if signature.verify(&pubkey, test_data) {

View File

@ -23,7 +23,7 @@ use solana_sdk::{
clock::{Slot, MAX_RECENT_BLOCKHASHES}, clock::{Slot, MAX_RECENT_BLOCKHASHES},
genesis_config::GenesisConfig, genesis_config::GenesisConfig,
hash::Hash, hash::Hash,
signature::{Keypair, KeypairUtil}, signature::Keypair,
timing::duration_as_ms, timing::duration_as_ms,
transaction::{Result, Transaction, TransactionError}, transaction::{Result, Transaction, TransactionError},
}; };

View File

@ -265,7 +265,7 @@ mod tests {
EpochSchedule, DEFAULT_LEADER_SCHEDULE_SLOT_OFFSET, DEFAULT_SLOTS_PER_EPOCH, EpochSchedule, DEFAULT_LEADER_SCHEDULE_SLOT_OFFSET, DEFAULT_SLOTS_PER_EPOCH,
MINIMUM_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}; use std::{sync::mpsc::channel, sync::Arc, thread::Builder};
#[test] #[test]

View File

@ -301,9 +301,9 @@ fn sign_shred_cpu(keypair: &Keypair, packet: &mut Packet) {
packet.meta.size >= msg_end, packet.meta.size >= msg_end,
"packet is not large enough for a signature" "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); 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]) { 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<u8> { pub fn sign_shreds_gpu_pinned_keypair(keypair: &Keypair, cache: &RecyclerCache) -> PinnedVec<u8> {
let mut vec = cache.buffer().allocate("pinned_keypair"); let mut vec = cache.buffer().allocate("pinned_keypair");
let pubkey = keypair.pubkey().to_bytes(); let pubkey = keypair.pubkey().to_bytes();
let secret = keypair.secret.to_bytes(); let secret = keypair.secret().to_bytes();
let mut hasher = Sha512::default(); let mut hasher = Sha512::default();
hasher.input(&secret); hasher.input(&secret);
let mut result = hasher.result(); let mut result = hasher.result();

View File

@ -57,11 +57,7 @@ impl<'a, 'b> Drop for TransactionBatch<'a, 'b> {
mod tests { mod tests {
use super::*; use super::*;
use crate::genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo}; use crate::genesis_utils::{create_genesis_config_with_leader, GenesisConfigInfo};
use solana_sdk::{ use solana_sdk::{pubkey::Pubkey, signature::Keypair, system_transaction};
pubkey::Pubkey,
signature::{Keypair, KeypairUtil},
system_transaction,
};
#[test] #[test]
fn test_transaction_batch() { fn test_transaction_batch() {

View File

@ -5,7 +5,7 @@ use bs58;
use ed25519_dalek; use ed25519_dalek;
use generic_array::{typenum::U64, GenericArray}; use generic_array::{typenum::U64, GenericArray};
use hmac::Hmac; use hmac::Hmac;
use rand::rngs::OsRng; use rand::{rngs::OsRng, CryptoRng, RngCore};
use serde_json; use serde_json;
use std::{ use std::{
borrow::{Borrow, Cow}, borrow::{Borrow, Cow},
@ -17,7 +17,35 @@ use std::{
str::FromStr, str::FromStr,
}; };
pub type Keypair = ed25519_dalek::Keypair; #[derive(Debug, Default)]
pub struct Keypair(ed25519_dalek::Keypair);
impl Keypair {
pub fn generate<R>(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<Self, ed25519_dalek::SignatureError> {
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)] #[repr(transparent)]
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
@ -103,33 +131,26 @@ impl FromStr for Signature {
} }
pub trait KeypairUtil { pub trait KeypairUtil {
fn new() -> Self;
fn pubkey(&self) -> Pubkey; fn pubkey(&self) -> Pubkey;
fn sign_message(&self, message: &[u8]) -> Signature; fn sign_message(&self, message: &[u8]) -> Signature;
} }
impl KeypairUtil for Keypair { 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 /// Return the public key for the given keypair
fn pubkey(&self) -> Pubkey { fn pubkey(&self) -> Pubkey {
Pubkey::new(self.public.as_ref()) Pubkey::new(self.0.public.as_ref())
} }
fn sign_message(&self, message: &[u8]) -> Signature { 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<R: Read>(reader: &mut R) -> Result<Keypair, Box<dyn error::Error>> { pub fn read_keypair<R: Read>(reader: &mut R) -> Result<Keypair, Box<dyn error::Error>> {
let bytes: Vec<u8> = serde_json::from_reader(reader)?; let bytes: Vec<u8> = 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()))?; .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<Keypair, Box<dyn error::Error>> { pub fn read_keypair_file(path: &str) -> Result<Keypair, Box<dyn error::Error>> {
@ -142,7 +163,7 @@ pub fn write_keypair<W: Write>(
keypair: &Keypair, keypair: &Keypair,
writer: &mut W, writer: &mut W,
) -> Result<String, Box<dyn error::Error>> { ) -> Result<String, Box<dyn error::Error>> {
let keypair_bytes = keypair.to_bytes(); let keypair_bytes = keypair.0.to_bytes();
let serialized = serde_json::to_string(&keypair_bytes.to_vec())?; let serialized = serde_json::to_string(&keypair_bytes.to_vec())?;
writer.write_all(&serialized.clone().into_bytes())?; writer.write_all(&serialized.clone().into_bytes())?;
Ok(serialized) Ok(serialized)
@ -183,8 +204,8 @@ pub fn keypair_from_seed(seed: &[u8]) -> Result<Keypair, Box<dyn error::Error>>
let secret = ed25519_dalek::SecretKey::from_bytes(&seed[..ed25519_dalek::SECRET_KEY_LENGTH]) let secret = ed25519_dalek::SecretKey::from_bytes(&seed[..ed25519_dalek::SECRET_KEY_LENGTH])
.map_err(|e| e.to_string())?; .map_err(|e| e.to_string())?;
let public = ed25519_dalek::PublicKey::from(&secret); let public = ed25519_dalek::PublicKey::from(&secret);
let keypair = Keypair { secret, public }; let dalek_keypair = ed25519_dalek::Keypair { secret, public };
Ok(keypair) Ok(Keypair(dalek_keypair))
} }
pub fn keypair_from_seed_phrase_and_passphrase( pub fn keypair_from_seed_phrase_and_passphrase(
@ -228,7 +249,7 @@ mod tests {
assert!(Path::new(&outfile).exists()); assert!(Path::new(&outfile).exists());
assert_eq!( assert_eq!(
keypair_vec, keypair_vec,
read_keypair_file(&outfile).unwrap().to_bytes().to_vec() read_keypair_file(&outfile).unwrap().0.to_bytes().to_vec()
); );
#[cfg(unix)] #[cfg(unix)]