From 1c447d85c0691f3f6cb6a05f79d9cc25a29a5649 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 14 Jul 2020 17:34:03 +1200 Subject: [PATCH] Replace libsodium's randombytes_buf with rand_core::OsRng::fill_bytes --- src/random.cpp | 4 ++-- src/random.h | 2 +- src/rust/include/librustzcash.h | 9 +++++++++ src/rust/src/rustzcash.rs | 6 ++++++ src/test/sighash_tests.cpp | 14 +++++++------- src/wallet/gtest/test_paymentdisclosure.cpp | 20 +++++++------------- src/zcash/NoteEncryption.cpp | 8 ++++---- src/zcbenchmarks.cpp | 4 ++-- 8 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/random.cpp b/src/random.cpp index 542fc57a0..be44c7d99 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -19,7 +19,7 @@ #include #endif -#include "sodium.h" +#include static inline int64_t GetPerformanceCounter() { @@ -36,7 +36,7 @@ static inline int64_t GetPerformanceCounter() void GetRandBytes(unsigned char* buf, size_t num) { - randombytes_buf(buf, num); + librustzcash_getrandom(buf, num); } uint64_t GetRand(uint64_t nMax) diff --git a/src/random.h b/src/random.h index 0a7852237..a0802d6fa 100644 --- a/src/random.h +++ b/src/random.h @@ -12,7 +12,7 @@ #include /** - * Functions to gather random data via the libsodium CSPRNG + * Functions to gather random data via the rand_core OsRng */ void GetRandBytes(unsigned char* buf, size_t num); uint64_t GetRand(uint64_t nMax); diff --git a/src/rust/include/librustzcash.h b/src/rust/include/librustzcash.h index 6f972a9ab..2b2f4fb70 100644 --- a/src/rust/include/librustzcash.h +++ b/src/rust/include/librustzcash.h @@ -359,6 +359,15 @@ extern "C" { unsigned char *h_ret ); + /// Fills the provided buffer with random bytes. This is intended to + /// be a cryptographically secure RNG; it uses Rust's `OsRng`, which + /// is implemented in terms of the `getrandom` crate. The first call + /// to this function may block until sufficient randomness is available. + void librustzcash_getrandom( + unsigned char *buf, + size_t buf_len + ); + int librustzcash_zebra_crypto_sign_verify_detached( const unsigned char *sig, const unsigned char *m, diff --git a/src/rust/src/rustzcash.rs b/src/rust/src/rustzcash.rs index aded2f3e6..9e0776901 100644 --- a/src/rust/src/rustzcash.rs +++ b/src/rust/src/rustzcash.rs @@ -1343,6 +1343,12 @@ pub extern "system" fn librustzcash_mmr_hash_node( 0 } +#[no_mangle] +pub extern "C" fn librustzcash_getrandom(buf: *mut u8, buf_len: usize) { + let buf = unsafe { slice::from_raw_parts_mut(buf, buf_len) }; + OsRng.fill_bytes(buf); +} + // The `librustzcash_zebra_crypto_sign_verify_detached` API attempts to // mimic the `crypto_sign_verify_detached` API in libsodium, but uses // the ed25519-zebra crate internally instead. diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 78591c951..f125cbee5 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -152,7 +152,7 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co sdesc.anchor = GetRandHash(); sdesc.nullifier = GetRandHash(); sdesc.rk = GetRandHash(); - randombytes_buf(sdesc.zkproof.begin(), sdesc.zkproof.size()); + GetRandBytes(sdesc.zkproof.begin(), sdesc.zkproof.size()); tx.vShieldedSpend.push_back(sdesc); } for (int out = 0; out < shielded_outs; out++) { @@ -160,9 +160,9 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co odesc.cv = GetRandHash(); odesc.cmu = GetRandHash(); odesc.ephemeralKey = GetRandHash(); - randombytes_buf(odesc.encCiphertext.begin(), odesc.encCiphertext.size()); - randombytes_buf(odesc.outCiphertext.begin(), odesc.outCiphertext.size()); - randombytes_buf(odesc.zkproof.begin(), odesc.zkproof.size()); + GetRandBytes(odesc.encCiphertext.begin(), odesc.encCiphertext.size()); + GetRandBytes(odesc.outCiphertext.begin(), odesc.outCiphertext.size()); + GetRandBytes(odesc.zkproof.begin(), odesc.zkproof.size()); tx.vShieldedOutput.push_back(odesc); } } @@ -181,11 +181,11 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle, uint32_t co jsdesc.nullifiers[1] = GetRandHash(); jsdesc.ephemeralKey = GetRandHash(); jsdesc.randomSeed = GetRandHash(); - randombytes_buf(jsdesc.ciphertexts[0].begin(), jsdesc.ciphertexts[0].size()); - randombytes_buf(jsdesc.ciphertexts[1].begin(), jsdesc.ciphertexts[1].size()); + GetRandBytes(jsdesc.ciphertexts[0].begin(), jsdesc.ciphertexts[0].size()); + GetRandBytes(jsdesc.ciphertexts[1].begin(), jsdesc.ciphertexts[1].size()); { libzcash::GrothProof zkproof; - randombytes_buf(zkproof.begin(), zkproof.size()); + GetRandBytes(zkproof.begin(), zkproof.size()); jsdesc.proof = zkproof; } jsdesc.macs[0] = GetRandHash(); diff --git a/src/wallet/gtest/test_paymentdisclosure.cpp b/src/wallet/gtest/test_paymentdisclosure.cpp index 7dae34cc5..9e655d56a 100644 --- a/src/wallet/gtest/test_paymentdisclosure.cpp +++ b/src/wallet/gtest/test_paymentdisclosure.cpp @@ -1,6 +1,7 @@ #include #include "main.h" +#include "random.h" #include "utilmoneystr.h" #include "chainparams.h" #include "utilstrencodings.h" @@ -43,13 +44,6 @@ using namespace std; static boost::uuids::random_generator uuidgen; -static uint256 random_uint256() -{ - uint256 ret; - randombytes_buf(ret.begin(), 32); - return ret; -} - // Subclass of PaymentDisclosureDB to add debugging methods class PaymentDisclosureDBTest : public PaymentDisclosureDB { public: @@ -113,11 +107,11 @@ TEST(paymentdisclosure, mainnet) { uint256 joinSplitPrivKey = uint256(vch); // Create payment disclosure key and info data to store in test database - size_t js = random_uint256().GetCheapHash() % std::numeric_limits::max(); - uint8_t n = random_uint256().GetCheapHash() % std::numeric_limits::max(); - PaymentDisclosureKey key { random_uint256(), js, n}; + size_t js = GetRandHash().GetCheapHash() % std::numeric_limits::max(); + uint8_t n = GetRandHash().GetCheapHash() % std::numeric_limits::max(); + PaymentDisclosureKey key { GetRandHash(), js, n}; PaymentDisclosureInfo info; - info.esk = random_uint256(); + info.esk = GetRandHash(); info.joinSplitPrivKey = joinSplitPrivKey; info.zaddr = libzcash::SproutSpendingKey::random().address(); ASSERT_TRUE(mydb.Put(key, info)); @@ -128,8 +122,8 @@ TEST(paymentdisclosure, mainnet) { ASSERT_EQ(info, info2); // Modify this local variable and confirm it no longer matches - info2.esk = random_uint256(); - info2.joinSplitPrivKey = random_uint256(); + info2.esk = GetRandHash(); + info2.joinSplitPrivKey = GetRandHash(); info2.zaddr = libzcash::SproutSpendingKey::random().address(); ASSERT_NE(info, info2); diff --git a/src/zcash/NoteEncryption.cpp b/src/zcash/NoteEncryption.cpp index dee211cba..c7f452d6c 100644 --- a/src/zcash/NoteEncryption.cpp +++ b/src/zcash/NoteEncryption.cpp @@ -1,4 +1,7 @@ #include "NoteEncryption.hpp" + +#include "random.h" + #include #include "sodium.h" #include @@ -444,10 +447,7 @@ uint256 NoteEncryption::generate_pubkey(const uint256 &sk_enc) uint256 random_uint256() { - uint256 ret; - randombytes_buf(ret.begin(), 32); - - return ret; + return GetRandHash(); } uint252 random_uint252() diff --git a/src/zcbenchmarks.cpp b/src/zcbenchmarks.cpp index f7d99958a..b7473f0b1 100644 --- a/src/zcbenchmarks.cpp +++ b/src/zcbenchmarks.cpp @@ -20,6 +20,7 @@ #include "policy/policy.h" #include "pow.h" #include "proof_verifier.h" +#include "random.h" #include "rpc/server.h" #include "script/sign.h" #include "sodium.h" @@ -161,8 +162,7 @@ double benchmark_solve_equihash() EhInitialiseState(n, k, eh_state); crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size()); - uint256 nonce; - randombytes_buf(nonce.begin(), 32); + uint256 nonce = GetRandHash(); crypto_generichash_blake2b_update(&eh_state, nonce.begin(), nonce.size());