Replace SHA3 with BLAKE2b everywhere

This commit is contained in:
Ignotus Peverell 2017-07-20 13:52:07 +00:00
parent 9703cba92a
commit 01b66de437
No known key found for this signature in database
GPG key ID: 99CD25F39F8F8211
7 changed files with 23 additions and 30 deletions

View file

@ -13,6 +13,7 @@ grin_grin = { path = "./grin" }
grin_config = { path = "./config" } grin_config = { path = "./config" }
secp256k1zkp = { path = "./secp256k1zkp" } secp256k1zkp = { path = "./secp256k1zkp" }
blake2-rfc = "~0.2.17"
clap = "^2.23.3" clap = "^2.23.3"
daemonize = "^0.2.3" daemonize = "^0.2.3"
env_logger="^0.3.5" env_logger="^0.3.5"
@ -20,6 +21,3 @@ log = "^0.3"
serde = "~1.0.8" serde = "~1.0.8"
serde_derive = "~1.0.8" serde_derive = "~1.0.8"
serde_json = "~1.0.2" serde_json = "~1.0.2"
tiny-keccak = "1.1"

View file

@ -6,6 +6,7 @@ workspace = ".."
[dependencies] [dependencies]
bitflags = "~0.7.0" bitflags = "~0.7.0"
blake2-rfc = "~0.2.17"
byteorder = "^0.5" byteorder = "^0.5"
num-bigint = "^0.1.35" num-bigint = "^0.1.35"
rust-crypto = "^0.2" rust-crypto = "^0.2"
@ -13,6 +14,5 @@ rand = "^0.3"
serde = "~1.0.8" serde = "~1.0.8"
serde_derive = "~1.0.8" serde_derive = "~1.0.8"
time = "^0.1" time = "^0.1"
tiny-keccak = "1.1"
secp256k1zkp = { path = "../secp256k1zkp" } secp256k1zkp = { path = "../secp256k1zkp" }

View file

