added support for n = m = 64
This commit is contained in:
父節點
05c52526c6
當前提交
9d9b782ff9
10
hash.c
10
hash.c
@ -101,12 +101,12 @@ int hash_2n_n(unsigned char *out,const unsigned char *in, const unsigned char *p
|
||||
|
||||
SET_KEY_BIT(addr,1);
|
||||
SET_BLOCK_BIT(addr,0);
|
||||
prg_with_counter(key, n, pub_seed, n, addr);
|
||||
prg_with_counter(key, pub_seed, n, addr);
|
||||
SET_KEY_BIT(addr,0);
|
||||
// Use MSB order
|
||||
prg_with_counter(bitmask, n, pub_seed, n, addr);
|
||||
prg_with_counter(bitmask, pub_seed, n, addr);
|
||||
SET_BLOCK_BIT(addr,1);
|
||||
prg_with_counter(bitmask+n, n, pub_seed, n, addr);
|
||||
prg_with_counter(bitmask+n, pub_seed, n, addr);
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
buf[i] = 0x00;
|
||||
@ -136,9 +136,9 @@ int hash_n_n(unsigned char *out,const unsigned char *in, const unsigned char *pu
|
||||
int i;
|
||||
|
||||
WOTS_SELECT_KEY(addr);
|
||||
prg_with_counter(key, n, pub_seed, n, addr);
|
||||
prg_with_counter(key, pub_seed, n, addr);
|
||||
WOTS_SELECT_BLOCK(addr);
|
||||
prg_with_counter(bitmask, n, pub_seed, n, addr);
|
||||
prg_with_counter(bitmask, pub_seed, n, addr);
|
||||
for(i=0;i<n;i++)
|
||||
{
|
||||
buf[i] = 0x00;
|
||||
|
68
prg.c
68
prg.c
@ -6,7 +6,9 @@ Public domain.
|
||||
#include "chacha.h"
|
||||
#include "prg.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
const unsigned char zero_nonce[12] = {0};
|
||||
|
||||
@ -15,18 +17,50 @@ const unsigned char zero_nonce[12] = {0};
|
||||
*/
|
||||
void prg(unsigned char *r, unsigned long long rlen, const unsigned char *key, unsigned int key_len)
|
||||
{
|
||||
CRYPTO_chacha_20_keystream(r, rlen, key, zero_nonce, 0);
|
||||
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 rlen output bytes using ChaCha20.
|
||||
* Nonce and counter are set depending on the address addr.
|
||||
* 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, unsigned long long rlen, const unsigned char *key, unsigned int key_len, const unsigned char addr[16])
|
||||
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(key_len == 32){
|
||||
if(n == 32){
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
nonce[i] = addr[i];
|
||||
@ -34,20 +68,26 @@ void prg_with_counter(unsigned char *r, unsigned long long rlen, const unsigned
|
||||
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, rlen, key, nonce, counter);
|
||||
CRYPTO_chacha_20_keystream(r, n, key, nonce, counter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(key_len == 64)
|
||||
if(n == 64)
|
||||
{
|
||||
for(i = 0; i < 12; i++)
|
||||
// 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: WRONG! Uses only 32 byte of key. However, does not compile with HMAC-SHA512
|
||||
// CRYPTO_chacha_20_keystream(r, rlen, key, nonce, counter);
|
||||
unsigned int length;
|
||||
HMAC(EVP_sha512(), key, n, addr, 16, r, &length);
|
||||
if(length != 64)
|
||||
{
|
||||
nonce[i] = addr[i];
|
||||
fprintf(stderr, "HMAC outputs %d bytes... That should not happen...",length);
|
||||
}
|
||||
uint32_t counter;
|
||||
counter = (((uint32_t)addr[12]) << 24)|(((uint32_t)addr[13]) << 16)|(((uint32_t)addr[14]) << 8)|addr[15];
|
||||
// TODO: WRONG! Uses only 32 byte of key. However, does not compile with HMAC-SHA512
|
||||
CRYPTO_chacha_20_keystream(r, rlen, key, nonce, counter);
|
||||
} else {
|
||||
fprintf(stderr,"prg.c:: Code only supports 32 byte and 64 byte seeds");
|
||||
}
|
||||
|
4
prg.h
4
prg.h
@ -15,8 +15,8 @@ Public domain.
|
||||
void prg(unsigned char *r, unsigned long long rlen, const unsigned char *key, unsigned int key_len);
|
||||
|
||||
/**
|
||||
* Generates rlen output bytes using key_len-byte key and hash address addr and places them in r.
|
||||
* Generates n output bytes using n-byte key and hash address addr and places them in r.
|
||||
*
|
||||
*/
|
||||
void prg_with_counter(unsigned char *r, unsigned long long rlen, const unsigned char *key, unsigned int key_len, const unsigned char addr[16]);
|
||||
void prg_with_counter(unsigned char *r, const unsigned char *key, unsigned int n, const unsigned char addr[16]);
|
||||
#endif
|
||||
|
@ -11,23 +11,26 @@ static void hexdump(unsigned char *a, size_t len)
|
||||
|
||||
int main()
|
||||
{
|
||||
int n = 32;
|
||||
unsigned char seed[32] = {0};
|
||||
unsigned char out[64];
|
||||
// unsigned char seed[64] = {0,0};
|
||||
|
||||
unsigned char out[2*n];
|
||||
unsigned char addr[16] = {2};
|
||||
|
||||
printf("Case 1: All 0\n");
|
||||
prg(out, 64, seed, 32);
|
||||
prg(out, 2*n, seed, n);
|
||||
|
||||
printf("\n");
|
||||
hexdump(out, 64);
|
||||
hexdump(out, 2*n);
|
||||
printf("\n");
|
||||
|
||||
printf("Case 2: key = 1\n");
|
||||
seed[31] = 1;
|
||||
prg_with_counter(out, 64, seed, 32, addr);
|
||||
prg_with_counter(out, seed, n, addr);
|
||||
|
||||
printf("\n");
|
||||
hexdump(out, 64);
|
||||
hexdump(out, n);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -11,24 +11,25 @@ static void hexdump(unsigned char *a, size_t len)
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned char seed[32];
|
||||
unsigned char pub_seed[32];
|
||||
wots_params params;
|
||||
wots_set_params(¶ms, 32, 32, 16);
|
||||
int n = 32;
|
||||
unsigned char seed[n];
|
||||
unsigned char pub_seed[n];
|
||||
wots_params params;
|
||||
wots_set_params(¶ms, n, n, 16);
|
||||
|
||||
int sig_len = params.len*params.n;
|
||||
int sig_len = params.len*params.n;
|
||||
|
||||
unsigned char pk1[sig_len];
|
||||
unsigned char pk2[sig_len];
|
||||
unsigned char sig[sig_len];
|
||||
unsigned char addr[16] = {1,2,3,4};
|
||||
unsigned char pk1[sig_len];
|
||||
unsigned char pk2[sig_len];
|
||||
unsigned char sig[sig_len];
|
||||
unsigned char addr[16] = {1,2,3,4};
|
||||
|
||||
unsigned char msg[32];
|
||||
unsigned char msg[n];
|
||||
int i;
|
||||
|
||||
randombytes(seed, 32);
|
||||
randombytes(pub_seed, 32);
|
||||
randombytes(msg, 32);
|
||||
randombytes(seed, n);
|
||||
randombytes(pub_seed, n);
|
||||
randombytes(msg, n);
|
||||
//randombytes(addr, 16);
|
||||
|
||||
wots_pkgen(pk1, seed, ¶ms, pub_seed, addr);
|
||||
|
@ -7,8 +7,7 @@
|
||||
#define SIGNATURES 50
|
||||
|
||||
|
||||
unsigned char sk[100];
|
||||
unsigned char pk[64];
|
||||
|
||||
unsigned char mi[MLEN];
|
||||
unsigned long long smlen;
|
||||
unsigned long long mlen;
|
||||
@ -17,13 +16,16 @@ int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i;
|
||||
int m = 32;
|
||||
int n = 32;
|
||||
int m = 64;
|
||||
int n = 64;
|
||||
int h = 8;
|
||||
int w = 16;
|
||||
|
||||
unsigned long errors = 0;
|
||||
|
||||
unsigned char sk[3*n+4];
|
||||
unsigned char pk[2*n];
|
||||
|
||||
xmss_params p;
|
||||
xmss_params *params = &p;
|
||||
xmss_set_params(params, m, n, h, w);
|
||||
@ -75,6 +77,7 @@ int main()
|
||||
|
||||
/* Test with modified signature */
|
||||
/* Modified index */
|
||||
sm[signature_length+10] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
printf("%d\n", r+1);
|
||||
|
@ -8,8 +8,7 @@
|
||||
#define SIGNATURES 256
|
||||
|
||||
|
||||
unsigned char sk[100];
|
||||
unsigned char pk[64];
|
||||
|
||||
unsigned char mi[MLEN];
|
||||
unsigned long long smlen;
|
||||
unsigned long long mlen;
|
||||
@ -26,6 +25,9 @@ int main()
|
||||
|
||||
unsigned long errors = 0;
|
||||
|
||||
unsigned char sk[3*n+4];
|
||||
unsigned char pk[2*n];
|
||||
|
||||
xmss_params p;
|
||||
xmss_params *params = &p;
|
||||
xmss_set_params(params, m, n, h, w, k);
|
||||
@ -34,7 +36,7 @@ int main()
|
||||
unsigned char stack[(h+1)*n];
|
||||
unsigned int stackoffset = 0;
|
||||
unsigned char stacklevels[h+1];
|
||||
unsigned char auth[h*n];
|
||||
unsigned char auth[(h)*n];
|
||||
unsigned char keep[(h >> 1)*n];
|
||||
treehash_inst treehash[h-k];
|
||||
unsigned char th_nodes[(h-k)*n];
|
||||
@ -64,7 +66,7 @@ int main()
|
||||
unsigned long idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3];
|
||||
if(idx) printf("\nidx != 0 %lu\n",idx);
|
||||
|
||||
for(i=0;i<(1<<h);i++){
|
||||
for(i=0;i<((1<<h));i++){
|
||||
printf("sign\n");
|
||||
xmss_sign(sk, state, sm, &smlen, mi, MLEN, params);
|
||||
idx = ((unsigned long)sm[0] << 24) | ((unsigned long)sm[1] << 16) | ((unsigned long)sm[2] << 8) | sm[3];
|
||||
@ -93,6 +95,7 @@ int main()
|
||||
|
||||
/* Test with modified signature */
|
||||
/* Modified index */
|
||||
sm[signature_length+10] ^= 1;
|
||||
sm[2] ^= 1;
|
||||
r = xmss_sign_open(mo, &mlen, sm, smlen, pk, params);
|
||||
printf("%d\n", r+1);
|
||||
|
@ -53,7 +53,7 @@ int main()
|
||||
|
||||
if(idx) printf("\nidx != 0: %llu\n",idx);
|
||||
|
||||
for(i=0;i<SIGNATURES;i++){
|
||||
for(i=0;i<(1<<h);i++){
|
||||
printf("sign\n");
|
||||
xmssmt_sign(sk, sm, &smlen, mi, MLEN, params);
|
||||
idx = 0;
|
||||
|
2
wots.c
2
wots.c
@ -45,7 +45,7 @@ void wots_set_params(wots_params *params, int m, int n, int w)
|
||||
*/
|
||||
static void expand_seed(unsigned char *outseeds, const unsigned char *inseed, const wots_params *params)
|
||||
{
|
||||
prg(outseeds, params->keysize, inseed, 32);
|
||||
prg(outseeds, params->keysize, inseed, params->n);
|
||||
}
|
||||
|
||||
/**
|
||||
|
18
xmss.c
18
xmss.c
@ -79,16 +79,18 @@ Public domain.
|
||||
a[12] = (a[12] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Used for pseudorandom keygeneration,
|
||||
* generates the seed for the WOTS keypair at address addr
|
||||
*
|
||||
* takes n byte sk_seed and returns n byte seed using 16 byte address addr.
|
||||
*/
|
||||
static void get_seed(unsigned char seed[32], const unsigned char *sk_seed, unsigned char addr[16])
|
||||
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, unsigned char addr[16])
|
||||
{
|
||||
// Make sure that chain addr, hash addr, and key bit are 0!
|
||||
ZEROISE_OTS_ADDR(addr);
|
||||
// Generate pseudorandom value
|
||||
prg_with_counter(seed, 32, sk_seed, 32, addr);
|
||||
prg_with_counter(seed, sk_seed, n, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,10 +177,10 @@ static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_param
|
||||
*/
|
||||
static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, unsigned char ltree_addr[16], unsigned char ots_addr[16])
|
||||
{
|
||||
unsigned char seed[32];
|
||||
unsigned char seed[params->n];
|
||||
unsigned char pk[params->wots_par.keysize];
|
||||
|
||||
get_seed(seed, sk_seed, ots_addr);
|
||||
get_seed(seed, sk_seed, params->n, ots_addr);
|
||||
wots_pkgen(pk, seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
|
||||
l_tree(leaf, pk, params, pub_seed, ltree_addr);
|
||||
@ -448,7 +450,7 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
SET_OTS_ADDRESS(ots_addr,idx);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
@ -673,7 +675,7 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
SET_OTS_ADDRESS(ots_addr, idx_leaf);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
@ -696,7 +698,7 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
SET_OTS_ADDRESS(ots_addr, idx_leaf);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, root, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
|
20
xmss_fast.c
20
xmss_fast.c
@ -78,16 +78,18 @@ Public domain.
|
||||
a[13] = (v >> 14) & 255;\
|
||||
a[12] = (a[12] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Used for pseudorandom keygeneration,
|
||||
* generates the seed for the WOTS keypair at address addr
|
||||
*
|
||||
* takes n byte sk_seed and returns n byte seed using 16 byte address addr.
|
||||
*/
|
||||
static void get_seed(unsigned char seed[32], const unsigned char *sk_seed, unsigned char addr[16])
|
||||
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, unsigned char addr[16])
|
||||
{
|
||||
// Make sure that chain addr, hash addr, and key bit are 0!
|
||||
ZEROISE_OTS_ADDR(addr);
|
||||
// Generate pseudorandom value
|
||||
prg_with_counter(seed, 32, sk_seed, 32, addr);
|
||||
prg_with_counter(seed, sk_seed, n, addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,10 +202,10 @@ static void l_tree(unsigned char *leaf, unsigned char *wots_pk, const xmss_param
|
||||
*/
|
||||
static void gen_leaf_wots(unsigned char *leaf, const unsigned char *sk_seed, const xmss_params *params, const unsigned char *pub_seed, unsigned char ltree_addr[16], unsigned char ots_addr[16])
|
||||
{
|
||||
unsigned char seed[32];
|
||||
unsigned char seed[params->n];
|
||||
unsigned char pk[params->wots_par.keysize];
|
||||
|
||||
get_seed(seed, sk_seed, ots_addr);
|
||||
get_seed(seed, sk_seed, params->n, ots_addr);
|
||||
wots_pkgen(pk, seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
|
||||
l_tree(leaf, pk, params, pub_seed, ltree_addr);
|
||||
@ -679,7 +681,7 @@ int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsig
|
||||
SET_OTS_ADDRESS(ots_addr,idx);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->wots_par), pub_seed, ots_addr);
|
||||
@ -828,7 +830,7 @@ int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsi
|
||||
// Compute seed for OTS key pair
|
||||
treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr);
|
||||
SET_LAYER_ADDRESS(addr, (i+1));
|
||||
get_seed(ots_seed, sk+params->index_len, addr);
|
||||
get_seed(ots_seed, sk+params->index_len, n, addr);
|
||||
wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, pk, ots_seed, &(params->xmss_par.wots_par), pk+n, addr);
|
||||
}
|
||||
treehash_setup(pk, params->xmss_par.h, 0, states + i, sk+params->index_len, &(params->xmss_par), pk+n, addr);
|
||||
@ -927,7 +929,7 @@ int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs,
|
||||
SET_OTS_ADDRESS(ots_addr, idx_leaf);
|
||||
|
||||
// Compute seed for OTS key pair
|
||||
get_seed(ots_seed, sk_seed, ots_addr);
|
||||
get_seed(ots_seed, sk_seed, n, ots_addr);
|
||||
|
||||
// Compute WOTS signature
|
||||
wots_sign(sig_msg, msg_h, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
@ -974,7 +976,7 @@ int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs,
|
||||
SET_OTS_ADDRESS(ots_addr, (((idx >> ((i+1) * tree_h)) + 1) & ((1 << tree_h)-1)));
|
||||
SET_LAYER_ADDRESS(ots_addr, (i+1));
|
||||
|
||||
get_seed(ots_seed, sk+params->index_len, ots_addr);
|
||||
get_seed(ots_seed, sk+params->index_len, n, ots_addr);
|
||||
wots_sign(wots_sigs + i*params->xmss_par.wots_par.keysize, states[i].stack, ots_seed, &(params->xmss_par.wots_par), pub_seed, ots_addr);
|
||||
|
||||
states[params->d + i].stackoffset = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user