Skip to content

Commit f0877f8

Browse files
committed
Merge pull request #5227
4cdaa95 Resize after succesful result (Pieter Wuille) 9d8604f Header define style cleanups (Pieter Wuille) a53fd41 Deterministic signing (Pieter Wuille) 3060e36 Add the RFC6979 PRNG (Pieter Wuille) a8f5087 Add HMAC-SHA256 (Pieter Wuille) 36fa4a7 Split up crypto/sha2 (Pieter Wuille)
2 parents 89151d9 + 4cdaa95 commit f0877f8

21 files changed

+612
-293
lines changed

src/Makefile.am

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,18 @@ libbitcoin_wallet_a_SOURCES = \
203203
crypto_libbitcoin_crypto_a_CPPFLAGS = $(BITCOIN_CONFIG_INCLUDES)
204204
crypto_libbitcoin_crypto_a_SOURCES = \
205205
crypto/sha1.cpp \
206-
crypto/sha2.cpp \
206+
crypto/sha256.cpp \
207+
crypto/sha512.cpp \
208+
crypto/hmac_sha256.cpp \
209+
crypto/rfc6979_hmac_sha256.cpp \
210+
crypto/hmac_sha512.cpp \
207211
crypto/ripemd160.cpp \
208212
crypto/common.h \
209-
crypto/sha2.h \
213+
crypto/sha256.h \
214+
crypto/sha512.h \
215+
crypto/hmac_sha256.h \
216+
crypto/rfc6979_hmac_sha256.h \
217+
crypto/hmac_sha512.h \
210218
crypto/sha1.h \
211219
crypto/ripemd160.h
212220

@@ -343,8 +351,10 @@ if BUILD_BITCOIN_LIBS
343351
include_HEADERS = script/bitcoinconsensus.h
344352
libbitcoinconsensus_la_SOURCES = \
345353
core/transaction.cpp \
354+
crypto/hmac_sha512.cpp \
346355
crypto/sha1.cpp \
347-
crypto/sha2.cpp \
356+
crypto/sha256.cpp \
357+
crypto/sha512.cpp \
348358
crypto/ripemd160.cpp \
349359
eccryptoverify.cpp \
350360
ecwrapper.cpp \

src/crypto/hmac_sha256.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "crypto/hmac_sha256.h"
6+
7+
#include <string.h>
8+
9+
CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen)
10+
{
11+
unsigned char rkey[64];
12+
if (keylen <= 64) {
13+
memcpy(rkey, key, keylen);
14+
memset(rkey + keylen, 0, 64 - keylen);
15+
} else {
16+
CSHA256().Write(key, keylen).Finalize(rkey);
17+
memset(rkey + 32, 0, 32);
18+
}
19+
20+
for (int n = 0; n < 64; n++)
21+
rkey[n] ^= 0x5c;
22+
outer.Write(rkey, 64);
23+
24+
for (int n = 0; n < 64; n++)
25+
rkey[n] ^= 0x5c ^ 0x36;
26+
inner.Write(rkey, 64);
27+
}
28+
29+
void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
30+
{
31+
unsigned char temp[32];
32+
inner.Finalize(temp);
33+
outer.Write(temp, 32).Finalize(hash);
34+
}

src/crypto/hmac_sha256.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_CRYPTO_HMAC_SHA256_H
6+
#define BITCOIN_CRYPTO_HMAC_SHA256_H
7+
8+
#include "crypto/sha256.h"
9+
10+
#include <stdint.h>
11+
#include <stdlib.h>
12+
13+
/** A hasher class for HMAC-SHA-512. */
14+
class CHMAC_SHA256
15+
{
16+
private:
17+
CSHA256 outer;
18+
CSHA256 inner;
19+
20+
public:
21+
static const size_t OUTPUT_SIZE = 32;
22+
23+
CHMAC_SHA256(const unsigned char* key, size_t keylen);
24+
CHMAC_SHA256& Write(const unsigned char* data, size_t len)
25+
{
26+
inner.Write(data, len);
27+
return *this;
28+
}
29+
void Finalize(unsigned char hash[OUTPUT_SIZE]);
30+
};
31+
32+
#endif // BITCOIN_CRYPTO_HMAC_SHA256_H

