diff --git a/hash.c b/hash.c index 21b00f9..e421f45 100644 --- a/hash.c +++ b/hash.c @@ -7,6 +7,7 @@ Public domain. #include "hash_address.h" #include "xmss_commons.h" +#include "hash.h" #include #include @@ -16,6 +17,17 @@ Public domain. #include #include +unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]){ +#if IS_LITTLE_ENDIAN==1 + int i = 0; + for(i=0;i<8;i++) + to_byte(bytes+i*4, addr[i],4); + return bytes; +#else + memcpy(bytes, addr, 32); + return bytes; +#endif +} int core_hash_SHA2(unsigned char *out, const unsigned int type, const unsigned char *key, unsigned int keylen, const unsigned char *in, unsigned long long inlen, unsigned int n){ unsigned long long i = 0; @@ -51,9 +63,8 @@ int core_hash_SHA2(unsigned char *out, const unsigned int type, const unsigned c * Implements PRF */ int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen) -{ - size_t inlen = 32; - return core_hash_SHA2(out, 3, key, keylen, in, inlen, keylen); +{ + return core_hash_SHA2(out, 3, key, keylen, in, 32, keylen); } /* @@ -77,15 +88,19 @@ int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub unsigned char buf[2*n]; unsigned char key[n]; unsigned char bitmask[2*n]; + unsigned char byte_addr[32]; unsigned int i; setKeyAndMask(addr, 0); - prf(key, (unsigned char *)addr, pub_seed, n); + addr_to_byte(byte_addr, addr); + prf(key, byte_addr, pub_seed, n); // Use MSB order setKeyAndMask(addr, 1); - prf(bitmask, (unsigned char *)addr, pub_seed, n); + addr_to_byte(byte_addr, addr); + prf(bitmask, byte_addr, pub_seed, n); setKeyAndMask(addr, 2); - prf(bitmask+n, (unsigned char *)addr, pub_seed, n); + addr_to_byte(byte_addr, addr); + prf(bitmask+n, byte_addr, pub_seed, n); for (i = 0; i < 2*n; i++) { buf[i] = in[i] ^ bitmask[i]; } @@ -97,13 +112,23 @@ int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub unsigned char buf[n]; unsigned char key[n]; unsigned char bitmask[n]; + unsigned char byte_addr[32]; unsigned int i; setKeyAndMask(addr, 0); - prf(key, (unsigned char *)addr, pub_seed, n); + printf("\naddr before: "); + for(i = 0; i< 8; i++){ + printf("%08x",addr[i]); + } + addr_to_byte(byte_addr, addr); + printf("\naddr after: "); + hexdump(byte_addr,32); + printf("\n"); + prf(key, byte_addr, pub_seed, n); // Use MSB order setKeyAndMask(addr, 1); - prf(bitmask, (unsigned char *)addr, pub_seed, n); + addr_to_byte(byte_addr, addr); + prf(bitmask, byte_addr, pub_seed, n); for (i = 0; i < n; i++) { buf[i] = in[i] ^ bitmask[i]; diff --git a/hash.h b/hash.h index 795b26e..fbe594d 100644 --- a/hash.h +++ b/hash.h @@ -8,8 +8,11 @@ Public domain. #ifndef HASH_H #define HASH_H -int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, int keylen); -int h_msg(unsigned char *out,const unsigned char *in,unsigned long long inlen, const unsigned char *key, const int keylen, const int n); +#define IS_LITTLE_ENDIAN 1 + +unsigned char* addr_to_byte(unsigned char *bytes, const uint32_t addr[8]); +int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen); +int h_msg(unsigned char *out,const unsigned char *in,unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int n); int hash_h(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n); diff --git a/prg.c b/prg.c deleted file mode 100644 index cb95b86..0000000 --- a/prg.c +++ /dev/null @@ -1,80 +0,0 @@ -/* -prg.c version 20160217 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ -#include "chacha.h" -#include "prg.h" -#include -#include -#include -#include - -const unsigned char zero_nonce[12] = {0}; - -/** - * Generates rlen output bytes using ChaCha20 with a zero nonce and counter = 0 - */ -void prg(unsigned char *r, unsigned long long rlen, const unsigned char *key, unsigned int key_len) -{ - if (key_len == 32) { - CRYPTO_chacha_20_keystream(r, rlen, key, zero_nonce, 0); - } - else { - if (key_len == 64) { - unsigned long long left = rlen; - u_int32_t counter = 0; - unsigned char *c = (unsigned char*)&counter; - unsigned int length; - unsigned int i = 0; - unsigned char tmp[64]; - while (left > 0) { - HMAC(EVP_sha512(), key, key_len, c , 4, tmp, &length); - if (length != 64) { - fprintf(stderr, "HMAC outputs %d bytes... That should not happen...", length); - } - for (i = 0; ((i < length) && (i < left)); i++) { - r[rlen-left+i] = tmp[i]; - } - left -= length; - counter++; - } - } - else { - fprintf(stderr,"prg.c:: Code only supports 32 byte and 64 byte seeds"); - } - } -} - -/** - * Generates n output bytes using ChaCha20 (n=32) or HMAC-SHA2-512 (n=64). - * - * For ChaCha, nonce and counter are set depending on the address addr. For HMAC, addr is used as message. - */ -void prg_with_counter(unsigned char *r, const unsigned char *key, unsigned int n, const unsigned char addr[16]) -{ - int i; - unsigned char nonce[12]; - if (n == 32) { - for (i = 0; i < 12; i++) { - nonce[i] = addr[i]; - } - uint32_t counter; - counter = (((uint32_t)addr[12]) << 24) | (((uint32_t)addr[13]) << 16) | (((uint32_t)addr[14]) << 8) | addr[15]; - // TODO: Check address handling. Endianess? - CRYPTO_chacha_20_keystream(r, n, key, nonce, counter); - } - else { - if (n == 64) { - unsigned int length; - HMAC(EVP_sha512(), key, n, addr, 16, r, &length); - if (length != 64) { - fprintf(stderr, "HMAC outputs %d bytes... That should not happen...", length); - } - } - else { - fprintf(stderr,"prg.c:: Code only supports 32 byte and 64 byte seeds"); - } - } -} \ No newline at end of file diff --git a/prg.h b/prg.h deleted file mode 100644 index 28f6c4f..0000000 --- a/prg.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -prg.h version 20160217 -Andreas Hülsing -Joost Rijneveld -Public domain. -*/ - -#ifndef PRG_H -#define PRG_H -#include - -/** - * Generates rlen output bytes using key_len-byte key and places them in r. - * - */ -void prg(unsigned char *r, unsigned long long rlen, const unsigned char *key, unsigned int key_len); - -/** - * Generates n output bytes using n-byte key and hash address addr and places them in r. - * - */ -void prg_with_counter(unsigned char *r, const unsigned char *key, unsigned int n, const unsigned char addr[16]); -#endif diff --git a/xmss.c b/xmss.c index c7188e0..a123cfe 100644 --- a/xmss.c +++ b/xmss.c @@ -30,12 +30,14 @@ Public domain. */ static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8]) { + unsigned char bytes[32]; // Make sure that chain addr, hash addr, and key bit are 0! setChainADRS(addr,0); setHashADRS(addr,0); setKeyAndMask(addr,0); // Generate pseudorandom value - prf(seed, (unsigned char*) addr, sk_seed, n); + addr_to_byte(bytes, addr); + prf(seed, bytes, sk_seed, n); } /** @@ -360,7 +362,7 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig to_byte(hash_key+2*n, idx, n); // Then use it for message digest h_msg(msg_h, msg, msglen, hash_key, 3*n, n); - + // Start collecting signature *sig_msg_len = 0; @@ -454,7 +456,7 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n; m_len = sig_msg_len - tmp_sig_len; h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n); - + //----------------------- // Verify signature //----------------------- diff --git a/xmss_fast.c b/xmss_fast.c index 4ef3e08..46a450a 100644 --- a/xmss_fast.c +++ b/xmss_fast.c @@ -30,12 +30,14 @@ Public domain. */ static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8]) { + unsigned char bytes[32]; // Make sure that chain addr, hash addr, and key bit are 0! setChainADRS(addr,0); setHashADRS(addr,0); setKeyAndMask(addr,0); // Generate pseudorandom value - prf(seed, (unsigned char*) addr, sk_seed, n); + addr_to_byte(bytes, addr); + prf(seed, bytes, sk_seed, n); } /**