Migrate from ring to ed25519-dalek

Why?

* Pure Rust, no BoringSSL (or OpenSSL) dependency
* Those avx2 benchmarks
* ring includes far more than what we need
* ring author won't add release tags: https://github.com/briansmith/ring#versioning--stability
This commit is contained in:
Greg Fitzgerald 2018-10-22 21:18:53 -06:00
parent bec34496f1
commit 7c610b216b
13 changed files with 58 additions and 83 deletions

View File

@ -75,6 +75,7 @@ bytes = "0.4"
chrono = { version = "0.4.0", features = ["serde"] }
clap = "2.31"
dirs = "1.0.2"
ed25519-dalek = "1.0.0-pre.0"
elf = "0.0.10"
env_logger = "0.5.12"
generic-array = { version = "0.12.0", default-features = false, features = ["serde"] }
@ -97,7 +98,6 @@ pnet_datalink = "0.21.0"
rand = "0.5.1"
rayon = "1.0.0"
reqwest = "0.9.0"
ring = "0.13.2"
sha2 = "0.8.0"
serde = "1.0.27"
serde_cbor = "0.9.0"
@ -108,7 +108,6 @@ solana-sdk = { path = "sdk", version = "0.11.0" }
sys-info = "0.5.6"
tokio = "0.1"
tokio-codec = "0.1"
untrusted = "0.6.2"
solana-bpfloader = { path = "programs/native/bpf_loader", version = "0.11.0" }
solana-erc20 = { path = "programs/native/erc20", version = "0.11.0" }
solana-lualoader = { path = "programs/native/lua_loader", version = "0.11.0" }

View File

