handle that most machines are little endian but addresses here are big endian...
This commit is contained in:
parent
2c290d39be
commit
ddddfd9739
41
hash.c
41
hash.c
@ -7,6 +7,7 @@ Public domain.
|
|||||||
|
|
||||||
#include "hash_address.h"
|
#include "hash_address.h"
|
||||||
#include "xmss_commons.h"
|
#include "xmss_commons.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -16,6 +17,17 @@ Public domain.
|
|||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
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){
|
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;
|
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
|
* Implements PRF
|
||||||
*/
|
*/
|
||||||
int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, unsigned int keylen)
|
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, 32, keylen);
|
||||||
return core_hash_SHA2(out, 3, key, keylen, in, inlen, 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 buf[2*n];
|
||||||
unsigned char key[n];
|
unsigned char key[n];
|
||||||
unsigned char bitmask[2*n];
|
unsigned char bitmask[2*n];
|
||||||
|
unsigned char byte_addr[32];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
setKeyAndMask(addr, 0);
|
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
|
// Use MSB order
|
||||||
setKeyAndMask(addr, 1);
|
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);
|
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++) {
|
for (i = 0; i < 2*n; i++) {
|
||||||
buf[i] = in[i] ^ bitmask[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 buf[n];
|
||||||
unsigned char key[n];
|
unsigned char key[n];
|
||||||
unsigned char bitmask[n];
|
unsigned char bitmask[n];
|
||||||
|
unsigned char byte_addr[32];
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
setKeyAndMask(addr, 0);
|
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
|
// Use MSB order
|
||||||
setKeyAndMask(addr, 1);
|
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++) {
|
for (i = 0; i < n; i++) {
|
||||||
buf[i] = in[i] ^ bitmask[i];
|
buf[i] = in[i] ^ bitmask[i];
|
||||||
|
7
hash.h
7
hash.h
@ -8,8 +8,11 @@ Public domain.
|
|||||||
#ifndef HASH_H
|
#ifndef HASH_H
|
||||||
#define HASH_H
|
#define HASH_H
|
||||||
|
|
||||||
int prf(unsigned char *out, const unsigned char *in, const unsigned char *key, int keylen);
|
#define IS_LITTLE_ENDIAN 1
|
||||||
int h_msg(unsigned char *out,const unsigned char *in,unsigned long long inlen, const unsigned char *key, const int keylen, const int n);
|
|
||||||
|
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_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);
|
int hash_f(unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8], const unsigned int n);
|
||||||
|
|
||||||
|
80
prg.c
80
prg.c
@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
prg.c version 20160217
|
|
||||||
Andreas Hülsing
|
|
||||||
Joost Rijneveld
|
|
||||||
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};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
23
prg.h
23
prg.h
@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
prg.h version 20160217
|
|
||||||
Andreas Hülsing
|
|
||||||
Joost Rijneveld
|
|
||||||
Public domain.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PRG_H
|
|
||||||
#define PRG_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
8
xmss.c
8
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])
|
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!
|
// Make sure that chain addr, hash addr, and key bit are 0!
|
||||||
setChainADRS(addr,0);
|
setChainADRS(addr,0);
|
||||||
setHashADRS(addr,0);
|
setHashADRS(addr,0);
|
||||||
setKeyAndMask(addr,0);
|
setKeyAndMask(addr,0);
|
||||||
// Generate pseudorandom value
|
// 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);
|
to_byte(hash_key+2*n, idx, n);
|
||||||
// Then use it for message digest
|
// Then use it for message digest
|
||||||
h_msg(msg_h, msg, msglen, hash_key, 3*n, n);
|
h_msg(msg_h, msg, msglen, hash_key, 3*n, n);
|
||||||
|
|
||||||
// Start collecting signature
|
// Start collecting signature
|
||||||
*sig_msg_len = 0;
|
*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;
|
unsigned long long tmp_sig_len = params->wots_par.keysize+params->h*n;
|
||||||
m_len = sig_msg_len - tmp_sig_len;
|
m_len = sig_msg_len - tmp_sig_len;
|
||||||
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n);
|
h_msg(msg_h, sig_msg + tmp_sig_len, m_len, hash_key, 3*n, n);
|
||||||
|
|
||||||
//-----------------------
|
//-----------------------
|
||||||
// Verify signature
|
// Verify signature
|
||||||
//-----------------------
|
//-----------------------
|
||||||
|
@ -30,12 +30,14 @@ Public domain.
|
|||||||
*/
|
*/
|
||||||
static void get_seed(unsigned char *seed, const unsigned char *sk_seed, int n, uint32_t addr[8])
|
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!
|
// Make sure that chain addr, hash addr, and key bit are 0!
|
||||||
setChainADRS(addr,0);
|
setChainADRS(addr,0);
|
||||||
setHashADRS(addr,0);
|
setHashADRS(addr,0);
|
||||||
setKeyAndMask(addr,0);
|
setKeyAndMask(addr,0);
|
||||||
// Generate pseudorandom value
|
// Generate pseudorandom value
|
||||||
prf(seed, (unsigned char*) addr, sk_seed, n);
|
addr_to_byte(bytes, addr);
|
||||||
|
prf(seed, bytes, sk_seed, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user