From 6a878602f2a531e087d07fbf5cbeed02431567ca Mon Sep 17 00:00:00 2001 From: Tyera Eulberg Date: Thu, 18 Apr 2019 11:47:34 -0600 Subject: [PATCH] Revert "Migrate from ring to ed25519-dalek, take 2 (#3844)" (#3868) This reverts commit e9b82bacdad0de664fff7b1e779c55313870b231. --- Cargo.lock | 46 +---------------------- bench-exchange/src/cli.rs | 5 +-- bench-tps/src/bench.rs | 2 +- core/Cargo.toml | 2 +- core/src/chacha.rs | 17 ++++++--- core/src/gen_keys.rs | 18 +-------- core/src/replicator.rs | 13 +++---- core/src/sigverify.rs | 15 +++++--- core/src/storage_stage.rs | 4 +- core/tests/tvu.rs | 2 +- sdk/Cargo.toml | 3 +- sdk/src/signature.rs | 78 +++++++++++++++------------------------ sdk/src/transaction.rs | 28 +++++++------- wallet/src/wallet.rs | 28 +++++++++++++- 14 files changed, 111 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72ec5bd7e..ad0bba7b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,14 +347,6 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "clear_on_drop" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "clicolors-control" version = "1.0.0" @@ -544,18 +536,6 @@ dependencies = [ "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "curve25519-dalek" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "difference" version = "2.0.0" @@ -592,18 +572,6 @@ name = "dtoa" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "ed25519-dalek" -version = "1.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "either" version = "1.5.1" @@ -2185,7 +2153,6 @@ dependencies = [ "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "hashbrown 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "hex-literal 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2204,6 +2171,7 @@ dependencies = [ "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2624,13 +2592,12 @@ dependencies = [ "bs58 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2808,11 +2775,6 @@ name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "subtle" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "syn" version = "0.11.11" @@ -3443,7 +3405,6 @@ dependencies = [ "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum clang-sys 0.26.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ef0c1bcf2e99c649104bd7a7012d8f8802684400e03db0ec0af48583c6fa0e4" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" -"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9" @@ -3463,13 +3424,11 @@ dependencies = [ "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" -"checksum curve25519-dalek 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e1f8a6fc0376eb52dc18af94915cc04dfdf8353746c0e8c550ae683a0815e5c1" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" "checksum dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" -"checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86" "checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac" "checksum elf 0.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4841de15dbe0e49b9b62a417589299e3be0d557e0900d36acb87e6dae47197f5" "checksum elfkit 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "02f182eda16a7360c80a2f8638d0726e9d5478173058f1505c42536ca666ecd2" @@ -3648,7 +3607,6 @@ dependencies = [ "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" "checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" -"checksum subtle 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "702662512f3ddeb74a64ce2fbbf3707ee1b6bb663d28bb054e0779bbc720d926" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" diff --git a/bench-exchange/src/cli.rs b/bench-exchange/src/cli.rs index 17a4655f3..6347492f8 100644 --- a/bench-exchange/src/cli.rs +++ b/bench-exchange/src/cli.rs @@ -2,9 +2,9 @@ use std::net::SocketAddr; use std::time::Duration; use clap::{crate_description, crate_name, crate_version, value_t, App, Arg, ArgMatches}; -use solana::gen_keys::GenKeys; use solana_drone::drone::DRONE_PORT; use solana_sdk::signature::{read_keypair, Keypair, KeypairUtil}; +use untrusted::Input; pub struct Config { pub network_addr: SocketAddr, @@ -152,8 +152,7 @@ pub fn extract_args<'a>(matches: &ArgMatches<'a>) -> Config { } else { args.identity = { let seed = [42_u8; 32]; - let mut rnd = GenKeys::new(seed); - rnd.gen_keypair() + Keypair::from_seed_unchecked(Input::from(&seed)).unwrap() }; } args.threads = value_t!(matches.value_of("threads"), usize).expect("Failed to parse threads"); diff --git a/bench-tps/src/bench.rs b/bench-tps/src/bench.rs index 2c07666c1..778196f09 100644 --- a/bench-tps/src/bench.rs +++ b/bench-tps/src/bench.rs @@ -68,7 +68,7 @@ pub fn do_bench_tps(config: Config) { let client = create_client(cluster_entrypoint.client_facing_addr(), FULLNODE_PORT_RANGE); let mut seed = [0u8; 32]; - seed.copy_from_slice(&id.to_bytes()[..32]); + seed.copy_from_slice(&id.public_key_bytes()[..32]); let mut rnd = GenKeys::new(seed); println!("Creating {} keypairs...", tx_count * 2); diff --git a/core/Cargo.toml b/core/Cargo.toml index 0c002a341..ec49f960f 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -25,7 +25,6 @@ bs58 = "0.2.0" byteorder = "1.3.1" chrono = { version = "0.4.0", features = ["serde"] } crc = { version = "1.8.1", optional = true } -ed25519-dalek = "1.0.0-pre.0" hashbrown = "0.2.0" indexmap = "1.0" itertools = "0.8.0" @@ -42,6 +41,7 @@ rand = "0.6.5" rand_chacha = "0.1.1" rayon = "1.0.0" reqwest = "0.9.11" +ring = "0.13.2" rocksdb = "0.11.0" serde = "1.0.89" serde_derive = "1.0.88" diff --git a/core/src/chacha.rs b/core/src/chacha.rs index 5c143e271..09eb03d78 100644 --- a/core/src/chacha.rs +++ b/core/src/chacha.rs @@ -94,7 +94,7 @@ mod tests { use crate::blocktree::Blocktree; use crate::chacha::chacha_cbc_encrypt_ledger; use crate::entry::Entry; - use crate::gen_keys::GenKeys; + use ring::signature::Ed25519KeyPair; use solana_sdk::hash::{hash, Hash, Hasher}; use solana_sdk::signature::KeypairUtil; use solana_sdk::system_transaction; @@ -103,14 +103,19 @@ mod tests { use std::io::Read; use std::path::Path; use std::sync::Arc; + use untrusted::Input; fn make_tiny_deterministic_test_entries(num: usize) -> Vec { let zero = Hash::default(); let one = hash(&zero.as_ref()); - - let seed = [2u8; 32]; - let mut rnd = GenKeys::new(seed); - let keypair = rnd.gen_keypair(); + let pkcs = [ + 48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 109, 148, 235, 20, 97, 127, + 43, 194, 109, 43, 121, 76, 54, 38, 234, 14, 108, 68, 209, 227, 137, 191, 167, 144, 177, + 174, 57, 182, 79, 198, 196, 93, 161, 35, 3, 33, 0, 116, 121, 255, 78, 31, 95, 179, 172, + 30, 125, 206, 87, 88, 78, 46, 145, 25, 154, 161, 252, 3, 58, 235, 116, 39, 148, 193, + 150, 111, 61, 20, 226, + ]; + let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs)).unwrap(); let mut id = one; let mut num_hashes = 0; @@ -159,7 +164,7 @@ mod tests { use bs58; // golden needs to be updated if blob stuff changes.... let golden = Hash::new( - &bs58::decode("GD6xs6Loh9gci6b6P8FVVJ1c1whCqxDzaqBrQkpcxowA") + &bs58::decode("5NBn4cBZmNZRftkjxj3um8W1eyYPzn2RgUJSA3SVbHaJ") .into_vec() .unwrap(), ); diff --git a/core/src/gen_keys.rs b/core/src/gen_keys.rs index afbe05c88..5782ed989 100644 --- a/core/src/gen_keys.rs +++ b/core/src/gen_keys.rs @@ -4,6 +4,7 @@ use rand::{Rng, SeedableRng}; use rand_chacha::ChaChaRng; use rayon::prelude::*; use solana_sdk::signature::Keypair; +use untrusted::Input; pub struct GenKeys { generator: ChaChaRng, @@ -25,14 +26,10 @@ impl GenKeys { (0..n).map(|_| self.gen_seed()).collect() } - pub fn gen_keypair(&mut self) -> Keypair { - Keypair::generate(&mut self.generator) - } - pub fn gen_n_keypairs(&mut self, n: u64) -> Vec { self.gen_n_seeds(n) .into_par_iter() - .map(|seed| Keypair::generate(&mut ChaChaRng::from_seed(seed))) + .map(|seed| Keypair::from_seed_unchecked(Input::from(&seed)).unwrap()) .collect() } } @@ -55,17 +52,6 @@ mod tests { } } - #[test] - fn test_gen_keypair_is_deterministic() { - let seed = [0u8; 32]; - let mut gen0 = GenKeys::new(seed); - let mut gen1 = GenKeys::new(seed); - assert_eq!( - gen0.gen_keypair().to_bytes().to_vec(), - gen1.gen_keypair().to_bytes().to_vec() - ); - } - fn gen_n_pubkeys(seed: [u8; 32], n: u64) -> HashSet { GenKeys::new(seed) .gen_n_keypairs(n) diff --git a/core/src/replicator.rs b/core/src/replicator.rs index 19e988b50..ad0d58550 100644 --- a/core/src/replicator.rs +++ b/core/src/replicator.rs @@ -14,7 +14,6 @@ use crate::streamer::receiver; use crate::streamer::responder; use crate::window_service::WindowService; use bincode::deserialize; -use ed25519_dalek; use rand::thread_rng; use rand::Rng; use solana_client::rpc_client::RpcClient; @@ -61,7 +60,7 @@ pub struct Replicator { slot: u64, ledger_path: String, storage_keypair: Arc, - signature: ed25519_dalek::Signature, + signature: ring::signature::Signature, cluster_entrypoint: ContactInfo, ledger_data_file_encrypted: PathBuf, sampling_offsets: Vec, @@ -108,10 +107,10 @@ pub fn sample_file(in_path: &Path, sample_offsets: &[u64]) -> io::Result { } fn get_entry_heights_from_blockhash( - signature: &ed25519_dalek::Signature, + signature: &ring::signature::Signature, storage_entry_height: 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) @@ -355,7 +354,7 @@ impl Replicator { #[cfg(feature = "chacha")] { let mut ivec = [0u8; 64]; - ivec.copy_from_slice(&self.signature.to_bytes()); + ivec.copy_from_slice(self.signature.as_ref()); let num_encrypted_bytes = chacha_cbc_encrypt_ledger( &self.blocktree, @@ -384,7 +383,7 @@ impl Replicator { use rand_chacha::ChaChaRng; let mut rng_seed = [0u8; 32]; - rng_seed.copy_from_slice(&self.signature.to_bytes()[0..32]); + rng_seed.copy_from_slice(&self.signature.as_ref()[0..32]); let mut rng = ChaChaRng::from_seed(rng_seed); for _ in 0..NUM_STORAGE_SAMPLES { self.sampling_offsets @@ -449,7 +448,7 @@ impl Replicator { &self.storage_keypair.pubkey(), self.hash, self.slot, - Signature::new(&self.signature.to_bytes()), + Signature::new(self.signature.as_ref()), ); let mut tx = Transaction::new_unsigned_instructions(vec![ix]); client diff --git a/core/src/sigverify.rs b/core/src/sigverify.rs index a307eebdf..7308b4ec0 100644 --- a/core/src/sigverify.rs +++ b/core/src/sigverify.rs @@ -67,8 +67,10 @@ pub fn init() { } fn verify_packet(packet: &Packet) -> u8 { + use ring::signature; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::Signature; + use untrusted; let (sig_len, sig_start, msg_start, pubkey_start) = get_packet_offsets(packet, 0); let mut sig_start = sig_start as usize; @@ -88,11 +90,14 @@ fn verify_packet(packet: &Packet) -> u8 { return 0; } - let signature = Signature::new(&packet.data[sig_start..sig_end]); - if !signature.verify( - &packet.data[pubkey_start..pubkey_end], - &packet.data[msg_start..msg_end], - ) { + if 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_err() + { return 0; } pubkey_start += size_of::(); diff --git a/core/src/storage_stage.rs b/core/src/storage_stage.rs index 46625292b..01d2ac1f0 100644 --- a/core/src/storage_stage.rs +++ b/core/src/storage_stage.rs @@ -327,7 +327,7 @@ impl StorageStage { let tx = Transaction::new_unsigned_instructions(vec![ix]); tx_sender.send(tx)?; - seed.copy_from_slice(&signature.to_bytes()[..32]); + seed.copy_from_slice(&signature.as_ref()[..32]); let mut rng = ChaChaRng::from_seed(seed); @@ -340,7 +340,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/core/tests/tvu.rs b/core/tests/tvu.rs index 794658603..f72f4f4c1 100644 --- a/core/tests/tvu.rs +++ b/core/tests/tvu.rs @@ -171,7 +171,7 @@ fn test_replay() { // receive retransmitted messages let timer = Duration::new(1, 0); while let Ok(_msg) = r_reader.recv_timeout(timer) { - info!("got msg"); + trace!("got msg"); } let working_bank = bank_forks.read().unwrap().working_bank(); diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 982116175..0088ae5b5 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -11,7 +11,6 @@ edition = "2018" [dependencies] bincode = "1.1.3" bs58 = "0.2.0" -ed25519-dalek = "1.0.0-pre.0" hex = "0.3.2" byteorder = "1.2.1" chrono = { version = "0.4.0", features = ["serde"] } @@ -19,7 +18,7 @@ generic-array = { version = "0.13.0", default-features = false, features = ["ser itertools = "0.8.0" log = "0.4.2" rand = "0.6.5" -rayon = "1.0.0" +ring = "0.13.2" sha2 = "0.8.0" serde = "1.0.90" serde_derive = "1.0.90" diff --git a/sdk/src/signature.rs b/sdk/src/signature.rs index 3edc71564..d8b584cd2 100644 --- a/sdk/src/signature.rs +++ b/sdk/src/signature.rs @@ -2,18 +2,19 @@ use crate::pubkey::Pubkey; use bs58; -use ed25519_dalek; use generic_array::typenum::U64; use generic_array::GenericArray; -use rand::rngs::OsRng; +use ring::signature::Ed25519KeyPair; +use ring::{rand, signature}; use serde_json; use std::error; use std::fmt; use std::fs::{self, File}; use std::io::Write; use std::path::Path; +use untrusted::Input; -pub type Keypair = ed25519_dalek::Keypair; +pub type Keypair = Ed25519KeyPair; #[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Signature(GenericArray); @@ -24,9 +25,10 @@ impl Signature { } pub fn verify(&self, pubkey_bytes: &[u8], message_bytes: &[u8]) -> bool { - let pubkey = ed25519_dalek::PublicKey::from_bytes(pubkey_bytes).unwrap(); - let signature = ed25519_dalek::Signature::from_bytes(self.0.as_slice()).unwrap(); - pubkey.verify(message_bytes, &signature).is_ok() + 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() } } @@ -70,33 +72,45 @@ pub trait KeypairUtil { fn sign_message(&self, message: &[u8]) -> Signature; } -impl KeypairUtil for Keypair { +impl KeypairUtil for Ed25519KeyPair { /// Return a new ED25519 keypair fn new() -> Self { - let mut rng = OsRng::new().unwrap(); - Keypair::generate(&mut rng) + 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") } /// Return the public key for the given keypair fn pubkey(&self) -> Pubkey { - Pubkey::new(&self.public.as_ref()) + Pubkey::new(self.public_key_bytes()) } fn sign_message(&self, message: &[u8]) -> Signature { - Signature::new(&self.sign(message).to_bytes()) + Signature::new(self.sign(message).as_ref()) } } -pub fn read_keypair(path: &str) -> Result> { +pub fn read_pkcs8(path: &str) -> Result, Box> { let file = File::open(path.to_string())?; - let bytes: Vec = serde_json::from_reader(file)?; - let keypair = Keypair::from_bytes(&bytes).unwrap(); + let pkcs8: Vec = serde_json::from_reader(file)?; + Ok(pkcs8) +} + +pub fn read_keypair(path: &str) -> Result> { + let pkcs8 = read_pkcs8(path)?; + let keypair = Ed25519KeyPair::from_pkcs8(Input::from(&pkcs8))?; Ok(keypair) } +pub fn gen_pkcs8() -> Result, Box> { + let rnd = rand::SystemRandom::new(); + let pkcs8_bytes = Ed25519KeyPair::generate_pkcs8(&rnd)?; + Ok(pkcs8_bytes.to_vec()) +} + +//pub fn gen_keypair_file(outfile: String) -> Result> { pub fn gen_keypair_file(outfile: String) -> Result> { - let keypair_bytes = Keypair::new().to_bytes(); - let serialized = serde_json::to_string(&keypair_bytes.to_vec())?; + let serialized = serde_json::to_string(&gen_pkcs8()?)?; if outfile != "-" { if let Some(outdir) = Path::new(&outfile).parent() { @@ -107,35 +121,3 @@ pub fn gen_keypair_file(outfile: String) -> Result> { } Ok(serialized) } - -#[cfg(test)] -mod tests { - use super::*; - use std::mem; - - fn tmp_file_path(name: &str) -> String { - use std::env; - let out_dir = env::var("OUT_DIR").unwrap_or_else(|_| "target".to_string()); - let keypair = Keypair::new(); - - format!("{}/tmp/{}-{}", out_dir, name, keypair.pubkey()).to_string() - } - - #[test] - fn test_gen_keypair_file() { - let outfile = tmp_file_path("test_gen_keypair_file.json"); - let serialized_keypair = gen_keypair_file(outfile.to_string()).unwrap(); - let keypair_vec: Vec = serde_json::from_str(&serialized_keypair).unwrap(); - assert!(Path::new(&outfile).exists()); - assert_eq!( - keypair_vec, - read_keypair(&outfile).unwrap().to_bytes().to_vec() - ); - assert_eq!( - read_keypair(&outfile).unwrap().pubkey().as_ref().len(), - mem::size_of::() - ); - fs::remove_file(&outfile).unwrap(); - assert!(!Path::new(&outfile).exists()); - } -} diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index da3ace0b7..2a66c5f0c 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -283,12 +283,14 @@ mod tests { } fn create_sample_transaction() -> Transaction { - let keypair = Keypair::from_bytes(&[ + use untrusted::Input; + let keypair = Keypair::from_pkcs8(Input::from(&[ 48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32, 255, 101, 36, 24, 124, 23, 167, 21, 132, 204, 155, 5, 185, 58, 121, 75, 156, 227, 116, 193, 215, 38, 142, 22, 8, 14, 229, 239, 119, 93, 5, 218, 161, 35, 3, 33, 0, 36, 100, 158, 252, 33, 161, 97, 185, - 62, 89, 99, - ]) + 62, 89, 99, 195, 250, 249, 187, 189, 171, 118, 241, 90, 248, 14, 68, 219, 231, 62, 157, + 5, 142, 27, 210, 117, + ])) .unwrap(); let to = Pubkey::new(&[ 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, @@ -373,16 +375,16 @@ mod tests { assert_eq!( serialize(&create_sample_transaction()).unwrap(), vec![ - 1, 134, 84, 186, 62, 126, 175, 48, 6, 80, 185, 139, 108, 109, 157, 213, 17, 249, 3, - 79, 83, 21, 89, 242, 148, 51, 140, 115, 77, 161, 134, 116, 136, 206, 171, 239, 236, - 240, 19, 73, 217, 152, 60, 159, 170, 41, 104, 29, 217, 93, 65, 139, 191, 202, 181, - 77, 246, 26, 15, 156, 186, 66, 32, 139, 6, 1, 2, 156, 227, 116, 193, 215, 38, 142, - 22, 8, 14, 229, 239, 119, 93, 5, 218, 161, 35, 3, 33, 0, 36, 100, 158, 252, 33, - 161, 97, 185, 62, 89, 99, 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, 1, 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, 2, 0, 1, 3, - 1, 2, 3 + 1, 0, 30, 236, 164, 222, 77, 89, 244, 36, 92, 35, 192, 25, 100, 18, 61, 155, 111, + 89, 189, 154, 90, 255, 217, 203, 105, 50, 243, 208, 179, 89, 146, 122, 222, 91, 34, + 106, 93, 82, 147, 213, 223, 184, 32, 204, 61, 227, 227, 41, 211, 67, 5, 156, 236, + 251, 178, 235, 234, 174, 123, 15, 26, 145, 3, 1, 2, 36, 100, 158, 252, 33, 161, 97, + 185, 62, 89, 99, 195, 250, 249, 187, 189, 171, 118, 241, 90, 248, 14, 68, 219, 231, + 62, 157, 5, 142, 27, 210, 117, 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, 1, 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, 2, 0, + 1, 3, 1, 2, 3 ] ); } diff --git a/wallet/src/wallet.rs b/wallet/src/wallet.rs index e264e85d3..751e5ed08 100644 --- a/wallet/src/wallet.rs +++ b/wallet/src/wallet.rs @@ -776,9 +776,11 @@ mod tests { use clap::{App, Arg, SubCommand}; use serde_json::Value; use solana_client::mock_rpc_client_request::SIGNATURE; + use solana_sdk::signature::{gen_keypair_file, read_keypair, read_pkcs8, Keypair, KeypairUtil}; use solana_sdk::transaction::TransactionError; + use std::fs; use std::net::{Ipv4Addr, SocketAddr}; - use std::path::PathBuf; + use std::path::{Path, PathBuf}; #[test] fn test_wallet_config_drone_addr() { @@ -1421,4 +1423,28 @@ mod tests { config.command = WalletCommand::Deploy("bad/file/location.so".to_string()); assert!(process_command(&config).is_err()); } + + fn tmp_file_path(name: &str) -> String { + use std::env; + let out_dir = env::var("OUT_DIR").unwrap_or_else(|_| "target".to_string()); + let keypair = Keypair::new(); + + format!("{}/tmp/{}-{}", out_dir, name, keypair.pubkey()).to_string() + } + + #[test] + fn test_wallet_gen_keypair_file() { + let outfile = tmp_file_path("test_gen_keypair_file.json"); + let serialized_keypair = gen_keypair_file(outfile.to_string()).unwrap(); + let keypair_vec: Vec = serde_json::from_str(&serialized_keypair).unwrap(); + assert!(Path::new(&outfile).exists()); + assert_eq!(keypair_vec, read_pkcs8(&outfile).unwrap()); + read_keypair(&outfile).unwrap(); + assert_eq!( + read_keypair(&outfile).unwrap().pubkey().as_ref().len(), + mem::size_of::() + ); + fs::remove_file(&outfile).unwrap(); + assert!(!Path::new(&outfile).exists()); + } }