@ -643,7 +643,7 @@ fn main() {
let mut barrier_client = mk_client(&leader);
let mut seed = [0u8; 32];
seed.copy_from_slice(&id.public_key_bytes()[..32]);
seed.copy_from_slice(&id.to_bytes()[..32]);
let mut rnd = GenKeys::new(seed);
println!("Creating {} keypairs...", tx_count * 2);

View File

@ -5,7 +5,6 @@ extern crate atty;
extern crate clap;
extern crate serde_json;
extern crate solana;
extern crate untrusted;
use clap::{App, Arg};
use solana::fullnode::Config;

View File

@ -1,7 +1,6 @@
#[macro_use]
extern crate clap;
extern crate dirs;
extern crate ring;
extern crate serde_json;
extern crate solana;

View File

@ -610,15 +610,14 @@ mod test {
tx.userdata(0).to_vec(),
vec![
0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 50, 48, 49, 54, 45,
48, 55, 45, 48, 56, 84, 48, 57, 58, 49, 48, 58, 49, 49, 90, 32, 253, 186, 201, 177,
11, 117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76,
16, 252, 180, 72, 134, 137, 247, 161, 68, 192, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 5,
6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 6, 5, 4, 1, 1, 1, 1,
0, 0, 0, 32, 253, 186, 201, 177, 11, 117, 135, 187, 167, 181, 188, 22, 59, 206,
105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161, 68, 192,
0, 0, 0, 0, 0, 0, 0, 32, 253, 186, 201, 177, 11, 117, 135, 187, 167, 181, 188, 22,
59, 206, 105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161,
68
48, 55, 45, 48, 56, 84, 48, 57, 58, 49, 48, 58, 49, 49, 90, 218, 65, 89, 124, 81,
87, 72, 141, 119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21, 24, 161,
28, 195, 135, 182, 105, 178, 238, 101, 134, 192, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4,
5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 6, 5, 4, 1, 1, 1,
1, 0, 0, 0, 218, 65, 89, 124, 81, 87, 72, 141, 119, 36, 224, 63, 184, 216, 74, 55,
106, 67, 184, 244, 21, 24, 161, 28, 195, 135, 182, 105, 178, 238, 101, 134, 192, 0,
0, 0, 0, 0, 0, 0, 218, 65, 89, 124, 81, 87, 72, 141, 119, 36, 224, 63, 184, 216,
74, 55, 106, 67, 184, 244, 21, 24, 161, 28, 195, 135, 182, 105, 178, 238, 101, 134
]
);

View File

@ -18,7 +18,6 @@ use std::sync::{Arc, RwLock};
use std::thread::Result;
use tpu::{Tpu, TpuReturnType};
use tvu::{Tvu, TvuReturnType};
use untrusted::Input;
use window::{new_window, SharedWindow};
pub enum NodeRole {
@ -113,15 +112,13 @@ pub struct Config {
impl Config {
pub fn new(bind_addr: &SocketAddr, pkcs8: Vec<u8>) -> Self {
let keypair =
Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in fullnode::Config new");
let keypair = Keypair::from_bytes(&pkcs8).expect("from_pkcs8 in fullnode::Config new");
let pubkey = keypair.pubkey();
let node_info = NodeInfo::new_with_pubkey_socketaddr(pubkey, bind_addr);
Config { node_info, pkcs8 }
}
pub fn keypair(&self) -> Keypair {
Keypair::from_pkcs8(Input::from(&self.pkcs8))
.expect("from_pkcs8 in fullnode::Config keypair")
Keypair::from_bytes(&self.pkcs8).expect("from_pkcs8 in fullnode::Config keypair")
}
}

View File

@ -87,6 +87,7 @@ extern crate bytes;
extern crate chrono;
extern crate clap;
extern crate dirs;
extern crate ed25519_dalek;
extern crate elf;
extern crate generic_array;
#[cfg(test)]
@ -103,7 +104,6 @@ extern crate nix;
extern crate pnet_datalink;
extern crate rayon;
extern crate reqwest;
extern crate ring;
extern crate serde;
#[macro_use]
extern crate serde_derive;
@ -122,7 +122,6 @@ extern crate solana_sdk;
extern crate sys_info;
extern crate tokio;
extern crate tokio_codec;
extern crate untrusted;
#[cfg(test)]
#[macro_use]

View File

@ -2,12 +2,10 @@
use entry::Entry;
use hash::{hash, Hash};
use ring::rand::SystemRandom;
use signature::{Keypair, KeypairUtil};
use solana_sdk::pubkey::Pubkey;
use system_transaction::SystemTransaction;
use transaction::Transaction;
use untrusted::Input;
#[derive(Serialize, Deserialize, Debug)]
pub struct Mint {
@ -25,8 +23,7 @@ impl Mint {
bootstrap_leader_id: Pubkey,
bootstrap_leader_tokens: u64,
) -> Self {
let keypair =
Keypair::from_pkcs8(Input::from(&pkcs8)).expect("from_pkcs8 in mint pub fn new");
let keypair = Keypair::from_bytes(&pkcs8).expect("from_pkcs8 in mint pub fn new");
let pubkey = keypair.pubkey();
Mint {
pkcs8,
@ -42,19 +39,12 @@ impl Mint {
bootstrap_leader: Pubkey,
bootstrap_leader_tokens: u64,
) -> Self {
let rnd = SystemRandom::new();
let pkcs8 = Keypair::generate_pkcs8(&rnd)
.expect("generate_pkcs8 in mint pub fn new")
.to_vec();
let pkcs8 = Keypair::new().to_bytes().to_vec();
Self::new_with_pkcs8(tokens, pkcs8, bootstrap_leader, bootstrap_leader_tokens)
}
pub fn new(tokens: u64) -> Self {
let rnd = SystemRandom::new();
let pkcs8 = Keypair::generate_pkcs8(&rnd)
.expect("generate_pkcs8 in mint pub fn new")
.to_vec();
Self::new_with_pkcs8(tokens, pkcs8, Pubkey::default(), 0)
Self::new_with_leader(tokens, Pubkey::default(), 0)
}
pub fn seed(&self) -> Hash {
@ -66,7 +56,7 @@ impl Mint {
}
pub fn keypair(&self) -> Keypair {
Keypair::from_pkcs8(Input::from(&self.pkcs8)).expect("from_pkcs8 in mint pub fn keypair")
Keypair::from_bytes(&self.pkcs8).expect("from_pkcs8 in mint pub fn keypair")
}
pub fn pubkey(&self) -> Pubkey {

View File

@ -1,20 +1,19 @@
//! The `signature` module provides functionality for public, and private keys.
use bs58;
use ed25519_dalek;
use generic_array::typenum::U64;
use generic_array::GenericArray;
use rand::{ChaChaRng, Rng, SeedableRng};
use rand::{ChaChaRng, OsRng, Rng, SeedableRng};
use rayon::prelude::*;
use ring::signature::Ed25519KeyPair;
use ring::{rand, signature};
use serde_json;
use sha2::Sha512;
use solana_sdk::pubkey::Pubkey;
use std::error;
use std::fmt;
use std::fs::File;
use untrusted::Input;
pub type Keypair = Ed25519KeyPair;
pub type Keypair = ed25519_dalek::Keypair;
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Signature(GenericArray<u8, U64>);
@ -24,10 +23,9 @@ impl Signature {
Signature(GenericArray::clone_from_slice(&signature_slice))
}
pub fn verify(&self, pubkey_bytes: &[u8], message_bytes: &[u8]) -> bool {
let pubkey = Input::from(pubkey_bytes);
let message = Input::from(message_bytes);
let signature = Input::from(self.0.as_slice());
signature::verify(&signature::ED25519, pubkey, message, signature).is_ok()
let pubkey = ed25519_dalek::PublicKey::from_bytes(pubkey_bytes).unwrap();
let signature = ed25519_dalek::Signature::from_bytes(self.0.as_slice()).unwrap();
pubkey.verify::<Sha512>(message_bytes, &signature).is_ok()
}
}
@ -54,17 +52,16 @@ pub trait KeypairUtil {
fn pubkey(&self) -> Pubkey;
}
impl KeypairUtil for Ed25519KeyPair {
impl KeypairUtil for Keypair {
/// Return a new ED25519 keypair
fn new() -> Self {
let rng = rand::SystemRandom::new();
let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rng).expect("generate_pkcs8");
Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8_bytes)).expect("from_pcks8")
let mut rng: OsRng = OsRng::new().unwrap();
Keypair::generate::<Sha512, _>(&mut rng)
}
/// Return the public key for the given keypair
fn pubkey(&self) -> Pubkey {
Pubkey::new(self.public_key_bytes())
Pubkey::new(&self.public.to_bytes())
}
}
@ -78,20 +75,20 @@ impl GenKeys {
GenKeys { generator }
}
fn gen_seed(&mut self) -> [u8; 32] {
let mut seed = [0u8; 32];
fn gen_seed(&mut self) -> [u8; 64] {
let mut seed = [0u8; 64];
self.generator.fill(&mut seed);
seed
}
fn gen_n_seeds(&mut self, n: u64) -> Vec<[u8; 32]> {
fn gen_n_seeds(&mut self, n: u64) -> Vec<[u8; 64]> {
(0..n).map(|_| self.gen_seed()).collect()
}
pub fn gen_n_keypairs(&mut self, n: u64) -> Vec<Keypair> {
self.gen_n_seeds(n)
.into_par_iter()
.map(|seed| Keypair::from_seed_unchecked(Input::from(&seed)).unwrap())
.map(|seed| Keypair::from_bytes(&seed).unwrap())
.collect()
}
}
@ -104,7 +101,7 @@ pub fn read_pkcs8(path: &str) -> Result<Vec<u8>, Box<error::Error>> {
pub fn read_keypair(path: &str) -> Result<Keypair, Box<error::Error>> {
let pkcs8 = read_pkcs8(path)?;
let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8))?;
let keypair = Keypair::from_bytes(&pkcs8).unwrap();
Ok(keypair)
}

View File

@ -59,10 +59,8 @@ pub fn init() {
}
fn verify_packet(packet: &Packet) -> u8 {
use ring::signature;
use signature::Signature;
use solana_sdk::pubkey::Pubkey;
use untrusted;
let msg_start = TX_OFFSET + SIGNED_DATA_OFFSET;
let sig_start = TX_OFFSET + SIG_OFFSET;
@ -75,12 +73,11 @@ fn verify_packet(packet: &Packet) -> u8 {
}
let msg_end = packet.meta.size;
signature::verify(
&signature::ED25519,
untrusted::Input::from(&packet.data[pubkey_start..pubkey_end]),
untrusted::Input::from(&packet.data[msg_start..msg_end]),
untrusted::Input::from(&packet.data[sig_start..sig_end]),
).is_ok() as u8
let signature = Signature::new(&packet.data[sig_start..sig_end]);
signature.verify(
&packet.data[pubkey_start..pubkey_end],
&packet.data[msg_start..msg_end],
) as u8
}
fn verify_packet_disabled(_packet: &Packet) -> u8 {

View File

@ -9,6 +9,7 @@ use hash::Hash;
use rand::{ChaChaRng, Rng, SeedableRng};
use result::{Error, Result};
use service::Service;
use sha2::Sha512;
use signature::Keypair;
use signature::Signature;
use solana_sdk::pubkey::Pubkey;
@ -138,9 +139,9 @@ impl StorageStage {
entry_height: u64,
) -> Result<()> {
let mut seed = [0u8; 32];
let signature = keypair.sign(&entry_id.as_ref());
let signature = keypair.sign::<Sha512>(&entry_id.as_ref());
seed.copy_from_slice(&signature.as_ref()[..32]);
seed.copy_from_slice(&signature.to_bytes()[..32]);
let mut rng = ChaChaRng::from_seed(seed);
@ -151,7 +152,7 @@ impl StorageStage {
return Ok(());
}
// TODO: what if the validator does not have this slice
let slice = signature.as_ref()[0] as usize % num_slices;
let slice = signature.to_bytes()[0] as usize % num_slices;
debug!(
"storage verifying: slice: {} identities: {}",

View File

@ -3,6 +3,7 @@
use bincode::serialize;
use hash::{Hash, Hasher};
use serde::Serialize;
use sha2::Sha512;
use signature::{Keypair, KeypairUtil, Signature};
use solana_sdk::pubkey::Pubkey;
use std::mem::size_of;
@ -158,7 +159,7 @@ impl Transaction {
pub fn sign(&mut self, keypair: &Keypair, last_id: Hash) {
self.last_id = last_id;
let sign_data = self.get_sign_data();
self.signature = Signature::new(keypair.sign(&sign_data).as_ref());
self.signature = Signature::new(&keypair.sign::<Sha512>(&sign_data).to_bytes());
}
/// Verify only the transaction signature.
@ -301,19 +302,19 @@ mod tests {
assert_eq!(
serialize(&tx).unwrap(),
vec![
234, 139, 34, 5, 120, 28, 107, 203, 69, 25, 236, 200, 164, 1, 12, 47, 147, 53, 41,
143, 23, 116, 230, 203, 59, 228, 153, 14, 22, 241, 103, 226, 186, 169, 181, 65, 49,
215, 44, 2, 61, 214, 113, 216, 184, 206, 147, 104, 140, 225, 138, 21, 172, 135,
211, 80, 103, 80, 216, 106, 249, 86, 194, 1, 3, 0, 0, 0, 0, 0, 0, 0, 32, 253, 186,
201, 177, 11, 117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30,
78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161, 68, 32, 253, 186, 201, 177, 11,
117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76, 16,
252, 180, 72, 134, 137, 247, 161, 68, 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3
238, 228, 120, 18, 14, 44, 44, 74, 186, 124, 104, 174, 137, 227, 237, 157, 147, 37,
230, 74, 20, 48, 234, 36, 170, 60, 68, 184, 171, 240, 203, 18, 255, 110, 164, 67,
212, 206, 115, 182, 13, 90, 38, 215, 191, 51, 79, 183, 57, 102, 248, 221, 114, 72,
120, 66, 113, 146, 251, 102, 69, 187, 25, 8, 3, 0, 0, 0, 0, 0, 0, 0, 218, 65, 89,
124, 81, 87, 72, 141, 119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21,
24, 161, 28, 195, 135, 182, 105, 178, 238, 101, 134, 218, 65, 89, 124, 81, 87, 72,
141, 119, 36, 224, 63, 184, 216, 74, 55, 106, 67, 184, 244, 21, 24, 161, 28, 195,
135, 182, 105, 178, 238, 101, 134, 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3
],
);
}

View File

@ -10,8 +10,6 @@ use elf;
use fullnode::Config;
use hash::Hash;
use loader_transaction::LoaderTransaction;
use ring::rand::SystemRandom;
use ring::signature::Ed25519KeyPair;
use rpc::RpcSignatureStatus;
use rpc_request::RpcRequest;
use serde_json;
@ -693,8 +691,7 @@ pub fn request_airdrop(
}
pub fn gen_keypair_file(outfile: String) -> Result<String, Box<error::Error>> {
let rnd = SystemRandom::new();
let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rnd)?;
let pkcs8_bytes = Keypair::new().to_bytes();
let serialized = serde_json::to_string(&pkcs8_bytes.to_vec())?;
if outfile != "-" {