Skip to content

Commit

Permalink
Merge bitcoin#463: Reduce usage of hardcoded size constants
Browse files Browse the repository at this point in the history
c7680e5 Reduce usage of hardcoded size constants (Thomas Snider)

Pull request description:

  In particular the usage of keylen in nonce_function_rfc6979 seemed precarious - in one conditional it was unconditionally set, then in the next it was added to.  While it was clearly correct as written, I think this change makes it easier to reason about for new eyes and more resistant to breakage if there is any future change to what gets fed into the PRNG.

Tree-SHA512: 2241c183acc0f318f85a11ccff7fe28de7777bc53dea93ab8308bad15871047a268c6a2b36f77a599dce536fca48ab305ea746223840bc10953c893daffa0a50
  • Loading branch information
sipa committed Dec 21, 2017
2 parents 02f5001 + c7680e5 commit fb46c83
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 21 deletions.
23 changes: 12 additions & 11 deletions src/hash_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,10 @@ static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *
hash->bytes += len;
while (bufsize + len >= 64) {
/* Fill the buffer, and process it. */
memcpy(((unsigned char*)hash->buf) + bufsize, data, 64 - bufsize);
data += 64 - bufsize;
len -= 64 - bufsize;
size_t chunk_len = 64 - bufsize;
memcpy(((unsigned char*)hash->buf) + bufsize, data, chunk_len);
data += chunk_len;
len -= chunk_len;
secp256k1_sha256_transform(hash->s, hash->buf);
bufsize = 0;
}
Expand All @@ -162,11 +163,11 @@ static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out
}

static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t keylen) {
int n;
size_t n;
unsigned char rkey[64];
if (keylen <= 64) {
if (keylen <= sizeof(rkey)) {
memcpy(rkey, key, keylen);
memset(rkey + keylen, 0, 64 - keylen);
memset(rkey + keylen, 0, sizeof(rkey) - keylen);
} else {
secp256k1_sha256 sha256;
secp256k1_sha256_initialize(&sha256);
Expand All @@ -176,17 +177,17 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const
}

secp256k1_sha256_initialize(&hash->outer);
for (n = 0; n < 64; n++) {
for (n = 0; n < sizeof(rkey); n++) {
rkey[n] ^= 0x5c;
}
secp256k1_sha256_write(&hash->outer, rkey, 64);
secp256k1_sha256_write(&hash->outer, rkey, sizeof(rkey));

secp256k1_sha256_initialize(&hash->inner);
for (n = 0; n < 64; n++) {
for (n = 0; n < sizeof(rkey); n++) {
rkey[n] ^= 0x5c ^ 0x36;
}
secp256k1_sha256_write(&hash->inner, rkey, 64);
memset(rkey, 0, 64);
secp256k1_sha256_write(&hash->inner, rkey, sizeof(rkey));
memset(rkey, 0, sizeof(rkey));
}

static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size) {
Expand Down
23 changes: 13 additions & 10 deletions src/secp256k1.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge,
* representation inside secp256k1_pubkey, as conversion is very fast.
* Note that secp256k1_pubkey_save must use the same representation. */
secp256k1_ge_storage s;
memcpy(&s, &pubkey->data[0], 64);
memcpy(&s, &pubkey->data[0], sizeof(s));
secp256k1_ge_from_storage(ge, &s);
} else {
/* Otherwise, fall back to 32-byte big endian for X and Y. */
Expand All @@ -149,7 +149,7 @@ static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) {
if (sizeof(secp256k1_ge_storage) == 64) {
secp256k1_ge_storage s;
secp256k1_ge_to_storage(&s, ge);
memcpy(&pubkey->data[0], &s, 64);
memcpy(&pubkey->data[0], &s, sizeof(s));
} else {
VERIFY_CHECK(!secp256k1_ge_is_infinity(ge));
secp256k1_fe_normalize_var(&ge->x);
Expand Down Expand Up @@ -319,9 +319,14 @@ int secp256k1_ecdsa_verify(const secp256k1_context* ctx, const secp256k1_ecdsa_s
secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m));
}

static SECP256K1_INLINE void buffer_append(unsigned char *buf, unsigned int *offset, const void *data, unsigned int len) {
memcpy(buf + *offset, data, len);
*offset += len;
}

static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
unsigned char keydata[112];
int keylen = 64;
unsigned int offset = 0;
secp256k1_rfc6979_hmac_sha256 rng;
unsigned int i;
/* We feed a byte array to the PRNG as input, consisting of:
Expand All @@ -332,17 +337,15 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m
* different argument mixtures to emulate each other and result in the same
* nonces.
*/
memcpy(keydata, key32, 32);
memcpy(keydata + 32, msg32, 32);
buffer_append(keydata, &offset, key32, 32);
buffer_append(keydata, &offset, msg32, 32);
if (data != NULL) {
memcpy(keydata + 64, data, 32);
keylen = 96;
buffer_append(keydata, &offset, data, 32);
}
if (algo16 != NULL) {
memcpy(keydata + keylen, algo16, 16);
keylen += 16;
buffer_append(keydata, &offset, algo16, 16);
}
secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, keylen);
secp256k1_rfc6979_hmac_sha256_initialize(&rng, keydata, offset);
memset(keydata, 0, sizeof(keydata));
for (i = 0; i <= counter; i++) {
secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
Expand Down

0 comments on commit fb46c83

Please sign in to comment.