Browse Source

added support for n = m = 64

master
Andreas 9 years ago
parent
commit
9d9b782ff9
11 changed files with 120 additions and 66 deletions
  1. +5
    -5
      hash.c
  2. +54
    -14
      prg.c
  3. +2
    -2
      prg.h
  4. +8
    -5
      test/test_chacha.c
  5. +14
    -13
      test/test_wots.c
  6. +7
    -4
      test/test_xmss.c
  7. +7
    -4
      test/test_xmss_fast.c
  8. +1
    -1
      test/test_xmssmt.c
  9. +1
    -1
      wots.c
  10. +10
    -8
      xmss.c
  11. +11
    -9
      xmss_fast.c

+ 5
- 5
hash.c View File

@@ -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;


+ 54
- 14
prg.c View File

@@ -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");
}


+ 2
- 2
prg.h View File

@@ -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

+ 8
- 5
test/test_chacha.c View File

@@ -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;
}

+ 14
- 13
test/test_wots.c View File

@@ -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(&params, 32, 32, 16);
int n = 32;
unsigned char seed[n];
unsigned char pub_seed[n];
wots_params params;
wots_set_params(&params, 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, &params, pub_seed, addr);


+ 7
- 4
test/test_xmss.c View File

@@ -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);


+ 7
- 4
test/test_xmss_fast.c View File

@@ -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);


+ 1
- 1
test/test_xmssmt.c View File

@@ -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;


+ 1
- 1
wots.c View File

@@ -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);
}

/**


+ 10
- 8
xmss.c View File

@@ -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);


+ 11
- 9
xmss_fast.c View File

@@ -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…
Cancel
Save