Migrate BLAKE2b Rust FFI to `cxx`

This commit is contained in:
Jack Grigg 2022-05-26 16:09:30 +00:00
parent 54aeb2c408
commit df08281f25
24 changed files with 158 additions and 214 deletions

View File

@ -45,9 +45,15 @@ LIBBITCOIN_WALLET=libbitcoin_wallet.a
endif
# TODO: Figure out how to avoid an explicit file list.
CXXBRIDGE_RS = rust/src/equihash.rs
CXXBRIDGE_H = rust/gen/include/rust/equihash.h
CXXBRIDGE_CPP = rust/gen/src/equihash.cpp
CXXBRIDGE_RS = \
rust/src/blake2b.rs \
rust/src/equihash.rs
CXXBRIDGE_H = \
rust/gen/include/rust/blake2b.h \
rust/gen/include/rust/equihash.h
CXXBRIDGE_CPP = \
rust/gen/src/blake2b.cpp \
rust/gen/src/equihash.cpp
# We add a rust/cxx.h include to indicate that we provide this (via the rustcxx depends
# package), so that cxxbridge doesn't include it within the generated headers and code.
@ -56,7 +62,7 @@ CXXBRIDGE_OPTS = -i rust/cxx.h
$(CXXBRIDGE_RS): ;
$(CXXBRIDGE_H) $(CXXBRIDGE_CPP): $(CXXBRIDGE_RS)
@$(MKDIR_P) $(@D)
$(AM_V_GEN)$(CXXBRIDGE) $(CXXBRIDGE_OPTS) $< -o $@
$(AM_V_GEN)$(CXXBRIDGE) $(CXXBRIDGE_OPTS) rust/src/$(basename $(@F)).rs -o $@
# We pass through CC etc. flags so they are available to Rust dependencies that internally
# compile C or C++ code with the `cc` crate.

View File

@ -25,12 +25,12 @@
#ifdef ENABLE_MINING
void eh_HashState::Update(const unsigned char *input, size_t inputLen)
{
blake2b_update(inner.get(), input, inputLen);
inner->update({input, inputLen});
}
void eh_HashState::Finalize(unsigned char *hash, size_t hLen)
{
blake2b_finalize(inner.get(), hash, hLen);
inner->finalize({hash, hLen});
}
#endif
@ -155,15 +155,15 @@ std::vector<unsigned char> GetMinimalFromIndices(std::vector<eh_index> indices,
static EhSolverCancelledException solver_cancelled;
template<unsigned int N, unsigned int K>
void Equihash<N,K>::InitialiseState(eh_HashState& base_state)
eh_HashState Equihash<N,K>::InitialiseState()
{
uint32_t le_N = htole32(N);
uint32_t le_K = htole32(K);
unsigned char personalization[BLAKE2bPersonalBytes] = {};
unsigned char personalization[blake2b::PERSONALBYTES] = {};
memcpy(personalization, "ZcashPoW", 8);
memcpy(personalization+8, &le_N, 4);
memcpy(personalization+12, &le_K, 4);
base_state = eh_HashState((512/N)*N/8, personalization);
return eh_HashState((512/N)*N/8, personalization);
}
void GenerateHash(const eh_HashState& base_state, eh_index g,
@ -730,7 +730,7 @@ invalidsolution:
}
// Explicit instantiations for Equihash<96,3>
template void Equihash<96,3>::InitialiseState(eh_HashState& base_state);
template eh_HashState Equihash<96,3>::InitialiseState();
template bool Equihash<96,3>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
@ -739,7 +739,7 @@ template bool Equihash<96,3>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(EhSolverCancelCheck)> cancelled);
// Explicit instantiations for Equihash<200,9>
template void Equihash<200,9>::InitialiseState(eh_HashState& base_state);
template eh_HashState Equihash<200,9>::InitialiseState();
template bool Equihash<200,9>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
@ -748,7 +748,7 @@ template bool Equihash<200,9>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(EhSolverCancelCheck)> cancelled);
// Explicit instantiations for Equihash<96,5>
template void Equihash<96,5>::InitialiseState(eh_HashState& base_state);
template eh_HashState Equihash<96,5>::InitialiseState();
template bool Equihash<96,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
@ -757,7 +757,7 @@ template bool Equihash<96,5>::OptimisedSolve(const eh_HashState& base_state,
const std::function<bool(EhSolverCancelCheck)> cancelled);
// Explicit instantiations for Equihash<48,5>
template void Equihash<48,5>::InitialiseState(eh_HashState& base_state);
template eh_HashState Equihash<48,5>::InitialiseState();
template bool Equihash<48,5>::BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);