@ -19,9 +19,10 @@
use std::cmp::min; use std::cmp::min;
use std::{fmt, ops}; use std::{fmt, ops};
use tiny_keccak::Keccak;
use std::convert::AsRef; use std::convert::AsRef;
use blake2::blake2b::Blake2b;
use ser::{self, Reader, Readable, Writer, Writeable, Error, AsFixedBytes}; use ser::{self, Reader, Readable, Writer, Writeable, Error, AsFixedBytes};
/// A hash consisting of all zeroes, used as a sentinel. No known preimage. /// A hash consisting of all zeroes, used as a sentinel. No known preimage.
@ -129,28 +130,28 @@ impl Writeable for Hash {
/// Serializer that outputs a hash of the serialized object /// Serializer that outputs a hash of the serialized object
pub struct HashWriter { pub struct HashWriter {
state: Keccak, state: Blake2b,
} }
impl HashWriter { impl HashWriter {
/// Consume the `HashWriter`, outputting its current hash into a 32-byte /// Consume the `HashWriter`, outputting its current hash into a 32-byte
/// array /// array
pub fn finalize(self, output: &mut [u8]) { pub fn finalize(self, output: &mut [u8]) {
self.state.finalize(output); output.copy_from_slice(self.state.finalize().as_bytes());
} }
/// Consume the `HashWriter`, outputting a `Hash` corresponding to its /// Consume the `HashWriter`, outputting a `Hash` corresponding to its
/// current state /// current state
pub fn into_hash(self) -> Hash { pub fn into_hash(self) -> Hash {
let mut new_hash = ZERO_HASH; let mut res = [0; 32];
self.state.finalize(&mut new_hash.0[..]); (&mut res).copy_from_slice(self.state.finalize().as_bytes());
new_hash Hash(res)
} }
} }
impl Default for HashWriter { impl Default for HashWriter {
fn default() -> HashWriter { fn default() -> HashWriter {
HashWriter { state: Keccak::new_sha3_256() } HashWriter { state: Blake2b::new(32) }
} }
} }

View file

@ -23,6 +23,7 @@
#[macro_use] #[macro_use]
extern crate bitflags; extern crate bitflags;
extern crate blake2_rfc as blake2;
extern crate byteorder; extern crate byteorder;
extern crate crypto; extern crate crypto;
extern crate num_bigint as bigint; extern crate num_bigint as bigint;
@ -32,7 +33,6 @@ extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate time; extern crate time;
extern crate tiny_keccak;
#[macro_use] #[macro_use]
pub mod macros; pub mod macros;

View file

@ -124,7 +124,7 @@ The Cuckoo Cycle outlined above forms the basis of Grin's mining process, howeve
In order to provide additional difficulty control in a manner that meets the needs of a network with constantly evolving hashpower In order to provide additional difficulty control in a manner that meets the needs of a network with constantly evolving hashpower
availability, a further Hashcash-based difficulty check is applied to potential solution sets as follows: availability, a further Hashcash-based difficulty check is applied to potential solution sets as follows:
If the SHA3-256 (Keccak) hash If the Blake2b hash
of a potential set of solution nonces (currently an array of 42 u32s representing the cycle nonces,) of a potential set of solution nonces (currently an array of 42 u32s representing the cycle nonces,)
is less than an evolving difficulty target T, then the solution is considered valid. More precisely, is less than an evolving difficulty target T, then the solution is considered valid. More precisely,
the proof difficulty is calculated as the maximum target hash (2^256) divided by the current hash, the proof difficulty is calculated as the maximum target hash (2^256) divided by the current hash,
@ -174,11 +174,11 @@ valid Proofs-of-Work to create the latest block in the chain. The following is a
of a solution appearing in the graph of a solution appearing in the graph
* The Cuckoo Cycle detection algorithm tries to find a solution (i.e. a cycle of length 42) within the generated * The Cuckoo Cycle detection algorithm tries to find a solution (i.e. a cycle of length 42) within the generated
graph. graph.
* If a cycle is found, a SHA3-256 hash of the proof is created and is compared to the current target * If a cycle is found, a Blake2b hash of the proof is created and is compared to the current target
difficulty, as outlined in [Additional Difficulty Control](#additional-difficulty-control) above. difficulty, as outlined in [Additional Difficulty Control](#additional-difficulty-control) above.
* If the SHA3-256 Hash difficulty is greater than or equal to the target difficulty, the block is sent to the * If the Blake2b Hash difficulty is greater than or equal to the target difficulty, the block is sent to the
transaction pool, propogated amongst peers for validation, and work begins on the next block. transaction pool, propogated amongst peers for validation, and work begins on the next block.
* If the SHA3-256 Hash difficulty is less than the target difficulty, the proof is thrown out and the timed loop continues. * If the Blake2b Hash difficulty is less than the target difficulty, the proof is thrown out and the timed loop continues.
* If no solution is found, increment the nonce in the header by 1, and update the header's timestamp so the next iteration * If no solution is found, increment the nonce in the header by 1, and update the header's timestamp so the next iteration
hashes a different value for seeding the next loop's graph generation step. hashes a different value for seeding the next loop's graph generation step.
* If the loop times out with no solution found, start over again from the top, collecting new transactions and creating * If the loop times out with no solution found, start over again from the top, collecting new transactions and creating
@ -229,7 +229,7 @@ every time while larger miners can move on as soon as they find a solution. So i
a POW that requires multiple solution attempts with each attempt taking a relatively small amount of time is desirable. a POW that requires multiple solution attempts with each attempt taking a relatively small amount of time is desirable.
Following from the this, Grin's progress-freeness is due to the fact that a solution to a Cuckoo with Grin's default parameters Following from the this, Grin's progress-freeness is due to the fact that a solution to a Cuckoo with Grin's default parameters
can typically be found in under a second on most GPUs, and there is the additional requirement of the SHA3-256 difficulty check can typically be found in under a second on most GPUs, and there is the additional requirement of the Blake2b difficulty check
on top of that. Members of a pool are thus able to prove they're working on a solution to a block by submitting valid Cuckoo solutions on top of that. Members of a pool are thus able to prove they're working on a solution to a block by submitting valid Cuckoo solutions
(or a small bundle of them) that simply fall under the current network target difficulty. (or a small bundle of them) that simply fall under the current network target difficulty.

View file

@ -19,8 +19,8 @@ extern crate grin_chain as chain;
extern crate grin_api as api; extern crate grin_api as api;
extern crate grin_wallet as wallet; extern crate grin_wallet as wallet;
extern crate secp256k1zkp as secp; extern crate secp256k1zkp as secp;
extern crate tiny_keccak;
extern crate blake2;
extern crate env_logger; extern crate env_logger;
extern crate futures; extern crate futures;
extern crate tokio_core; extern crate tokio_core;
@ -35,6 +35,7 @@ use std::fs;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::ops::Deref; use std::ops::Deref;
use blake2::blake2b::blake2b;
use futures::{Future}; use futures::{Future};
use futures::future::join_all; use futures::future::join_all;
use futures::task::park; use futures::task::park;
@ -44,7 +45,6 @@ use tokio_core::reactor::Handle;
use tokio_timer::Timer; use tokio_timer::Timer;
use secp::Secp256k1; use secp::Secp256k1;
use tiny_keccak::Keccak;
use wallet::WalletConfig; use wallet::WalletConfig;
use core::consensus; use core::consensus;
@ -269,10 +269,7 @@ impl LocalServerContainer {
//Just use the name of the server for a seed for now //Just use the name of the server for a seed for now
let seed = format!("{}", self.config.name); let seed = format!("{}", self.config.name);
let mut sha3 = Keccak::new_sha3_256(); let seed = blake2b(32, &[], seed.as_bytes());
sha3.update(seed.as_bytes());
let mut seed = [0; 32];
sha3.finalize(&mut seed);
let s = Secp256k1::new(); let s = Secp256k1::new();
let key = wallet::ExtendedKey::from_seed(&s, &seed[..]) let key = wallet::ExtendedKey::from_seed(&s, &seed[..])
@ -523,4 +520,4 @@ impl LocalServerContainerPool {
} }
} }
} }

