mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 20:42:59 +01:00
Add the RFC6979 PRNG
This commit is contained in:
parent
a8f5087e53
commit
3060e36098
@ -206,12 +206,14 @@ crypto_libbitcoin_crypto_a_SOURCES = \
|
||||
crypto/sha256.cpp \
|
||||
crypto/sha512.cpp \
|
||||
crypto/hmac_sha256.cpp \
|
||||
crypto/rfc6979_hmac_sha256.cpp \
|
||||
crypto/hmac_sha512.cpp \
|
||||
crypto/ripemd160.cpp \
|
||||
crypto/common.h \
|
||||
crypto/sha256.h \
|
||||
crypto/sha512.h \
|
||||
crypto/hmac_sha256.h \
|
||||
crypto/rfc6979_hmac_sha256.h \
|
||||
crypto/hmac_sha512.h \
|
||||
crypto/sha1.h \
|
||||
crypto/ripemd160.h
|
||||
|
47
src/crypto/rfc6979_hmac_sha256.cpp
Normal file
47
src/crypto/rfc6979_hmac_sha256.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/rfc6979_hmac_sha256.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
static const unsigned char zero[1] = {0x00};
|
||||
static const unsigned char one[1] = {0x01};
|
||||
|
||||
RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false)
|
||||
{
|
||||
memset(V, 0x01, sizeof(V));
|
||||
memset(K, 0x00, sizeof(K));
|
||||
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
}
|
||||
|
||||
RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256()
|
||||
{
|
||||
memset(V, 0x01, sizeof(V));
|
||||
memset(K, 0x00, sizeof(K));
|
||||
}
|
||||
|
||||
void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen)
|
||||
{
|
||||
if (retry) {
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K);
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
}
|
||||
|
||||
while (outputlen > 0) {
|
||||
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
|
||||
size_t len = std::min(outputlen, sizeof(V));
|
||||
memcpy(output, V, len);
|
||||
output += len;
|
||||
outputlen -= len;
|
||||
}
|
||||
|
||||
retry = true;
|
||||
}
|
36
src/crypto/rfc6979_hmac_sha256.h
Normal file
36
src/crypto/rfc6979_hmac_sha256.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2014 The Bitcoin developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_RFC6979_HMAC_SHA256_H
|
||||
#define BITCOIN_RFC6979_HMAC_SHA256_H
|
||||
|
||||
#include "crypto/hmac_sha256.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** The RFC 6979 PRNG using HMAC-SHA256. */
|
||||
class RFC6979_HMAC_SHA256
|
||||
{
|
||||
private:
|
||||
unsigned char V[CHMAC_SHA256::OUTPUT_SIZE];
|
||||
unsigned char K[CHMAC_SHA256::OUTPUT_SIZE];
|
||||
bool retry;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new RFC6979 PRNG, using the given key and message.
|
||||
* The message is assumed to be already hashed.
|
||||
*/
|
||||
RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen);
|
||||
|
||||
/**
|
||||
* Generate a byte array.
|
||||
*/
|
||||
void Generate(unsigned char* output, size_t outputlen);
|
||||
|
||||
~RFC6979_HMAC_SHA256();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_RFC6979_HMAC_SHA256_H
|
@ -2,6 +2,7 @@
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "crypto/rfc6979_hmac_sha256.h"
|
||||
#include "crypto/ripemd160.h"
|
||||
#include "crypto/sha1.h"
|
||||
#include "crypto/sha256.h"
|
||||
@ -13,6 +14,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(crypto_tests)
|
||||
@ -246,4 +248,38 @@ BOOST_AUTO_TEST_CASE(hmac_sha512_testvectors) {
|
||||
"b6022cac3c4982b10d5eeb55c3e4de15134676fb6de0446065c97440fa8c6a58");
|
||||
}
|
||||
|
||||
void TestRFC6979(const std::string& hexkey, const std::string& hexmsg, const std::vector<std::string>& hexout)
|
||||
{
|
||||
std::vector<unsigned char> key = ParseHex(hexkey);
|
||||
std::vector<unsigned char> msg = ParseHex(hexmsg);
|
||||
RFC6979_HMAC_SHA256 rng(&key[0], key.size(), &msg[0], msg.size());
|
||||
|
||||
for (unsigned int i = 0; i < hexout.size(); i++) {
|
||||
std::vector<unsigned char> out = ParseHex(hexout[i]);
|
||||
std::vector<unsigned char> gen;
|
||||
gen.resize(out.size());
|
||||
rng.Generate(&gen[0], gen.size());
|
||||
BOOST_CHECK(out == gen);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rfc6979_hmac_sha256)
|
||||
{
|
||||
TestRFC6979(
|
||||
"0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f00",
|
||||
"4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
|
||||
boost::assign::list_of
|
||||
("4fe29525b2086809159acdf0506efb86b0ec932c7ba44256ab321e421e67e9fb")
|
||||
("2bf0fff1d3c378a22dc5de1d856522325c65b504491a0cbd01cb8f3aa67ffd4a")
|
||||
("f528b410cb541f77000d7afb6c5b53c5c471eab43e466d9ac5190c39c82fd82e"));
|
||||
|
||||
TestRFC6979(
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
boost::assign::list_of
|
||||
("9c236c165b82ae0cd590659e100b6bab3036e7ba8b06749baf6981e16f1a2b95")
|
||||
("df471061625bc0ea14b682feee2c9c02f235da04204c1d62a1536c6e17aed7a9")
|
||||
("7597887cbd76321f32e30440679a22cf7f8d9d2eac390e581fea091ce202ba94"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Loading…
Reference in New Issue
Block a user