View File

@ -39,16 +39,17 @@ void EhIndexToArray(const eh_index i, unsigned char* array);
#include <set>
#include <rust/blake2b.h>
#include <rust/constants.h>
#include <rust/cxx.h>
struct eh_HashState {
std::unique_ptr<BLAKE2bState, decltype(&blake2b_free)> inner;
rust::Box<blake2b::State> inner;
eh_HashState() : inner(nullptr, blake2b_free) {}
eh_HashState(size_t length, unsigned char personalization[BLAKE2bPersonalBytes]) : inner(blake2b_init(length, personalization), blake2b_free) {}
eh_HashState(size_t length, unsigned char personalization[blake2b::PERSONALBYTES]) :
inner(blake2b::init(length, {personalization, blake2b::PERSONALBYTES})) {}
eh_HashState(eh_HashState&& baseState) : inner(std::move(baseState.inner)) {}
eh_HashState(const eh_HashState& baseState) : inner(blake2b_clone(baseState.inner.get()), blake2b_free) {}
eh_HashState(const eh_HashState& baseState) : inner(baseState.inner->box_clone()) {}
eh_HashState& operator=(eh_HashState&& baseState)
{
if (this != &baseState) {
@ -59,7 +60,7 @@ struct eh_HashState {
eh_HashState& operator=(const eh_HashState& baseState)
{
if (this != &baseState) {
inner.reset(blake2b_clone(baseState.inner.get()));
inner = baseState.inner->box_clone();
}
return *this;
}
@ -212,7 +213,7 @@ public:
Equihash() { }
void InitialiseState(eh_HashState& base_state);
eh_HashState InitialiseState();
bool BasicSolve(const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,
const std::function<bool(EhSolverCancelCheck)> cancelled);
@ -228,18 +229,19 @@ static Equihash<200,9> Eh200_9;
static Equihash<96,5> Eh96_5;
static Equihash<48,5> Eh48_5;
#define EhInitialiseState(n, k, base_state) \
#define EhInitialiseState(n, k) [&](){ \
if (n == 96 && k == 3) { \
Eh96_3.InitialiseState(base_state); \
return Eh96_3.InitialiseState(); \
} else if (n == 200 && k == 9) { \
Eh200_9.InitialiseState(base_state); \
return Eh200_9.InitialiseState(); \
} else if (n == 96 && k == 5) { \
Eh96_5.InitialiseState(base_state); \
return Eh96_5.InitialiseState(); \
} else if (n == 48 && k == 5) { \
Eh48_5.InitialiseState(base_state); \
return Eh48_5.InitialiseState(); \
} else { \
throw std::invalid_argument("Unsupported Equihash parameters"); \
}
} \
}()
inline bool EhBasicSolve(unsigned int n, unsigned int k, const eh_HashState& base_state,
const std::function<bool(std::vector<unsigned char>)> validBlock,

View File

@ -86,8 +86,7 @@ TEST(EquihashTests, IsProbablyDuplicate) {
TEST(EquihashTests, CheckBasicSolverCancelled) {
Equihash<48,5> Eh48_5;
eh_HashState state;
Eh48_5.InitialiseState(state);
eh_HashState state = Eh48_5.InitialiseState();
uint256 V = uint256S("0x00");
state.Update(V.begin(), V.size());
@ -190,8 +189,7 @@ TEST(EquihashTests, CheckBasicSolverCancelled) {
TEST(EquihashTests, CheckOptimisedSolverCancelled) {
Equihash<48,5> Eh48_5;
eh_HashState state;
Eh48_5.InitialiseState(state);
eh_HashState state = Eh48_5.InitialiseState();
uint256 V = uint256S("0x00");
state.Update(V.begin(), V.size());

View File

@ -17,6 +17,8 @@
#include <vector>
#include <rust/blake2b.h>
#include <rust/constants.h>
#include <rust/cxx.h>
typedef uint256 ChainCode;
@ -154,31 +156,29 @@ public:
class CBLAKE2bWriter
{
private:
BLAKE2bState* state;
rust::Box<blake2b::State> state;
public:
int nType;
int nVersion;
CBLAKE2bWriter(int nTypeIn, int nVersionIn, const unsigned char* personal) : nType(nTypeIn), nVersion(nVersionIn) {
state = blake2b_init(32, personal);
}
~CBLAKE2bWriter() {
blake2b_free(state);
}
CBLAKE2bWriter(int nTypeIn, int nVersionIn, const unsigned char* personal) :
nType(nTypeIn),
nVersion(nVersionIn),
state(blake2b::init(32, {personal, blake2b::PERSONALBYTES})) {}
int GetType() const { return nType; }
int GetVersion() const { return nVersion; }
CBLAKE2bWriter& write(const char *pch, size_t size) {
blake2b_update(state, (const unsigned char*)pch, size);
state->update({(const unsigned char*)pch, size});
return (*this);
}
// invalidates the object
uint256 GetHash() {
uint256 result;
blake2b_finalize(state, (unsigned char*)&result, 32);
state->finalize({result.begin(), result.size()});
return result;
}

View File

@ -994,8 +994,7 @@ void static BitcoinMiner(const CChainParams& chainparams)
while (true) {
// Hash state
eh_HashState state;
EhInitialiseState(n, k, state);
eh_HashState state = EhInitialiseState(n, k);
// I = the block header minus nonce and solution.
CEquihashInput I{*pblock};
@ -1006,8 +1005,7 @@ void static BitcoinMiner(const CChainParams& chainparams)
state.Update((unsigned char*)&ss[0], ss.size());
// H(I||V||...
eh_HashState curr_state;
curr_state = state;
eh_HashState curr_state = state;
curr_state.Update(pblock->nNonce.begin(), pblock->nNonce.size());
// (x_1, x_2, ...) = A(I, V, n, k)
@ -1056,7 +1054,7 @@ void static BitcoinMiner(const CChainParams& chainparams)
if (solver == "tromp") {
// Create solver and initialize it.
equi eq(1);
eq.setstate(curr_state.inner.get());
eq.setstate(curr_state.inner);
// Initialization done, start algo driver.
eq.digit0(0);

View File

@ -14,6 +14,8 @@
#include <stdlib.h> // for function qsort
#include <rust/blake2b.h>
#include <rust/constants.h>
#include <rust/cxx.h>
typedef uint32_t u32;
typedef unsigned char uchar;
@ -43,17 +45,16 @@ typedef u32 proof[PROOFSIZE];
enum verify_code { POW_OK, POW_DUPLICATE, POW_OUT_OF_ORDER, POW_NONZERO_XOR };
const char *errstr[] = { "OK", "duplicate index", "indices out of order", "nonzero xor" };
void genhash(const BLAKE2bState *ctx, u32 idx, uchar *hash) {
auto state = blake2b_clone(ctx);
void genhash(const rust::Box<blake2b::State>& ctx, u32 idx, uchar *hash) {
auto state = ctx->box_clone();
u32 leb = htole32(idx / HASHESPERBLAKE);
blake2b_update(state, (uchar *)&leb, sizeof(u32));
state->update({(const uchar *)&leb, sizeof(u32)});
uchar blakehash[HASHOUT];
blake2b_finalize(state, blakehash, HASHOUT);
blake2b_free(state);
state->finalize({blakehash, HASHOUT});
memcpy(hash, blakehash + (idx % HASHESPERBLAKE) * WN/8, WN/8);
}
int verifyrec(const BLAKE2bState *ctx, u32 *indices, uchar *hash, int r) {
int verifyrec(const rust::Box<blake2b::State>& ctx, u32 *indices, uchar *hash, int r) {
if (r == 0) {
genhash(ctx, *indices, hash);
return POW_OK;
@ -95,7 +96,7 @@ bool duped(proof prf) {
}
// verify Wagner conditions
int verify(u32 indices[PROOFSIZE], const BLAKE2bState *ctx) {
int verify(u32 indices[PROOFSIZE], const rust::Box<blake2b::State> ctx) {
if (duped(indices))
return POW_DUPLICATE;
uchar hash[WN/8];

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include <optional>
typedef uint16_t u16;
typedef uint64_t u64;
@ -207,7 +208,7 @@ u32 min(const u32 a, const u32 b) {
}
struct equi {
BLAKE2bState* blake_ctx;
std::optional<rust::Box<blake2b::State>> blake_ctx;
htalloc hta;
bsizes *nslots; // PUT IN BUCKET STRUCT
proof *sols;
@ -230,10 +231,9 @@ struct equi {
hta.dealloctrees();
free(nslots);
free(sols);
blake2b_free(blake_ctx);
}
void setstate(const BLAKE2bState *ctx) {
blake_ctx = blake2b_clone(ctx);
void setstate(const rust::Box<blake2b::State>& ctx) {
blake_ctx = ctx->box_clone();
memset(nslots, 0, NBUCKETS * sizeof(au32)); // only nslots[0] needs zeroing
nsols = 0;
}
@ -435,15 +435,13 @@ struct equi {
void digit0(const u32 id) {
uchar hash[HASHOUT];
BLAKE2bState* state;
htlayout htl(this, 0);
const u32 hashbytes = hashsize(0);
for (u32 block = id; block < NBLOCKS; block += nthreads) {
state = blake2b_clone(blake_ctx);
auto state = blake_ctx.value()->box_clone();
u32 leb = htole32(block);
blake2b_update(state, (uchar *)&leb, sizeof(u32));
blake2b_finalize(state, hash, HASHOUT);
blake2b_free(state);
state->update({(const uchar *)&leb, sizeof(u32)});
state->finalize({hash, HASHOUT});
for (u32 i = 0; i<HASHESPERBLAKE; i++) {
const uchar *ph = hash + i * WN/8;
#if BUCKBITS == 16 && RESTBITS == 4

View File

@ -11,11 +11,13 @@
#include "utilstrencodings.h"
#include "crypto/common.h"
#include <rust/constants.h>
#include <algorithm>
const unsigned char ZCASH_AUTH_DATA_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_AUTH_DATA_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','A','u','t','h','D','a','t','H','a','s','h'};
const unsigned char ZCASH_BLOCK_COMMITMENTS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_BLOCK_COMMITMENTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','B','l','o','c','k','C','o','m','m','i','t'};
uint256 DeriveBlockCommitmentsHash(

View File

@ -229,8 +229,7 @@ UniValue generate(const UniValue& params, bool fHelp)
}
// Hash state
eh_HashState eh_state;
EhInitialiseState(n, k, eh_state);
eh_HashState eh_state = EhInitialiseState(n, k);
// I = the block header minus nonce and solution.
CEquihashInput I{*pblock};

View File

@ -1,59 +0,0 @@
// Copyright (c) 2020-2022 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#ifndef ZCASH_RUST_INCLUDE_RUST_BLAKE2B_H
#define ZCASH_RUST_INCLUDE_RUST_BLAKE2B_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct BLAKE2bState;
typedef struct BLAKE2bState BLAKE2bState;
#define BLAKE2bPersonalBytes 16U
/// Initializes a BLAKE2b state with no key and no salt.
///
/// `personalization` MUST be a pointer to a 16-byte array.
///
/// Please free this with `blake2b_free` when you are done.
BLAKE2bState* blake2b_init(
size_t output_len,
const unsigned char* personalization);
/// Clones the given BLAKE2b state.
///
/// Both states need to be separately freed with `blake2b_free` when you are
/// done.
BLAKE2bState* blake2b_clone(const BLAKE2bState* state);
/// Frees a BLAKE2b state returned by `blake2b_init`.
void blake2b_free(BLAKE2bState* state);
/// Adds input to the hash. You can call this any number of times.
void blake2b_update(
BLAKE2bState* state,
const unsigned char* input,
size_t input_len);
/// Finalizes the `state` and stores the result in `output`.
///
/// `output_len` MUST be less than or equal to the value that was passed as the
/// first parameter to `blake2b_init`.
///
/// This method is idempotent, and calling it multiple times will give the same
/// result. It's also possible to call `blake2b_update` with more input in
/// between.
void blake2b_finalize(
BLAKE2bState* state,
unsigned char* output,
size_t output_len);
#ifdef __cplusplus
}
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_BLAKE2B_H

View File

@ -0,0 +1,16 @@
// Copyright (c) 2022 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
#ifndef ZCASH_RUST_INCLUDE_RUST_CONSTANTS_H
#define ZCASH_RUST_INCLUDE_RUST_CONSTANTS_H
#include <stddef.h>
#ifdef __cplusplus
namespace blake2b {
const size_t PERSONALBYTES = 16;
}
#endif
#endif // ZCASH_RUST_INCLUDE_RUST_TYPES_H

View File

@ -2,19 +2,23 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
use blake2b_simd::{State, PERSONALBYTES};
use libc::{c_uchar, size_t};
use std::ptr;
use std::slice;
#[cxx::bridge(namespace = "blake2b")]
mod ffi {
extern "Rust" {
type State;
#[no_mangle]
pub extern "C" fn blake2b_init(
output_len: size_t,
personalization: *const [c_uchar; PERSONALBYTES],
) -> *mut State {
let personalization = unsafe { personalization.as_ref().unwrap() };
fn init(output_len: usize, personalization: &[u8]) -> Box<State>;
fn box_clone(&self) -> Box<State>;
fn update(&mut self, input: &[u8]);
fn finalize(&self, output: &mut [u8]);
}
}
Box::into_raw(Box::new(
#[derive(Clone)]
struct State(blake2b_simd::State);
fn init(output_len: usize, personalization: &[u8]) -> Box<State> {
Box::new(State(
blake2b_simd::Params::new()
.hash_length(output_len)
.personal(personalization)
@ -22,35 +26,19 @@ pub extern "C" fn blake2b_init(
))
}
#[no_mangle]
pub extern "C" fn blake2b_clone(state: *const State) -> *mut State {
unsafe { state.as_ref() }
.map(|state| Box::into_raw(Box::new(state.clone())))
.unwrap_or(ptr::null_mut())
}
impl State {
fn box_clone(&self) -> Box<Self> {
Box::new(self.clone())
}
#[no_mangle]
pub extern "C" fn blake2b_free(state: *mut State) {
if !state.is_null() {
drop(unsafe { Box::from_raw(state) });
fn update(&mut self, input: &[u8]) {
self.0.update(input);
}
fn finalize(&self, output: &mut [u8]) {
// Allow consuming only part of the output.
let hash = self.0.finalize();
assert!(output.len() <= hash.as_bytes().len());
output.copy_from_slice(&hash.as_bytes()[..output.len()]);
}
}
#[no_mangle]
pub extern "C" fn blake2b_update(state: *mut State, input: *const c_uchar, input_len: size_t) {
let state = unsafe { state.as_mut().unwrap() };
let input = unsafe { slice::from_raw_parts(input, input_len) };
state.update(input);
}
#[no_mangle]
pub extern "C" fn blake2b_finalize(state: *mut State, output: *mut c_uchar, output_len: size_t) {
let state = unsafe { state.as_mut().unwrap() };
let output = unsafe { slice::from_raw_parts_mut(output, output_len) };
// Allow consuming only part of the output.
let hash = state.finalize();
assert!(output_len <= hash.as_bytes().len());
output.copy_from_slice(&hash.as_bytes()[..output_len]);
}

View File

@ -16,6 +16,7 @@
#include "uint256.h"
#include <librustzcash.h>
#include <rust/constants.h>
#include <rust/transaction.h>
using namespace std;
@ -1061,17 +1062,17 @@ public:
}
};
const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_PREVOUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','P','r','e','v','o','u','t','H','a','s','h'};
const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_SEQUENCE_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','S','e','q','u','e','n','c','H','a','s','h'};
const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'};
uint256 GetPrevoutHash(const CTransaction& txTo) {

View File

@ -47,8 +47,7 @@ void PrintSolutions(std::stringstream &strm, std::set<std::vector<uint32_t>> sol
#ifdef ENABLE_MINING
void TestEquihashSolvers(unsigned int n, unsigned int k, const std::string &I, const arith_uint256 &nonce, const std::set<std::vector<uint32_t>> &solns) {
size_t cBitLen { n/(k+1) };
eh_HashState state;
EhInitialiseState(n, k, state);
eh_HashState state = EhInitialiseState(n, k);
uint256 V = ArithToUint256(nonce);
BOOST_TEST_MESSAGE("Running solver: n = " << n << ", k = " << k << ", I = " << I << ", V = " << V.GetHex());
state.Update((unsigned char*)&I[0], I.size());

View File

@ -200,8 +200,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
unsigned int k = Params().GetConsensus().nEquihashK;
// Hash state
eh_HashState eh_state;
EhInitialiseState(n, k, eh_state);
eh_HashState eh_state = EhInitialiseState(n, k);
// I = the block header minus nonce and solution.
CEquihashInput I{*pblock};

View File

@ -157,8 +157,7 @@ TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>&
IncrementExtraNonce(pblocktemplate, chainActive.Tip(), extraNonce, chainparams.GetConsensus());
// Hash state
eh_HashState eh_state;
EhInitialiseState(n, k, eh_state);
eh_HashState eh_state = EhInitialiseState(n, k);
// I = the block header minus nonce and solution.
CEquihashInput I{block};

View File

@ -17,9 +17,10 @@
#include "zcash/address/zip32.h"
#include <variant>
#include <rust/constants.h>
#include <rust/unified_keys.h>
const unsigned char ZCASH_UFVK_ID_PERSONAL[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_UFVK_ID_PERSONAL[blake2b::PERSONALBYTES] =
{'Z', 'c', 'a', 's', 'h', '_', 'U', 'F', 'V', 'K', '_', 'I', 'd', '_', 'F', 'P'};
namespace libzcash {

View File

@ -206,7 +206,7 @@ uint256 JoinSplit<NumInputs, NumOutputs>::h_sig(
const std::array<uint256, NumInputs>& nullifiers,
const Ed25519VerificationKey& joinSplitPubKey
) {
const unsigned char personalization[BLAKE2bPersonalBytes]
const unsigned char personalization[blake2b::PERSONALBYTES]
= {'Z','c','a','s','h','C','o','m','p','u','t','e','h','S','i','g'};
std::vector<unsigned char> block(randomSeed.begin(), randomSeed.end());
@ -219,10 +219,9 @@ uint256 JoinSplit<NumInputs, NumOutputs>::h_sig(
uint256 output;
auto state = blake2b_init(32, personalization);
blake2b_update(state, &block[0], block.size());
blake2b_finalize(state, output.begin(), 32);
blake2b_free(state);
auto state = blake2b::init(32, {personalization, blake2b::PERSONALBYTES});
state->update({&block[0], block.size()});
state->finalize({output.begin(), 32});
return output;
}

View File

@ -8,6 +8,7 @@
#include "librustzcash.h"
#include <rust/blake2b.h>
#include <rust/constants.h>
#define NOTEENCRYPTION_CIPHER_KEYSIZE 32
@ -32,13 +33,12 @@ void PRF_ock(
memcpy(block+64, cm.begin(), 32);
memcpy(block+96, epk.begin(), 32);
unsigned char personalization[BLAKE2bPersonalBytes] = {};
unsigned char personalization[blake2b::PERSONALBYTES] = {};
memcpy(personalization, "Zcash_Derive_ock", 16);
auto state = blake2b_init(NOTEENCRYPTION_CIPHER_KEYSIZE, personalization);
blake2b_update(state, block, 128);
blake2b_finalize(state, K, NOTEENCRYPTION_CIPHER_KEYSIZE);
blake2b_free(state);
auto state = blake2b::init(NOTEENCRYPTION_CIPHER_KEYSIZE, {personalization, blake2b::PERSONALBYTES});
state->update({block, 128});
state->finalize({K, NOTEENCRYPTION_CIPHER_KEYSIZE});
}
void KDF_Sapling(
@ -51,13 +51,12 @@ void KDF_Sapling(
memcpy(block+0, dhsecret.begin(), 32);
memcpy(block+32, epk.begin(), 32);
unsigned char personalization[BLAKE2bPersonalBytes] = {};
unsigned char personalization[blake2b::PERSONALBYTES] = {};
memcpy(personalization, "Zcash_SaplingKDF", 16);
auto state = blake2b_init(NOTEENCRYPTION_CIPHER_KEYSIZE, personalization);
blake2b_update(state, block, 64);
blake2b_finalize(state, K, NOTEENCRYPTION_CIPHER_KEYSIZE);
blake2b_free(state);
auto state = blake2b::init(NOTEENCRYPTION_CIPHER_KEYSIZE, {personalization, blake2b::PERSONALBYTES});
state->update({block, 64});
state->finalize({K, NOTEENCRYPTION_CIPHER_KEYSIZE});
}
void KDF(unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE],
@ -78,14 +77,13 @@ void KDF(unsigned char K[NOTEENCRYPTION_CIPHER_KEYSIZE],
memcpy(block+64, epk.begin(), 32);
memcpy(block+96, pk_enc.begin(), 32);
unsigned char personalization[BLAKE2bPersonalBytes] = {};
unsigned char personalization[blake2b::PERSONALBYTES] = {};
memcpy(personalization, "ZcashKDF", 8);
memcpy(personalization+8, &nonce, 1);
auto state = blake2b_init(NOTEENCRYPTION_CIPHER_KEYSIZE, personalization);
blake2b_update(state, block, 128);
blake2b_finalize(state, K, NOTEENCRYPTION_CIPHER_KEYSIZE);
blake2b_free(state);
auto state = blake2b::init(NOTEENCRYPTION_CIPHER_KEYSIZE, {personalization, blake2b::PERSONALBYTES});
state->update({block, 128});
state->finalize({K, NOTEENCRYPTION_CIPHER_KEYSIZE});
}
namespace libzcash {

View File

@ -10,10 +10,11 @@
#include "zcash/prf.h"
#include <librustzcash.h>
#include <rust/constants.h>
namespace libzcash {
const unsigned char ZCASH_SAPLING_FVFP_PERSONALIZATION[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_SAPLING_FVFP_PERSONALIZATION[blake2b::PERSONALBYTES] =
{'Z', 'c', 'a', 's', 'h', 'S', 'a', 'p', 'l', 'i', 'n', 'g', 'F', 'V', 'F', 'P'};
//! Sapling

View File

@ -12,11 +12,12 @@
#include <librustzcash.h>
#include <rust/blake2b.h>
#include <rust/constants.h>
const unsigned char ZCASH_HD_SEED_FP_PERSONAL[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_HD_SEED_FP_PERSONAL[blake2b::PERSONALBYTES] =
{'Z', 'c', 'a', 's', 'h', '_', 'H', 'D', '_', 'S', 'e', 'e', 'd', '_', 'F', 'P'};
const unsigned char ZCASH_TADDR_OVK_PERSONAL[BLAKE2bPersonalBytes] =
const unsigned char ZCASH_TADDR_OVK_PERSONAL[blake2b::PERSONALBYTES] =
{'Z', 'c', 'T', 'a', 'd', 'd', 'r', 'T', 'o', 'S', 'a', 'p', 'l', 'i', 'n', 'g'};
uint256 HDSeed::Fingerprint() const
@ -30,11 +31,10 @@ uint256 ovkForShieldingFromTaddr(HDSeed& seed) {
auto rawSeed = seed.RawSeed();
// I = BLAKE2b-512("ZcTaddrToSapling", seed)
auto state = blake2b_init(64, ZCASH_TADDR_OVK_PERSONAL);
blake2b_update(state, rawSeed.data(), rawSeed.size());
auto state = blake2b::init(64, {ZCASH_TADDR_OVK_PERSONAL, blake2b::PERSONALBYTES});
state->update({rawSeed.data(), rawSeed.size()});
auto intermediate = std::array<unsigned char, 64>();
blake2b_finalize(state, intermediate.data(), 64);
blake2b_free(state);
state->finalize({intermediate.data(), 64});
// I_L = I[0..32]
uint256 intermediate_L;

View File

@ -5,8 +5,9 @@
#include <array>
#include <librustzcash.h>
#include <rust/blake2b.h>
#include <rust/constants.h>
const unsigned char ZCASH_EXPANDSEED_PERSONALIZATION[BLAKE2bPersonalBytes] = {'Z','c','a','s','h','_','E','x','p','a','n','d','S','e','e','d'};
const unsigned char ZCASH_EXPANDSEED_PERSONALIZATION[blake2b::PERSONALBYTES] = {'Z','c','a','s','h','_','E','x','p','a','n','d','S','e','e','d'};
// Sapling
std::array<unsigned char, 64> PRF_expand(const uint256& sk, unsigned char t)
@ -17,10 +18,9 @@ std::array<unsigned char, 64> PRF_expand(const uint256& sk, unsigned char t)
memcpy(&blob[0], sk.begin(), 32);
blob[32] = t;
auto state = blake2b_init(64, ZCASH_EXPANDSEED_PERSONALIZATION);
blake2b_update(state, blob, 33);
blake2b_finalize(state, res.data(), 64);
blake2b_free(state);
auto state = blake2b::init(64, {ZCASH_EXPANDSEED_PERSONALIZATION, blake2b::PERSONALBYTES});
state->update({blob, 33});
state->finalize({res.data(), 64});
return res;
}
@ -75,10 +75,9 @@ std::array<unsigned char, 11> default_diversifier(const uint256& sk)
blob[33] = 0;
while (true) {
auto state = blake2b_init(64, ZCASH_EXPANDSEED_PERSONALIZATION);
blake2b_update(state, blob, 34);
blake2b_finalize(state, res.data(), 11);
blake2b_free(state);
auto state = blake2b::init(64, {ZCASH_EXPANDSEED_PERSONALIZATION, blake2b::PERSONALBYTES});
state->update({blob, 34});
state->finalize({res.data(), 11});
if (librustzcash_check_diversifier(res.data())) {
break;

View File

@ -161,8 +161,7 @@ double benchmark_solve_equihash()
const Consensus::Params& params = Params(CBaseChainParams::MAIN).GetConsensus();
unsigned int n = params.nEquihashN;
unsigned int k = params.nEquihashK;
eh_HashState eh_state;
EhInitialiseState(n, k, eh_state);
eh_HashState eh_state = EhInitialiseState(n, k);
eh_state.Update((unsigned char*)&ss[0], ss.size());
uint256 nonce = GetRandHash();