View file

@ -21,7 +21,7 @@ extern crate log;
extern crate env_logger; extern crate env_logger;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate tiny_keccak; extern crate blake2;
extern crate grin_api as api; extern crate grin_api as api;
extern crate grin_grin as grin; extern crate grin_grin as grin;
@ -34,8 +34,8 @@ use std::thread;
use std::io::Read; use std::io::Read;
use std::fs::File; use std::fs::File;
use std::time::Duration; use std::time::Duration;
use tiny_keccak::Keccak;
use blake2::blake2b::blake2b;
use clap::{Arg, App, SubCommand, ArgMatches}; use clap::{Arg, App, SubCommand, ArgMatches};
use daemonize::Daemonize; use daemonize::Daemonize;
@ -264,10 +264,7 @@ fn wallet_command(wallet_args: &ArgMatches) {
let hd_seed = wallet_args.value_of("pass").expect("Wallet passphrase required."); let hd_seed = wallet_args.value_of("pass").expect("Wallet passphrase required.");
// TODO do something closer to BIP39, eazy solution right now // TODO do something closer to BIP39, eazy solution right now
let mut sha3 = Keccak::new_sha3_256(); let seed = blake2b(32, &[], hd_seed.as_bytes());
sha3.update(hd_seed.as_bytes());
let mut seed = [0; 32];
sha3.finalize(&mut seed);
let s = Secp256k1::new(); let s = Secp256k1::new();
let key = wallet::ExtendedKey::from_seed(&s, &seed[..]) let key = wallet::ExtendedKey::from_seed(&s, &seed[..])