SWITCH from v01 to v03
Versions are incompatible due to different address formats and differing message compression!
这个提交包含在:
父节点
59a4846fbd
当前提交
c37b9dcfca
10
Makefile
10
Makefile
@ -11,19 +11,19 @@ test/test_xmssmt
|
||||
test/test_chacha: chacha.c prg.c randombytes.c test/test_chacha.c chacha.h prg.h randombytes.h
|
||||
$(CC) $(CFLAGS) chacha.c prg.c randombytes.c test/test_chacha.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_wots: chacha.c hash.c prg.c randombytes.c wots.c xmss_commons.c test/test_wots.c chacha.h hash.h prg.h randombytes.h wots.h xmss_commons.h
|
||||
test/test_wots: chacha.c hash.c prg.c randombytes.c wots.c xmss_commons.c test/test_wots.c chacha.h hash.h hash_address.h prg.h randombytes.h wots.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) chacha.c hash.c prg.c randombytes.c wots.c xmss_commons.c test/test_wots.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss: chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c chacha.h hash.h prg.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
test/test_xmss: chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c chacha.h hash.h hash_address.h prg.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmss.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmss_fast: chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c chacha.h hash.h prg.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
test/test_xmss_fast: chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c chacha.h hash.h hash_address.h prg.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmss_fast.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt: chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c chacha.h hash.h prg.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
test/test_xmssmt: chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c chacha.h hash.h hash_address.h prg.h randombytes.h wots.h xmss.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) chacha.c hash.c prg.c randombytes.c wots.c xmss.c xmss_commons.c test/test_xmssmt.c -o $@ -lcrypto -lm
|
||||
|
||||
test/test_xmssmt_fast: chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c chacha.h hash.h prg.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
test/test_xmssmt_fast: chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c chacha.h hash.h hash_address.h prg.h randombytes.h wots.h xmss_fast.h xmss_commons.h
|
||||
$(CC) $(CFLAGS) chacha.c hash.c prg.c randombytes.c wots.c xmss_fast.c xmss_commons.c test/test_xmssmt_fast.c -o $@ -lcrypto -lm
|
||||
|
||||
.PHONY: clean
|
||||
|
28
hash.c
28
hash.c
@ -1,10 +1,12 @@
|
||||
/*
|
||||
hash.c version 20151120
|
||||
hash.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
#include "prg.h"
|
||||
#include "hash_address.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
@ -14,12 +16,6 @@ Public domain.
|
||||
#include <openssl/evp.h>
|
||||
|
||||
|
||||
#define SET_KEY_BIT(a, b) (a[15] = (a[15] & 253) | ((b << 1) & 2))
|
||||
#define SET_BLOCK_BIT(a, b) (a[15] = (a[15] & 254) | (b & 1))
|
||||
|
||||
#define WOTS_SELECT_KEY(a) (a[15] = (a[15] & 254) | 1)
|
||||
#define WOTS_SELECT_BLOCK(a) (a[15] = (a[15] & 254) | 0)
|
||||
|
||||
/**
|
||||
* Implements PRF_m
|
||||
*/
|
||||
@ -51,29 +47,27 @@ int prf_m(unsigned char *out, const unsigned char *in, size_t inlen, const unsig
|
||||
int hash_m(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *key, const unsigned int keylen, const unsigned int m)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char buf[inlen + keylen + m];
|
||||
unsigned char buf[inlen + keylen];
|
||||
|
||||
if (keylen != m){
|
||||
fprintf(stderr, "H_m takes m-bit keys, we got m=%d but a keylength of %d.\n", m, keylen);
|
||||
if (keylen != 2*m){
|
||||
fprintf(stderr, "H_m takes 2m-bit keys, we got m=%d but a keylength of %d.\n", m, keylen);
|
||||
return 1;
|
||||
}
|
||||
for (i=0; i < m; i++) {
|
||||
buf[i] = 0x00;
|
||||
}
|
||||
|
||||
for (i=0; i < keylen; i++) {
|
||||
buf[m + i] = key[i];
|
||||
buf[i] = key[i];
|
||||
}
|
||||
for (i=0; i < inlen; i++) {
|
||||
buf[m + keylen + i] = in[i];
|
||||
buf[keylen + i] = in[i];
|
||||
}
|
||||
|
||||
if (m == 32) {
|
||||
SHA256(buf, inlen + keylen + m, out);
|
||||
SHA256(buf, inlen + keylen, out);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
if (m == 64) {
|
||||
SHA512(buf, inlen + keylen + m, out);
|
||||
SHA512(buf, inlen + keylen, out);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
3
hash.h
3
hash.h
@ -1,6 +1,7 @@
|
||||
/*
|
||||
hash.h version 20151120
|
||||
hash.h version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
83
hash_address.h
普通文件
83
hash_address.h
普通文件
@ -0,0 +1,83 @@
|
||||
/*
|
||||
hash.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Used in hash.c
|
||||
*/
|
||||
#define SET_BLOCK_BIT(a, b) (a[15] = (a[15] & 1) | ((b << 1) & 2))
|
||||
#define SET_KEY_BIT(a, b) (a[15] = (a[15] & 2) | (b & 1))
|
||||
|
||||
#define WOTS_SELECT_KEY(a) (a[15] = 1)
|
||||
#define WOTS_SELECT_BLOCK(a) (a[15] = 0)
|
||||
/*
|
||||
* Used in wots.c
|
||||
*/
|
||||
#define SET_HASH_ADDRESS(a, v) {\
|
||||
a[14] = (v & 255);}
|
||||
|
||||
#define SET_CHAIN_ADDRESS(a, v) {\
|
||||
a[13] = (v & 255);\
|
||||
a[12] = ((v >> 8) & 255);}
|
||||
|
||||
/*
|
||||
* Used in xmss_fast.c and xmss.c
|
||||
*/
|
||||
#define SET_LAYER_ADDRESS(a, v) {\
|
||||
a[0] = (v & 255);}
|
||||
|
||||
#define SET_TREE_ADDRESS(a, v) {\
|
||||
a[5] = (v & 255);\
|
||||
a[4] = (v >> 8) & 255;\
|
||||
a[3] = (v >> 16) & 255;\
|
||||
a[2] = (v >> 24) & 255;\
|
||||
a[1] = (v >> 32) & 255;}
|
||||
|
||||
#define SET_OTS_BIT(a, b) {\
|
||||
a[6] = (b & 1);\
|
||||
a[7] = 0;\
|
||||
a[8] = 0;}
|
||||
|
||||
#define SET_OTS_ADDRESS(a, v) {\
|
||||
a[11] = (v & 255);\
|
||||
a[10] = (v >> 8) & 255;\
|
||||
a[9] = (v >> 16) & 255;}
|
||||
|
||||
#define ZEROISE_OTS_ADDR(a) {\
|
||||
a[12] = 0;\
|
||||
a[13] = 0;\
|
||||
a[14] = 0;\
|
||||
a[15] = 0;}
|
||||
|
||||
#define SET_LTREE_BIT(a, b) {\
|
||||
a[7] = (a[7] & 0) | (b & 1);}
|
||||
|
||||
#define SET_LTREE_ADDRESS(a, v) {\
|
||||
a[10] = v & 255;\
|
||||
a[9] = (v >> 8) & 255;\
|
||||
a[8] = (v >> 16) & 255;}
|
||||
|
||||
#define SET_LTREE_TREE_HEIGHT(a, v) {\
|
||||
a[11] = (v & 255);}
|
||||
|
||||
#define SET_LTREE_TREE_INDEX(a, v) {\
|
||||
a[14] = (v & 255);\
|
||||
a[13] = (v >> 8) & 255;\
|
||||
a[12] = (v >> 16) & 3;}
|
||||
|
||||
#define SET_NODE_PADDING(a) {\
|
||||
a[8] = 0;\
|
||||
a[9] = 0;\
|
||||
a[10] = 0;}
|
||||
|
||||
#define SET_NODE_TREE_HEIGHT(a, v) {\
|
||||
a[11] = (v & 255);}
|
||||
|
||||
#define SET_NODE_TREE_INDEX(a, v) {\
|
||||
a[14] = v & 255;\
|
||||
a[13] = (v >> 8) & 255;\
|
||||
a[12] = (v >> 16) & 255;}
|
||||
|
3
prg.c
3
prg.c
@ -1,6 +1,7 @@
|
||||
/*
|
||||
prg.c version 20151120
|
||||
prg.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
#include "chacha.h"
|
||||
|
3
prg.h
3
prg.h
@ -1,6 +1,7 @@
|
||||
/*
|
||||
prg.h version 20151120
|
||||
prg.h version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
@ -14,8 +14,8 @@ int main()
|
||||
{
|
||||
int r;
|
||||
unsigned long long i;
|
||||
unsigned int m = 64;
|
||||
unsigned int n = 64;
|
||||
unsigned int m = 32;
|
||||
unsigned int n = 32;
|
||||
unsigned int h = 8;
|
||||
unsigned int w = 16;
|
||||
|
||||
|
17
wots.c
17
wots.c
@ -1,6 +1,7 @@
|
||||
/*
|
||||
wots.c version 20151120
|
||||
wots.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
@ -11,19 +12,7 @@ Public domain.
|
||||
#include "prg.h"
|
||||
#include "hash.h"
|
||||
#include "wots.h"
|
||||
|
||||
/**
|
||||
* Macros used to manipulate the respective fields
|
||||
* in the 16byte hash address
|
||||
*/
|
||||
#define SET_HASH_ADDRESS(a, v) {\
|
||||
a[15] = (a[15] & 1) | ((v << 1) & 254);\
|
||||
a[14] = (a[14] & 254) | ((v >> 7) & 1);}
|
||||
|
||||
#define SET_CHAIN_ADDRESS(a, v) {\
|
||||
a[14] = (a[14] & 1) | ((v << 1) & 254);\
|
||||
a[13] = (v >> 7) & 255;\
|
||||
a[12] = (a[12] & 254) | ((v >> 15) & 1);}
|
||||
#include "hash_address.h"
|
||||
|
||||
|
||||
void wots_set_params(wots_params *params, int m, int n, int w)
|
||||
|
3
wots.h
3
wots.h
@ -1,6 +1,7 @@
|
||||
/*
|
||||
wots.h version 20151120
|
||||
wots.h version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
130
xmss.c
130
xmss.c
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss.c version 20151120
|
||||
xmss.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
@ -15,69 +16,11 @@ Public domain.
|
||||
#include "hash.h"
|
||||
#include "prg.h"
|
||||
#include "xmss_commons.h"
|
||||
#include "hash_address.h"
|
||||
|
||||
// For testing
|
||||
#include "stdio.h"
|
||||
|
||||
/**
|
||||
* Macros used to manipulate the respective fields
|
||||
* in the 16byte hash address
|
||||
*/
|
||||
#define SET_LAYER_ADDRESS(a, v) {\
|
||||
a[6] = (a[6] & 3) | ((v << 2) & 252);\
|
||||
a[5] = (a[5] & 252) | ((v >> 6) & 3);}
|
||||
|
||||
#define SET_TREE_ADDRESS(a, v) {\
|
||||
a[9] = (a[9] & 3) | ((v << 2) & 252);\
|
||||
a[8] = (v >> 6) & 255;\
|
||||
a[7] = (v >> 14) & 255;\
|
||||
a[6] = (a[6] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
#define SET_OTS_BIT(a, b) {\
|
||||
a[9] = (a[9] & 253) | ((b << 1) & 2);}
|
||||
|
||||
#define SET_OTS_ADDRESS(a, v) {\
|
||||
a[12] = (a[12] & 1) | ((v << 1) & 254);\
|
||||
a[11] = (v >> 7) & 255;\
|
||||
a[10] = (v >> 15) & 255;\
|
||||
a[9] = (a[9] & 254) | ((v >> 23) & 1);}
|
||||
|
||||
#define ZEROISE_OTS_ADDR(a) {\
|
||||
a[12] = (a[12] & 254);\
|
||||
a[13] = 0;\
|
||||
a[14] = 0;\
|
||||
a[15] = 0;}
|
||||
|
||||
#define SET_LTREE_BIT(a, b) {\
|
||||
a[9] = (a[9] & 254) | (b & 1);}
|
||||
|
||||
#define SET_LTREE_ADDRESS(a, v) {\
|
||||
a[12] = v & 255;\
|
||||
a[11] = (v >> 8) & 255;\
|
||||
a[10] = (v >> 16) & 255;}
|
||||
|
||||
#define SET_LTREE_TREE_HEIGHT(a, v) {\
|
||||
a[13] = (a[13] & 3) | ((v << 2) & 252);}
|
||||
|
||||
#define SET_LTREE_TREE_INDEX(a, v) {\
|
||||
a[15] = (a[15] & 3) | ((v << 2) & 252);\
|
||||
a[14] = (v >> 6) & 255;\
|
||||
a[13] = (a[13] & 252) | ((v >> 14) & 3);}
|
||||
|
||||
#define SET_NODE_PADDING(a) {\
|
||||
a[10] = 0;\
|
||||
a[11] = a[11] & 3;}
|
||||
|
||||
#define SET_NODE_TREE_HEIGHT(a, v) {\
|
||||
a[12] = (a[12] & 3) | ((v << 2) & 252);\
|
||||
a[11] = (a[11] & 252) | ((v >> 6) & 3);}
|
||||
|
||||
#define SET_NODE_TREE_INDEX(a, v) {\
|
||||
a[15] = (a[15] & 3) | ((v << 2) & 252);\
|
||||
a[14] = (v >> 6) & 255;\
|
||||
a[13] = (v >> 14) & 255;\
|
||||
a[12] = (a[12] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
|
||||
/**
|
||||
* Used for pseudorandom keygeneration,
|
||||
@ -382,7 +325,16 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
memcpy(sk_prf, sk+4+n, m);
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, sk+4+n+m, n);
|
||||
|
||||
|
||||
unsigned char hash_key[2*m];
|
||||
unsigned long long i;
|
||||
for(i = 0; i < m-4; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for(i = 0; i < 4; i++){
|
||||
hash_key[i+m-4] = sk[i];
|
||||
}
|
||||
|
||||
// Update SK
|
||||
sk[0] = ((idx + 1) >> 24) & 255;
|
||||
sk[1] = ((idx + 1) >> 16) & 255;
|
||||
@ -392,7 +344,6 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
// -- A productive implementation should use a file handle instead and write the updated secret key at this point!
|
||||
|
||||
// Init working params
|
||||
unsigned long long i;
|
||||
unsigned char R[m];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char root[n];
|
||||
@ -404,10 +355,12 @@ int xmss_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *sig
|
||||
// ---------------------------------
|
||||
|
||||
// Message Hash:
|
||||
// First compute pseudorandom key
|
||||
// First compute pseudorandom value
|
||||
prf_m(R, msg, msglen, sk_prf, m);
|
||||
// Generate hash key (idx || R)
|
||||
memcpy(hash_key+m, R, m);
|
||||
// Then use it for message digest
|
||||
hash_m(msg_h, msg, msglen, R, m, m);
|
||||
hash_m(msg_h, msg, msglen, hash_key, 2*m, m);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
@ -472,6 +425,7 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char hash_key[2*m];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
@ -494,16 +448,19 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
// Extract index
|
||||
idx = ((unsigned long)sig_msg[0] << 24) | ((unsigned long)sig_msg[1] << 16) | ((unsigned long)sig_msg[2] << 8) | sig_msg[3];
|
||||
printf("verify:: idx = %lu\n", idx);
|
||||
sig_msg += 4;
|
||||
sig_msg_len -= 4;
|
||||
for(i = 0; i < m-4; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for(i = 0; i < m+4; i++){
|
||||
hash_key[i+m-4] = sig_msg[i];
|
||||
}
|
||||
sig_msg += (m+4);
|
||||
sig_msg_len -= (m+4);
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = m+params->wots_par.keysize+params->h*n;
|
||||
// hash message
|
||||
unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n;
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, sig_msg, m, m);
|
||||
|
||||
sig_msg += m;
|
||||
sig_msg_len -= m;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 2*m, m);
|
||||
|
||||
//-----------------------
|
||||
// Verify signature
|
||||
@ -596,15 +553,20 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
unsigned char pub_seed[n];
|
||||
// Init working params
|
||||
unsigned char R[m];
|
||||
unsigned char hash_key[2*m];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char root[n];
|
||||
unsigned char ots_seed[n];
|
||||
unsigned char ots_addr[16] = {0, 0, 0, 0};
|
||||
|
||||
// Extract SK
|
||||
for(i = 0; i < m-idx_len; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
unsigned long long idx = 0;
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sk[i]) << 8*(idx_len - 1 - i);
|
||||
hash_key[m-idx_len+i] = sk[i];
|
||||
}
|
||||
|
||||
memcpy(sk_seed, sk+idx_len, n);
|
||||
@ -626,8 +588,12 @@ int xmssmt_sign(unsigned char *sk, unsigned char *sig_msg, unsigned long long *s
|
||||
// Message Hash:
|
||||
// First compute pseudorandom key
|
||||
prf_m(R, msg, msglen, sk_prf, m);
|
||||
|
||||
// Generate hash key (idx || R)
|
||||
memcpy(hash_key+m, R, m);
|
||||
|
||||
// Then use it for message digest
|
||||
hash_m(msg_h, msg, msglen, R, m, m);
|
||||
hash_m(msg_h, msg, msglen, hash_key, 2*m, m);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
@ -726,6 +692,7 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char hash_key[2*m];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
@ -736,20 +703,29 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
unsigned char node_addr[16];
|
||||
|
||||
// Extract index
|
||||
for(i = 0; i < m-idx_len; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sig_msg[i]) << (8*(idx_len - 1 - i));
|
||||
hash_key[m-idx_len+i] = sig_msg[i];
|
||||
}
|
||||
printf("verify:: idx = %llu\n", idx);
|
||||
sig_msg += idx_len;
|
||||
sig_msg_len -= idx_len;
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = m+ (params->d * params->xmss_par.wots_par.keysize) + (params->h * n);
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, sig_msg, m, m);
|
||||
for(i = 0; i < m; i++){
|
||||
hash_key[m+i] = sig_msg[i];
|
||||
}
|
||||
|
||||
sig_msg += m;
|
||||
sig_msg_len -= m;
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = (params->d * params->xmss_par.wots_par.keysize) + (params->h * n);
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 2*m, m);
|
||||
|
||||
|
||||
//-----------------------
|
||||
// Verify signature
|
||||
|
3
xmss.h
3
xmss.h
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss.h version 20151120
|
||||
xmss.h version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss_commons.c version 20151120
|
||||
xmss_commons.c 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss_commons.h version 20151120
|
||||
xmss_commons.h 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
#ifndef XMSS_COMMONS_H
|
||||
|
133
xmss_fast.c
133
xmss_fast.c
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss_fast.c version 20151120
|
||||
Andreas Hülsing and Joost Rijneveld
|
||||
xmss_fast.c version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
@ -15,68 +16,11 @@ Public domain.
|
||||
#include "hash.h"
|
||||
#include "prg.h"
|
||||
#include "xmss_commons.h"
|
||||
|
||||
#include "hash_address.h"
|
||||
// For testing
|
||||
#include "stdio.h"
|
||||
|
||||
/**
|
||||
* Macros used to manipulate the respective fields
|
||||
* in the 16byte hash address
|
||||
*/
|
||||
#define SET_LAYER_ADDRESS(a, v) {\
|
||||
a[6] = (a[6] & 3) | ((v << 2) & 252);\
|
||||
a[5] = (a[5] & 252) | ((v >> 6) & 3);}
|
||||
|
||||
#define SET_TREE_ADDRESS(a, v) {\
|
||||
a[9] = (a[9] & 3) | ((v << 2) & 252);\
|
||||
a[8] = (v >> 6) & 255;\
|
||||
a[7] = (v >> 14) & 255;\
|
||||
a[6] = (a[6] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
#define SET_OTS_BIT(a, b) {\
|
||||
a[9] = (a[9] & 253) | ((b << 1) & 2);}
|
||||
|
||||
#define SET_OTS_ADDRESS(a, v) {\
|
||||
a[12] = (a[12] & 1) | ((v << 1) & 254);\
|
||||
a[11] = (v >> 7) & 255;\
|
||||
a[10] = (v >> 15) & 255;\
|
||||
a[9] = (a[9] & 254) | ((v >> 23) & 1);}
|
||||
|
||||
#define ZEROISE_OTS_ADDR(a) {\
|
||||
a[12] = (a[12] & 254);\
|
||||
a[13] = 0;\
|
||||
a[14] = 0;\
|
||||
a[15] = 0;}
|
||||
|
||||
#define SET_LTREE_BIT(a, b) {\
|
||||
a[9] = (a[9] & 254) | (b & 1);}
|
||||
|
||||
#define SET_LTREE_ADDRESS(a, v) {\
|
||||
a[12] = v & 255;\
|
||||
a[11] = (v >> 8) & 255;\
|
||||
a[10] = (v >> 16) & 255;}
|
||||
|
||||
#define SET_LTREE_TREE_HEIGHT(a, v) {\
|
||||
a[13] = (a[13] & 3) | ((v << 2) & 252);}
|
||||
|
||||
#define SET_LTREE_TREE_INDEX(a, v) {\
|
||||
a[15] = (a[15] & 3) | ((v << 2) & 252);\
|
||||
a[14] = (v >> 6) & 255;\
|
||||
a[13] = (a[13] & 252) | ((v >> 14) & 3);}
|
||||
|
||||
#define SET_NODE_PADDING(a) {\
|
||||
a[10] = 0;\
|
||||
a[11] = a[11] & 3;}
|
||||
|
||||
#define SET_NODE_TREE_HEIGHT(a, v) {\
|
||||
a[12] = (a[12] & 3) | ((v << 2) & 252);\
|
||||
a[11] = (a[11] & 252) | ((v >> 6) & 3);}
|
||||
|
||||
#define SET_NODE_TREE_INDEX(a, v) {\
|
||||
a[15] = (a[15] & 3) | ((v << 2) & 252);\
|
||||
a[14] = (v >> 6) & 255;\
|
||||
a[13] = (v >> 14) & 255;\
|
||||
a[12] = (a[12] & 252) | ((v >> 22) & 3);}
|
||||
|
||||
/**
|
||||
* Used for pseudorandom keygeneration,
|
||||
@ -614,6 +558,16 @@ int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsig
|
||||
memcpy(sk_prf, sk+4+n, m);
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, sk+4+n+m, n);
|
||||
|
||||
unsigned char hash_key[2*m];
|
||||
unsigned long long i;
|
||||
for(i = 0; i < m-4; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for(i = 0; i < 4; i++){
|
||||
hash_key[i+m-4] = sk[i];
|
||||
}
|
||||
|
||||
|
||||
// Update SK
|
||||
sk[0] = ((idx + 1) >> 24) & 255;
|
||||
@ -624,7 +578,6 @@ int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsig
|
||||
// -- A productive implementation should use a file handle instead and write the updated secret key at this point!
|
||||
|
||||
// Init working params
|
||||
unsigned long long i;
|
||||
unsigned char R[m];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char ots_seed[n];
|
||||
@ -637,8 +590,10 @@ int xmss_sign(unsigned char *sk, bds_state *state, unsigned char *sig_msg, unsig
|
||||
// Message Hash:
|
||||
// First compute pseudorandom key
|
||||
prf_m(R, msg, msglen, sk_prf, m);
|
||||
// Generate hash key (idx || R)
|
||||
memcpy(hash_key+m, R, m);
|
||||
// Then use it for message digest
|
||||
hash_m(msg_h, msg, msglen, R, m, m);
|
||||
hash_m(msg_h, msg, msglen, hash_key, 2*m, m);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
@ -710,6 +665,7 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char hash_key[2*m];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
@ -732,16 +688,19 @@ int xmss_sign_open(unsigned char *msg, unsigned long long *msglen, const unsigne
|
||||
// Extract index
|
||||
idx = ((unsigned long)sig_msg[0] << 24) | ((unsigned long)sig_msg[1] << 16) | ((unsigned long)sig_msg[2] << 8) | sig_msg[3];
|
||||
printf("verify:: idx = %lu\n", idx);
|
||||
sig_msg += 4;
|
||||
sig_msg_len -= 4;
|
||||
for(i = 0; i < m-4; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for(i = 0; i < m+4; i++){
|
||||
hash_key[i+m-4] = sig_msg[i];
|
||||
}
|
||||
sig_msg += (m+4);
|
||||
sig_msg_len -= (m+4);
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = m+params->wots_par.keysize+params->h*n;
|
||||
// hash message
|
||||
unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n;
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, sig_msg, m, m);
|
||||
|
||||
sig_msg += m;
|
||||
sig_msg_len -= m;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 2*m, m);
|
||||
|
||||
//-----------------------
|
||||
// Verify signature
|
||||
@ -807,7 +766,7 @@ int xmssmt_keypair(unsigned char *pk, unsigned char *sk, bds_state *states, unsi
|
||||
// Set address to point on the single tree on layer d-1
|
||||
unsigned char addr[16] = {0, 0, 0, 0};
|
||||
SET_OTS_BIT(addr, 1);
|
||||
SET_TREE_ADDRESS(addr, 0);
|
||||
SET_TREE_ADDRESS(addr, (unsigned long long)0);
|
||||
SET_OTS_ADDRESS(addr, 0);
|
||||
SET_LAYER_ADDRESS(addr, 0);
|
||||
// Set up state and compute wots signatures for all but topmost tree root
|
||||
@ -849,15 +808,20 @@ int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs,
|
||||
// Init working params
|
||||
unsigned char R[m];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char hash_key[2*m];
|
||||
unsigned char ots_seed[n];
|
||||
unsigned char addr[16] = {0, 0, 0, 0};
|
||||
unsigned char ots_addr[16] = {0, 0, 0, 0};
|
||||
bds_state tmp;
|
||||
|
||||
// Extract SK
|
||||
for(i = 0; i < m-idx_len; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
unsigned long long idx = 0;
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sk[i]) << 8*(idx_len - 1 - i);
|
||||
hash_key[m-idx_len+i] = sk[i];
|
||||
}
|
||||
|
||||
memcpy(sk_seed, sk+idx_len, n);
|
||||
@ -879,8 +843,12 @@ int xmssmt_sign(unsigned char *sk, bds_state *states, unsigned char *wots_sigs,
|
||||
// Message Hash:
|
||||
// First compute pseudorandom key
|
||||
prf_m(R, msg, msglen, sk_prf, m);
|
||||
|
||||
// Generate hash key (idx || R)
|
||||
memcpy(hash_key+m, R, m);
|
||||
|
||||
// Then use it for message digest
|
||||
hash_m(msg_h, msg, msglen, R, m, m);
|
||||
hash_m(msg_h, msg, msglen, hash_key, 2*m, m);
|
||||
|
||||
// Start collecting signature
|
||||
*sig_msg_len = 0;
|
||||
@ -1020,6 +988,7 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
unsigned char pkhash[n];
|
||||
unsigned char root[n];
|
||||
unsigned char msg_h[m];
|
||||
unsigned char hash_key[2*m];
|
||||
|
||||
unsigned char pub_seed[n];
|
||||
memcpy(pub_seed, pk+n, n);
|
||||
@ -1030,21 +999,31 @@ int xmssmt_sign_open(unsigned char *msg, unsigned long long *msglen, const unsig
|
||||
unsigned char node_addr[16];
|
||||
|
||||
// Extract index
|
||||
for(i = 0; i < m-idx_len; i++){
|
||||
hash_key[i] = 0;
|
||||
}
|
||||
for (i = 0; i < idx_len; i++) {
|
||||
idx |= ((unsigned long long)sig_msg[i]) << (8*(idx_len - 1 - i));
|
||||
hash_key[m-idx_len+i] = sig_msg[i];
|
||||
}
|
||||
printf("verify:: idx = %llu\n", idx);
|
||||
sig_msg += idx_len;
|
||||
sig_msg_len -= idx_len;
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = m+ (params->d * params->xmss_par.wots_par.keysize) + (params->h * n);
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, sig_msg, m, m);
|
||||
|
||||
for(i = 0; i < m; i++){
|
||||
hash_key[m+i] = sig_msg[i];
|
||||
}
|
||||
|
||||
sig_msg += m;
|
||||
sig_msg_len -= m;
|
||||
|
||||
|
||||
// hash message (recall, R is now on pole position at sig_msg
|
||||
unsigned long long tmp_sig_len = (params->d * params->xmss_par.wots_par.keysize) + (params->h * n);
|
||||
m_len = sig_msg_len - tmp_sig_len;
|
||||
hash_m(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 2*m, m);
|
||||
|
||||
|
||||
//-----------------------
|
||||
// Verify signature
|
||||
//-----------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
xmss_fast.h version 20151120
|
||||
Andreas Hülsing and Joost Rijneveld
|
||||
xmss_fast.h version 20160210
|
||||
Andreas Hülsing
|
||||
Joost Rijneveld
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
|
正在加载...
在新工单中引用
屏蔽一个用户