Implement equihash verification (#549)

This change brings in the `equihash` crate from librustzcash and uses it to add a basic `is_valid` test for `EquihashSolutions`.

Co-authored-by: Jane Lusby <jane@zfnd.org>
This commit is contained in:
Jane Lusby 2020-06-26 11:21:02 -07:00 committed by GitHub
parent eff8a3889e
commit afd0e90a74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 1 deletions

11
Cargo.lock generated
View File

@ -428,6 +428,16 @@ dependencies = [
"thiserror",
]
[[package]]
name = "equihash"
version = "0.0.0"
source = "git+https://github.com/ZcashFoundation/librustzcash.git?branch=equihash-crate#5b2c71e112ade5488ba49bb16f50897d513702f8"
dependencies = [
"blake2b_simd",
"byteorder",
"log",
]
[[package]]
name = "eyre"
version = "0.6.0"
@ -2300,6 +2310,7 @@ dependencies = [
"byteorder",
"chrono",
"ed25519-zebra",
"equihash",
"futures",
"hex",
"jubjub",

View File

@ -29,6 +29,7 @@ serde-big-array = "0.3.0"
# ZF deps
ed25519-zebra = "0.4"
redjubjub = "0.1"
equihash = { git = "https://github.com/ZcashFoundation/librustzcash.git", branch = "equihash-crate" }
[dev-dependencies]
proptest = "0.10"

View File

@ -28,6 +28,15 @@ pub struct EquihashSolution(
#[serde(with = "serde_helpers::BigArray")] pub [u8; EQUIHASH_SOLUTION_SIZE],
);
impl EquihashSolution {
/// Validate an equihash solution
pub fn is_valid(&self, input: &[u8], nonce: &[u8]) -> bool {
let n = 200;
let k = 9;
equihash::is_valid_solution(n, k, input, nonce, &self.0)
}
}
impl PartialEq<EquihashSolution> for EquihashSolution {
fn eq(&self, other: &EquihashSolution) -> bool {
self.0.as_ref() == other.0.as_ref()
@ -117,7 +126,8 @@ mod tests {
}
const EQUIHASH_SOLUTION_BLOCK_OFFSET: usize = 4 + 32 * 3 + 4 * 2 + 32;
const EQUIHASH_NONCE_BLOCK_OFFSET: usize = 4 + 32 * 3 + 4 * 2;
const EQUIHASH_SOLUTION_BLOCK_OFFSET: usize = EQUIHASH_NONCE_BLOCK_OFFSET + 32;
#[test]
fn equihash_solution_test_vector() {
@ -134,6 +144,27 @@ mod tests {
assert_eq!(solution_bytes, data.as_slice());
}
#[test]
fn equihash_solution_test_vector_is_valid() {
let block = crate::block::Block::zcash_deserialize(
&zebra_test::vectors::BLOCK_MAINNET_415000_BYTES[..],
)
.expect("block test vector should deserialize");
let solution = block.header.solution;
let header_bytes =
&zebra_test::vectors::HEADER_MAINNET_415000_BYTES[..EQUIHASH_NONCE_BLOCK_OFFSET];
assert!(solution.is_valid(header_bytes, &block.header.nonce));
let heade_bytes =
&zebra_test::vectors::HEADER_MAINNET_415000_BYTES[..EQUIHASH_NONCE_BLOCK_OFFSET - 1];
let headerr_bytes =
&zebra_test::vectors::HEADER_MAINNET_415000_BYTES[..EQUIHASH_NONCE_BLOCK_OFFSET + 1];
assert!(!solution.is_valid(heade_bytes, &block.header.nonce));
assert!(!solution.is_valid(headerr_bytes, &block.header.nonce));
}
static EQUIHASH_SIZE_TESTS: &[u64] = &[
0,
1,