src/crypto/hmac_sha512.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "crypto/hmac_sha512.h"
6+
7+
#include <string.h>
8+
9+
CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
10+
{
11+
unsigned char rkey[128];
12+
if (keylen <= 128) {
13+
memcpy(rkey, key, keylen);
14+
memset(rkey + keylen, 0, 128 - keylen);
15+
} else {
16+
CSHA512().Write(key, keylen).Finalize(rkey);
17+
memset(rkey + 64, 0, 64);
18+
}
19+
20+
for (int n = 0; n < 128; n++)
21+
rkey[n] ^= 0x5c;
22+
outer.Write(rkey, 128);
23+
24+
for (int n = 0; n < 128; n++)
25+
rkey[n] ^= 0x5c ^ 0x36;
26+
inner.Write(rkey, 128);
27+
}
28+
29+
void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
30+
{
31+
unsigned char temp[64];
32+
inner.Finalize(temp);
33+
outer.Write(temp, 64).Finalize(hash);
34+
}

src/crypto/hmac_sha512.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H
6+
#define BITCOIN_CRYPTO_HMAC_SHA512_H
7+
8+
#include "crypto/sha512.h"
9+
10+
#include <stdint.h>
11+
#include <stdlib.h>
12+
13+
/** A hasher class for HMAC-SHA-512. */
14+
class CHMAC_SHA512
15+
{
16+
private:
17+
CSHA512 outer;
18+
CSHA512 inner;
19+
20+
public:
21+
static const size_t OUTPUT_SIZE = 64;
22+
23+
CHMAC_SHA512(const unsigned char* key, size_t keylen);
24+
CHMAC_SHA512& Write(const unsigned char* data, size_t len)
25+
{
26+
inner.Write(data, len);
27+
return *this;
28+
}
29+
void Finalize(unsigned char hash[OUTPUT_SIZE]);
30+
};
31+
32+
#endif // BITCOIN_CRYPTO_HMAC_SHA512_H

src/crypto/rfc6979_hmac_sha256.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "crypto/rfc6979_hmac_sha256.h"
6+
7+
#include <string.h>
8+
9+
#include <algorithm>
10+
11+
static const unsigned char zero[1] = {0x00};
12+
static const unsigned char one[1] = {0x01};
13+
14+
RFC6979_HMAC_SHA256::RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen) : retry(false)
15+
{
16+
memset(V, 0x01, sizeof(V));
17+
memset(K, 0x00, sizeof(K));
18+
19+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Write(key, keylen).Write(msg, msglen).Finalize(K);
20+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
21+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(one, sizeof(one)).Write(key, keylen).Write(msg, msglen).Finalize(K);
22+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
23+
}
24+
25+
RFC6979_HMAC_SHA256::~RFC6979_HMAC_SHA256()
26+
{
27+
memset(V, 0x01, sizeof(V));
28+
memset(K, 0x00, sizeof(K));
29+
}
30+
31+
void RFC6979_HMAC_SHA256::Generate(unsigned char* output, size_t outputlen)
32+
{
33+
if (retry) {
34+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Write(zero, sizeof(zero)).Finalize(K);
35+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
36+
}
37+
38+
while (outputlen > 0) {
39+
CHMAC_SHA256(K, sizeof(K)).Write(V, sizeof(V)).Finalize(V);
40+
size_t len = std::min(outputlen, sizeof(V));
41+
memcpy(output, V, len);
42+
output += len;
43+
outputlen -= len;
44+
}
45+
46+
retry = true;
47+
}

src/crypto/rfc6979_hmac_sha256.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) 2014 The Bitcoin developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_RFC6979_HMAC_SHA256_H
6+
#define BITCOIN_RFC6979_HMAC_SHA256_H
7+
8+
#include "crypto/hmac_sha256.h"
9+
10+
#include <stdint.h>
11+
#include <stdlib.h>
12+
13+
/** The RFC 6979 PRNG using HMAC-SHA256. */
14+
class RFC6979_HMAC_SHA256
15+
{
16+
private:
17+
unsigned char V[CHMAC_SHA256::OUTPUT_SIZE];
18+
unsigned char K[CHMAC_SHA256::OUTPUT_SIZE];
19+
bool retry;
20+
21+
public:
22+
/**
23+
* Construct a new RFC6979 PRNG, using the given key and message.
24+
* The message is assumed to be already hashed.
25+
*/
26+
RFC6979_HMAC_SHA256(const unsigned char* key, size_t keylen, const unsigned char* msg, size_t msglen);
27+
28+
/**
29+
* Generate a byte array.
30+
*/
31+
void Generate(unsigned char* output, size_t outputlen);
32+
33+
~RFC6979_HMAC_SHA256();
34+
};
35+
36+
#endif // BITCOIN_RFC6979_HMAC_SHA256_H

src/crypto/sha2.h

Lines changed: 0 additions & 64 deletions
This file was deleted.

0 commit comments

Comments
 (0)