picnic3L1: needed updates
This commit is contained in:
부모
67fb9cf574
커밋
20cc113042
@ -144,6 +144,7 @@ add_subdirectory(src/sign/sphincs/sphincs-sha256-256s-robust/clean)
|
||||
add_subdirectory(src/sign/sphincs/sphincs-sha256-128s-robust/clean)
|
||||
add_subdirectory(src/sign/sphincs/sphincs-sha256-128f-simple/clean)
|
||||
add_subdirectory(src/sign/sphincs/sphincs-sha256-192f-robust/clean)
|
||||
add_subdirectory(src/sign/picnic/picnic3l1/clean)
|
||||
|
||||
add_subdirectory(src/kem/kyber/kyber512/clean)
|
||||
add_subdirectory(src/kem/kyber/kyber768/clean)
|
||||
|
@ -41,7 +41,8 @@ extern "C" {
|
||||
_(SPHINCSSHA256256SROBUST) \
|
||||
_(SPHINCSSHA256128SROBUST) \
|
||||
_(SPHINCSSHA256128FSIMPLE) \
|
||||
_(SPHINCSSHA256192FROBUST)
|
||||
_(SPHINCSSHA256192FROBUST) \
|
||||
_(PICNIC3L1)
|
||||
|
||||
// defines supported kem algorithm list
|
||||
#define PQC_SUPPORTED_KEMS(_)\
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "sign/dilithium/dilithium3/avx2/api.h"
|
||||
#include "sign/dilithium/dilithium5/clean/api.h"
|
||||
#include "sign/dilithium/dilithium5/avx2/api.h"
|
||||
#include "sign/picnic/picnic3l1/clean/api.h"
|
||||
#include "kem/ntru/ntruhps4096821/clean/api.h"
|
||||
#include "kem/ntru/ntruhps4096821/avx2/api.h"
|
||||
#include "kem/ntru/ntruhps2048509/clean/api.h"
|
||||
|
@ -1,277 +0,0 @@
|
||||
|
||||
//
|
||||
// PQCgenKAT_sign.c
|
||||
//
|
||||
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "rng.h"
|
||||
#include "api.h"
|
||||
|
||||
#define MAX_MARKER_LEN 50
|
||||
|
||||
#define KAT_SUCCESS 0
|
||||
#define KAT_FILE_OPEN_ERROR -1
|
||||
#define KAT_DATA_ERROR -3
|
||||
#define KAT_CRYPTO_FAILURE -4
|
||||
|
||||
int FindMarker(FILE *infile, const char *marker);
|
||||
int ReadHex(FILE *infile, unsigned char *A, int Length, char *str);
|
||||
void fprintBstr(FILE *fp, char *S, unsigned char *A, unsigned long long L);
|
||||
|
||||
char AlgName[] = "My Alg Name";
|
||||
static const char* l1 = "L1";
|
||||
static const char* l3 = "L3";
|
||||
static const char* l5 = "L5";
|
||||
static const char* unknown = "UNKNOWN_PARAM_SET";
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
char fn_req[64], fn_rsp[64];
|
||||
FILE *fp_req, *fp_rsp;
|
||||
unsigned char seed[48];
|
||||
unsigned char msg[3300];
|
||||
unsigned char entropy_input[48];
|
||||
unsigned char *m, *sm, *m1;
|
||||
unsigned long long mlen, smlen, mlen1;
|
||||
int count;
|
||||
int done;
|
||||
unsigned char pk[CRYPTO_PUBLICKEYBYTES], sk[CRYPTO_SECRETKEYBYTES];
|
||||
int ret_val;
|
||||
const char* suffix;
|
||||
|
||||
|
||||
switch(((CRYPTO_PUBLICKEYBYTES - 1)/2)*8) {
|
||||
case 128:
|
||||
case 136: // 129-bit keys, rounded to next byte
|
||||
suffix = l1;
|
||||
break;
|
||||
case 192:
|
||||
suffix = l3;
|
||||
break;
|
||||
case 256:
|
||||
suffix = l5;
|
||||
break;
|
||||
default:
|
||||
suffix = unknown;
|
||||
break;
|
||||
}
|
||||
|
||||
// Create the REQUEST file
|
||||
sprintf(fn_req, "PQCsignKAT_%s.req", suffix);
|
||||
if ( (fp_req = fopen(fn_req, "w")) == NULL ) {
|
||||
printf("Couldn't open <%s> for write\n", fn_req);
|
||||
return KAT_FILE_OPEN_ERROR;
|
||||
}
|
||||
sprintf(fn_rsp, "PQCsignKAT_%s.rsp", suffix);
|
||||
if ( (fp_rsp = fopen(fn_rsp, "w")) == NULL ) {
|
||||
printf("Couldn't open <%s> for write\n", fn_rsp);
|
||||
return KAT_FILE_OPEN_ERROR;
|
||||
}
|
||||
|
||||
for (int i=0; i<48; i++)
|
||||
entropy_input[i] = i;
|
||||
|
||||
NIST_randombytes_init(entropy_input, NULL, 256);
|
||||
for (int i=0; i<100; i++) {
|
||||
fprintf(fp_req, "count = %d\n", i);
|
||||
NIST_randombytes(seed, 48);
|
||||
fprintBstr(fp_req, "seed = ", seed, 48);
|
||||
mlen = 33*(i+1);
|
||||
fprintf(fp_req, "mlen = %llu\n", mlen);
|
||||
NIST_randombytes(msg, mlen);
|
||||
fprintBstr(fp_req, "msg = ", msg, mlen);
|
||||
fprintf(fp_req, "pk =\n");
|
||||
fprintf(fp_req, "sk =\n");
|
||||
fprintf(fp_req, "smlen =\n");
|
||||
fprintf(fp_req, "sm =\n\n");
|
||||
}
|
||||
fclose(fp_req);
|
||||
|
||||
//Create the RESPONSE file based on what's in the REQUEST file
|
||||
if ( (fp_req = fopen(fn_req, "r")) == NULL ) {
|
||||
printf("Couldn't open <%s> for read\n", fn_req);
|
||||
return KAT_FILE_OPEN_ERROR;
|
||||
}
|
||||
|
||||
fprintf(fp_rsp, "# %s\n\n", CRYPTO_ALGNAME);
|
||||
done = 0;
|
||||
do {
|
||||
if ( FindMarker(fp_req, "count = ") )
|
||||
fscanf(fp_req, "%d", &count);
|
||||
else {
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
fprintf(fp_rsp, "count = %d\n", count);
|
||||
|
||||
if ( !ReadHex(fp_req, seed, 48, "seed = ") ) {
|
||||
printf("ERROR: unable to read 'seed' from <%s>\n", fn_req);
|
||||
return KAT_DATA_ERROR;
|
||||
}
|
||||
fprintBstr(fp_rsp, "seed = ", seed, 48);
|
||||
|
||||
NIST_randombytes_init(seed, NULL, 256);
|
||||
|
||||
if ( FindMarker(fp_req, "mlen = ") )
|
||||
fscanf(fp_req, "%llu", &mlen);
|
||||
else {
|
||||
printf("ERROR: unable to read 'mlen' from <%s>\n", fn_req);
|
||||
return KAT_DATA_ERROR;
|
||||
}
|
||||
fprintf(fp_rsp, "mlen = %llu\n", mlen);
|
||||
|
||||
m = (unsigned char *)calloc(mlen, sizeof(unsigned char));
|
||||
m1 = (unsigned char *)calloc(mlen, sizeof(unsigned char));
|
||||
sm = (unsigned char *)calloc(mlen+CRYPTO_BYTES, sizeof(unsigned char));
|
||||
|
||||
if ( !ReadHex(fp_req, m, (int)mlen, "msg = ") ) {
|
||||
printf("ERROR: unable to read 'msg' from <%s>\n", fn_req);
|
||||
return KAT_DATA_ERROR;
|
||||
}
|
||||
fprintBstr(fp_rsp, "msg = ", m, mlen);
|
||||
|
||||
// Generate the public/private keypair
|
||||
if ( (ret_val = crypto_sign_keypair(pk, sk)) != 0) {
|
||||
printf("crypto_sign_keypair returned <%d>\n", ret_val);
|
||||
return KAT_CRYPTO_FAILURE;
|
||||
}
|
||||
fprintBstr(fp_rsp, "pk = ", pk, CRYPTO_PUBLICKEYBYTES);
|
||||
fprintBstr(fp_rsp, "sk = ", sk, CRYPTO_SECRETKEYBYTES);
|
||||
|
||||
if ( (ret_val = crypto_sign(sm, &smlen, m, mlen, sk)) != 0) {
|
||||
printf("crypto_sign returned <%d>\n", ret_val);
|
||||
return KAT_CRYPTO_FAILURE;
|
||||
}
|
||||
fprintf(fp_rsp, "smlen = %llu\n", smlen);
|
||||
fprintBstr(fp_rsp, "sm = ", sm, smlen);
|
||||
fprintf(fp_rsp, "\n");
|
||||
|
||||
if ( (ret_val = crypto_sign_open(m1, &mlen1, sm, smlen, pk)) != 0) {
|
||||
printf("crypto_sign_open returned <%d>\n", ret_val);
|
||||
return KAT_CRYPTO_FAILURE;
|
||||
}
|
||||
|
||||
if ( mlen != mlen1 ) {
|
||||
printf("crypto_sign_open returned bad 'mlen': Got <%llu>, expected <%llu>\n", mlen1, mlen);
|
||||
return KAT_CRYPTO_FAILURE;
|
||||
}
|
||||
|
||||
if ( memcmp(m, m1, mlen) ) {
|
||||
printf("crypto_sign_open returned bad 'm' value\n");
|
||||
return KAT_CRYPTO_FAILURE;
|
||||
}
|
||||
|
||||
free(m);
|
||||
free(m1);
|
||||
free(sm);
|
||||
|
||||
} while ( !done );
|
||||
|
||||
fclose(fp_req);
|
||||
fclose(fp_rsp);
|
||||
|
||||
return KAT_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
|
||||
//
|
||||
int
|
||||
FindMarker(FILE *infile, const char *marker)
|
||||
{
|
||||
char line[MAX_MARKER_LEN];
|
||||
int i, len;
|
||||
|
||||
len = (int)strlen(marker);
|
||||
if ( len > MAX_MARKER_LEN-1 )
|
||||
len = MAX_MARKER_LEN-1;
|
||||
|
||||
for ( i=0; i<len; i++ )
|
||||
if ( (line[i] = fgetc(infile)) == EOF )
|
||||
return 0;
|
||||
line[len] = '\0';
|
||||
|
||||
while ( 1 ) {
|
||||
if ( !strncmp(line, marker, len) )
|
||||
return 1;
|
||||
|
||||
for ( i=0; i<len-1; i++ )
|
||||
line[i] = line[i+1];
|
||||
if ( (line[len-1] = fgetc(infile)) == EOF )
|
||||
return 0;
|
||||
line[len] = '\0';
|
||||
}
|
||||
|
||||
// shouldn't get here
|
||||
return 0;
|
||||
}
|
||||
|
||||
//
|
||||
// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.)
|
||||
//
|
||||
int
|
||||
ReadHex(FILE *infile, unsigned char *A, int Length, char *str)
|
||||
{
|
||||
int i, ch, started;
|
||||
unsigned char ich;
|
||||
|
||||
if ( Length == 0 ) {
|
||||
A[0] = 0x00;
|
||||
return 1;
|
||||
}
|
||||
memset(A, 0x00, Length);
|
||||
started = 0;
|
||||
if ( FindMarker(infile, str) )
|
||||
while ( (ch = fgetc(infile)) != EOF ) {
|
||||
if ( !isxdigit(ch) ) {
|
||||
if ( !started ) {
|
||||
if ( ch == '\n' )
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
started = 1;
|
||||
if ( (ch >= '0') && (ch <= '9') )
|
||||
ich = ch - '0';
|
||||
else if ( (ch >= 'A') && (ch <= 'F') )
|
||||
ich = ch - 'A' + 10;
|
||||
else if ( (ch >= 'a') && (ch <= 'f') )
|
||||
ich = ch - 'a' + 10;
|
||||
else // shouldn't ever get here
|
||||
ich = 0;
|
||||
|
||||
for ( i=0; i<Length-1; i++ )
|
||||
A[i] = (A[i] << 4) | (A[i+1] >> 4);
|
||||
A[Length-1] = (A[Length-1] << 4) | ich;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
fprintBstr(FILE *fp, char *S, unsigned char *A, unsigned long long L)
|
||||
{
|
||||
unsigned long long i;
|
||||
|
||||
fprintf(fp, "%s", S);
|
||||
|
||||
for ( i=0; i<L; i++ )
|
||||
fprintf(fp, "%02X", A[i]);
|
||||
|
||||
if ( L == 0 )
|
||||
fprintf(fp, "00");
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
@ -1,222 +0,0 @@
|
||||
//
|
||||
// rng.c
|
||||
//
|
||||
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "rng.h"
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
AES256_CTR_DRBG_struct DRBG_ctx;
|
||||
|
||||
void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer);
|
||||
|
||||
/*
|
||||
seedexpander_init()
|
||||
ctx - stores the current state of an instance of the seed expander
|
||||
seed - a 32 byte random value
|
||||
diversifier - an 8 byte diversifier
|
||||
maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier
|
||||
*/
|
||||
int
|
||||
seedexpander_init(AES_XOF_struct *ctx,
|
||||
unsigned char *seed,
|
||||
unsigned char *diversifier,
|
||||
unsigned long maxlen)
|
||||
{
|
||||
if ( maxlen >= 0x100000000 )
|
||||
return RNG_BAD_MAXLEN;
|
||||
|
||||
ctx->length_remaining = maxlen;
|
||||
|
||||
memcpy(ctx->key, seed, 32);
|
||||
|
||||
memcpy(ctx->ctr, diversifier, 8);
|
||||
ctx->ctr[11] = maxlen % 256;
|
||||
maxlen >>= 8;
|
||||
ctx->ctr[10] = maxlen % 256;
|
||||
maxlen >>= 8;
|
||||
ctx->ctr[9] = maxlen % 256;
|
||||
maxlen >>= 8;
|
||||
ctx->ctr[8] = maxlen % 256;
|
||||
memset(ctx->ctr+12, 0x00, 4);
|
||||
|
||||
ctx->buffer_pos = 16;
|
||||
memset(ctx->buffer, 0x00, 16);
|
||||
|
||||
return RNG_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
seedexpander()
|
||||
ctx - stores the current state of an instance of the seed expander
|
||||
x - returns the XOF data
|
||||
xlen - number of bytes to return
|
||||
*/
|
||||
int
|
||||
seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen)
|
||||
{
|
||||
unsigned long offset;
|
||||
|
||||
if ( x == NULL )
|
||||
return RNG_BAD_OUTBUF;
|
||||
if ( xlen >= ctx->length_remaining )
|
||||
return RNG_BAD_REQ_LEN;
|
||||
|
||||
ctx->length_remaining -= xlen;
|
||||
|
||||
offset = 0;
|
||||
while ( xlen > 0 ) {
|
||||
if ( xlen <= (16-ctx->buffer_pos) ) { // buffer has what we need
|
||||
memcpy(x+offset, ctx->buffer+ctx->buffer_pos, xlen);
|
||||
ctx->buffer_pos += xlen;
|
||||
|
||||
return RNG_SUCCESS;
|
||||
}
|
||||
|
||||
// take what's in the buffer
|
||||
memcpy(x+offset, ctx->buffer+ctx->buffer_pos, 16-ctx->buffer_pos);
|
||||
xlen -= 16-ctx->buffer_pos;
|
||||
offset += 16-ctx->buffer_pos;
|
||||
|
||||
AES256_ECB(ctx->key, ctx->ctr, ctx->buffer);
|
||||
ctx->buffer_pos = 0;
|
||||
|
||||
//increment the counter
|
||||
for (int i=15; i>=12; i--) {
|
||||
if ( ctx->ctr[i] == 0xff )
|
||||
ctx->ctr[i] = 0x00;
|
||||
else {
|
||||
ctx->ctr[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return RNG_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void handleErrors(void)
|
||||
{
|
||||
ERR_print_errors_fp(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
// Use whatever AES implementation you have. This uses AES from openSSL library
|
||||
// key - 256-bit AES key
|
||||
// ctr - a 128-bit plaintext value
|
||||
// buffer - a 128-bit ciphertext value
|
||||
void
|
||||
AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
|
||||
int len;
|
||||
|
||||
int ciphertext_len;
|
||||
|
||||
/* Create and initialise the context */
|
||||
if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors();
|
||||
|
||||
if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL))
|
||||
handleErrors();
|
||||
|
||||
if(1 != EVP_EncryptUpdate(ctx, buffer, &len, ctr, 16))
|
||||
handleErrors();
|
||||
ciphertext_len = len;
|
||||
|
||||
/* Clean up */
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
NIST_randombytes_init(unsigned char *entropy_input,
|
||||
unsigned char *personalization_string,
|
||||
int security_strength)
|
||||
{
|
||||
unsigned char seed_material[48];
|
||||
|
||||
memcpy(seed_material, entropy_input, 48);
|
||||
if (personalization_string)
|
||||
for (int i=0; i<48; i++)
|
||||
seed_material[i] ^= personalization_string[i];
|
||||
memset(DRBG_ctx.Key, 0x00, 32);
|
||||
memset(DRBG_ctx.V, 0x00, 16);
|
||||
AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V);
|
||||
DRBG_ctx.reseed_counter = 1;
|
||||
}
|
||||
|
||||
int
|
||||
NIST_randombytes(unsigned char *x, unsigned long long xlen)
|
||||
{
|
||||
unsigned char block[16];
|
||||
int i = 0;
|
||||
|
||||
while ( xlen > 0 ) {
|
||||
//increment V
|
||||
for (int j=15; j>=0; j--) {
|
||||
if ( DRBG_ctx.V[j] == 0xff )
|
||||
DRBG_ctx.V[j] = 0x00;
|
||||
else {
|
||||
DRBG_ctx.V[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block);
|
||||
if ( xlen > 15 ) {
|
||||
memcpy(x+i, block, 16);
|
||||
i += 16;
|
||||
xlen -= 16;
|
||||
}
|
||||
else {
|
||||
memcpy(x+i, block, xlen);
|
||||
xlen = 0;
|
||||
}
|
||||
}
|
||||
AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V);
|
||||
DRBG_ctx.reseed_counter++;
|
||||
|
||||
return RNG_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
AES256_CTR_DRBG_Update(unsigned char *provided_data,
|
||||
unsigned char *Key,
|
||||
unsigned char *V)
|
||||
{
|
||||
unsigned char temp[48];
|
||||
|
||||
for (int i=0; i<3; i++) {
|
||||
//increment V
|
||||
for (int j=15; j>=0; j--) {
|
||||
if ( V[j] == 0xff )
|
||||
V[j] = 0x00;
|
||||
else {
|
||||
V[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AES256_ECB(Key, V, temp+16*i);
|
||||
}
|
||||
if ( provided_data != NULL )
|
||||
for (int i=0; i<48; i++)
|
||||
temp[i] ^= provided_data[i];
|
||||
memcpy(Key, temp, 32);
|
||||
memcpy(V, temp+32, 16);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,55 +0,0 @@
|
||||
//
|
||||
// rng.h
|
||||
//
|
||||
// Created by Bassham, Lawrence E (Fed) on 8/29/17.
|
||||
// Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef rng_h
|
||||
#define rng_h
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define RNG_SUCCESS 0
|
||||
#define RNG_BAD_MAXLEN -1
|
||||
#define RNG_BAD_OUTBUF -2
|
||||
#define RNG_BAD_REQ_LEN -3
|
||||
|
||||
typedef struct {
|
||||
unsigned char buffer[16];
|
||||
int buffer_pos;
|
||||
unsigned long length_remaining;
|
||||
unsigned char key[32];
|
||||
unsigned char ctr[16];
|
||||
} AES_XOF_struct;
|
||||
|
||||
typedef struct {
|
||||
unsigned char Key[32];
|
||||
unsigned char V[16];
|
||||
int reseed_counter;
|
||||
} AES256_CTR_DRBG_struct;
|
||||
|
||||
|
||||
void
|
||||
AES256_CTR_DRBG_Update(unsigned char *provided_data,
|
||||
unsigned char *Key,
|
||||
unsigned char *V);
|
||||
|
||||
int
|
||||
seedexpander_init(AES_XOF_struct *ctx,
|
||||
unsigned char *seed,
|
||||
unsigned char *diversifier,
|
||||
unsigned long maxlen);
|
||||
|
||||
int
|
||||
seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen);
|
||||
|
||||
void
|
||||
NIST_randombytes_init(unsigned char *entropy_input,
|
||||
unsigned char *personalization_string,
|
||||
int security_strength);
|
||||
|
||||
int
|
||||
NIST_randombytes(unsigned char *x, unsigned long long xlen);
|
||||
|
||||
#endif /* rng_h */
|
@ -13,14 +13,10 @@
|
||||
|
||||
#include "api.h"
|
||||
|
||||
#ifdef SUPERCOP
|
||||
#include "crypto_sign.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//#ifndef htole32
|
||||
static uint32_t bswap32(uint32_t x)
|
||||
static uint32_t bswap32(uint32_t x)
|
||||
{
|
||||
return ((x & 0xff000000) >> 24) | ((x & 0x00ff0000) >> 8) | ((x & 0x0000ff00) << 8) |
|
||||
((x & 0x000000ff) << 24);
|
||||
@ -36,42 +32,42 @@ static int isBigEndianSystem()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t htole32_portable(uint32_t x)
|
||||
static uint32_t htole32_portable(uint32_t x)
|
||||
{
|
||||
if(isBigEndianSystem()) {
|
||||
return bswap32(x);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
static uint32_t le32toh_portable(uint32_t x)
|
||||
static uint32_t le32toh_portable(uint32_t x)
|
||||
{
|
||||
if(isBigEndianSystem()) {
|
||||
return bswap32(x);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
picnic_params_t params = Picnic3_L1;
|
||||
picnic_params_t PQCLEAN_PICNIC3L1_CLEAN_params = Picnic3_L1;
|
||||
|
||||
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
|
||||
int PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
|
||||
{
|
||||
picnic_publickey_t pubkey;
|
||||
picnic_privatekey_t secret;
|
||||
|
||||
int ret = picnic_keygen(params, &pubkey, &secret);
|
||||
int ret = picnic_keygen(PQCLEAN_PICNIC3L1_CLEAN_params, &pubkey, &secret);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = picnic_write_public_key(&pubkey, pk, CRYPTO_PUBLICKEYBYTES);
|
||||
ret = picnic_write_public_key(&pubkey, pk, PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_PUBLICKEYBYTES);
|
||||
if (ret < 1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = picnic_write_private_key(&secret, sk, CRYPTO_SECRETKEYBYTES);
|
||||
ret = picnic_write_private_key(&secret, sk, PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_SECRETKEYBYTES);
|
||||
if (ret < 1) {
|
||||
return ret;
|
||||
}
|
||||
@ -79,67 +75,36 @@ int crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign(unsigned char *sm, unsigned long long *smlen,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *sk)
|
||||
int PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_signature(
|
||||
uint8_t *sm, size_t *smlen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *sk)
|
||||
{
|
||||
picnic_privatekey_t secret;
|
||||
|
||||
int ret = picnic_read_private_key(&secret, sk, CRYPTO_SECRETKEYBYTES);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
if (picnic_read_private_key(&secret, sk, PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_SECRETKEYBYTES)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Write out sm as
|
||||
* 4-byte integer signature length | message | signature
|
||||
*/
|
||||
size_t signature_len = CRYPTO_BYTES;
|
||||
ret = picnic_sign(&secret, m, mlen, sm + mlen + 4, &signature_len);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
*smlen = PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_BYTES;
|
||||
if (picnic_sign(&secret, m, mlen, sm, smlen)) {
|
||||
return -2;
|
||||
}
|
||||
if (signature_len > CRYPTO_BYTES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*smlen = 4 + mlen + signature_len;
|
||||
signature_len = htole32_portable(signature_len);
|
||||
memcpy(sm, (uint8_t*)&signature_len, 4);
|
||||
memcpy(sm + 4, m, mlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign_open(unsigned char *m, unsigned long long *mlen,
|
||||
const unsigned char *sm, unsigned long long smlen,
|
||||
const unsigned char *pk)
|
||||
int PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_verify(
|
||||
const uint8_t *sig, size_t siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *pk)
|
||||
{
|
||||
picnic_publickey_t pubkey;
|
||||
|
||||
int ret = picnic_read_public_key(&pubkey, pk, CRYPTO_PUBLICKEYBYTES);
|
||||
|
||||
if (ret != 0) {
|
||||
if (picnic_read_public_key(&pubkey, pk, PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_PUBLICKEYBYTES)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
uint32_t signature_len;
|
||||
memcpy((uint8_t*)&signature_len, sm, 4);
|
||||
signature_len = le32toh_portable(signature_len);
|
||||
if (signature_len > smlen - 1 - 4) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
size_t message_len = smlen - signature_len - 4;
|
||||
ret = picnic_verify(&pubkey, sm + 4, message_len,
|
||||
sm + 4 + message_len, signature_len);
|
||||
if (ret != 0) {
|
||||
if (picnic_verify(&pubkey, m, mlen, sig, siglen)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memmove(m, sm + 4, message_len);
|
||||
*mlen = message_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -16,25 +16,27 @@
|
||||
#ifndef api_h
|
||||
#define api_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Set these three values apropriately for your algorithm
|
||||
#define CRYPTO_SECRETKEYBYTES 52
|
||||
#define CRYPTO_PUBLICKEYBYTES 35
|
||||
#define CRYPTO_BYTES 14612
|
||||
#define PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_SECRETKEYBYTES 52
|
||||
#define PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_PUBLICKEYBYTES 35
|
||||
#define PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_BYTES 14612
|
||||
|
||||
// Change the algorithm name
|
||||
#define CRYPTO_ALGNAME "picnic3l1"
|
||||
#define PQCLEAN_PICNIC3L1_CLEAN_CRYPTO_ALGNAME "picnic3l1"
|
||||
|
||||
int
|
||||
crypto_sign_keypair(unsigned char *pk, unsigned char *sk);
|
||||
PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk);
|
||||
|
||||
int
|
||||
crypto_sign(unsigned char *sm, unsigned long long *smlen,
|
||||
const unsigned char *m, unsigned long long mlen,
|
||||
const unsigned char *sk);
|
||||
PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_signature(
|
||||
uint8_t *sig, size_t *siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *sk);
|
||||
|
||||
int
|
||||
crypto_sign_open(unsigned char *m, unsigned long long *mlen,
|
||||
const unsigned char *sm, unsigned long long smlen,
|
||||
const unsigned char *pk);
|
||||
int PQCLEAN_PICNIC3L1_CLEAN_crypto_sign_verify(
|
||||
const uint8_t *sig, size_t siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *pk);
|
||||
|
||||
#endif /* api_h */
|
||||
|
@ -12,11 +12,7 @@
|
||||
#include "hash.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#if !defined(SUPERCOP)
|
||||
#include "sha3/brg_endian.h"
|
||||
#else
|
||||
#include <libkeccak.a.headers/brg_endian.h>
|
||||
#endif
|
||||
|
||||
void HashUpdate(HashInstance* ctx, const uint8_t* data, size_t byteLen)
|
||||
{
|
||||
|
@ -12,11 +12,7 @@
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
#ifndef SUPERCOP
|
||||
#include "sha3/KeccakHash.h"
|
||||
#else
|
||||
#include <libkeccak.a.headers/KeccakHash.h>
|
||||
#endif
|
||||
#include "picnic_impl.h"
|
||||
|
||||
/* Wrap the Keccak API, checking return values, logging errors, and working
|
||||
|
@ -31,6 +31,7 @@ extern "C" {
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "common/randombytes.h"
|
||||
|
||||
/* Maximum lengths in bytes */
|
||||
#define PICNIC_MAX_LOWMC_BLOCK_SIZE 32
|
||||
@ -224,21 +225,7 @@ int picnic_validate_keypair(const picnic_privatekey_t* privatekey, const picnic_
|
||||
* random_bytes_default, and change the definition of
|
||||
* picnic_random_bytes.
|
||||
*/
|
||||
#ifdef USE_NIST_KAT_INSECURE_RNG
|
||||
/* For the NIST submission, when generating known-answer-tests (KATs), we
|
||||
* must use an RNG with a fixed seed so that re-running the program to
|
||||
* generate KATs prduces the same results. The function randombytes is
|
||||
* provided by NIST, in the file rng.c. */
|
||||
#include "NIST-KATs/rng.h"
|
||||
#define picnic_random_bytes NIST_randombytes
|
||||
#elif SUPERCOP
|
||||
int random_bytes_supercop(uint8_t* buf, size_t len);
|
||||
#define picnic_random_bytes random_bytes_supercop
|
||||
#else
|
||||
#define PICNIC_BUILD_DEFAULT_RNG 1
|
||||
#define picnic_random_bytes random_bytes_default
|
||||
#endif
|
||||
|
||||
#define picnic_random_bytes randombytes
|
||||
|
||||
/** Parse the signature and print the individual parts. Used when creating test vectors */
|
||||
void print_signature(const uint8_t* sigBytes, size_t sigBytesLen, picnic_params_t picnic_params);
|
||||
|
@ -122,7 +122,7 @@ void xor_three(uint32_t* output, const uint32_t* in1, const uint32_t* in2, const
|
||||
output[i] = in1[i] ^ in2[i] ^ in3[i];
|
||||
}
|
||||
for(size_t i = wholeWords*sizeof(uint32_t); i < lenBytes; i++) {
|
||||
out[i] = i1[i] ^ i2[i] ^ i3[i];
|
||||
out[i] = i1[i] ^ i2[i] ^ i3[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,13 +138,13 @@ void matrix_mul(
|
||||
{
|
||||
// Use temp to correctly handle the case when state = output
|
||||
uint8_t prod;
|
||||
uint32_t temp[LOWMC_MAX_WORDS];
|
||||
uint32_t temp[LOWMC_MAX_WORDS];
|
||||
temp[params->stateSizeWords-1] = 0;
|
||||
|
||||
for (uint32_t i = 0; i < params->stateSizeBits; i++) {
|
||||
prod = 0;
|
||||
for (uint32_t j = 0; j < params->stateSizeBits; j++) {
|
||||
size_t index = i * params->stateSizeWords*WORD_SIZE_BITS + j;
|
||||
size_t index = i * params->stateSizeWords*WORD_SIZE_BITS + j;
|
||||
prod ^= (getBitFromWordArray(state,j) & getBitFromWordArray(matrix, index));
|
||||
}
|
||||
setBit((uint8_t*)temp, i, prod);
|
||||
@ -666,7 +666,7 @@ int verify(signature_t* sig, const uint32_t* pubKey, const uint32_t* plaintext,
|
||||
|
||||
VIEW_OUTPUTS(i, challenge) = view1s[i].outputShare;
|
||||
VIEW_OUTPUTS(i, (challenge + 1) % 3) = view2s[i].outputShare;
|
||||
xor_three(view3Output, view1s[i].outputShare, view2s[i].outputShare, pubKey, params->stateSizeBytes);
|
||||
xor_three(view3Output, view1s[i].outputShare, view2s[i].outputShare, pubKey, params->stateSizeBytes);
|
||||
VIEW_OUTPUTS(i, (challenge + 2) % 3) = view3Output;
|
||||
view3Output = (uint32_t*) ((uint8_t*)view3Output + params->stateSizeBytes);
|
||||
}
|
||||
@ -756,9 +756,9 @@ void print_reconstruct(const char* label, uint32_t* s[3], size_t lengthBytes)
|
||||
xor_three(temp, s[0], s[1], s[2], lengthBytes);
|
||||
#if 0
|
||||
printf("\n");
|
||||
printHex("s0", (uint8_t*)s[0], lengthBytes);
|
||||
printHex("s1", (uint8_t*)s[1], lengthBytes);
|
||||
printHex("s2", (uint8_t*)s[2], lengthBytes);
|
||||
printHex("s0", (uint8_t*)s[0], lengthBytes);
|
||||
printHex("s1", (uint8_t*)s[1], lengthBytes);
|
||||
printHex("s2", (uint8_t*)s[2], lengthBytes);
|
||||
#endif
|
||||
printHex(label, (uint8_t*)temp, lengthBytes);
|
||||
}
|
||||
@ -799,51 +799,6 @@ void mpc_LowMC(randomTape_t* tapes, view_t views[3],
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PICNIC_BUILD_DEFAULT_RNG
|
||||
int random_bytes_default(uint8_t* buf, size_t len)
|
||||
{
|
||||
|
||||
#if defined(__LINUX__)
|
||||
FILE* urandom = fopen("/dev/urandom", "r");
|
||||
if (urandom == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(buf, sizeof(uint8_t), len, urandom) != len) {
|
||||
return -2;
|
||||
}
|
||||
fclose(urandom);
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined(__WINDOWS__)
|
||||
#ifndef ULONG_MAX
|
||||
#define ULONG_MAX 0xFFFFFFFFULL
|
||||
#endif
|
||||
if (len > ULONG_MAX) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG))) {
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
#error "If neither __LINUX__ or __WINDOWS__ are defined, you'll have to implement the random number generator"
|
||||
#endif
|
||||
|
||||
}
|
||||
#endif /* PICNIC_BUILD_DEFAULT_RNG */
|
||||
|
||||
#ifdef SUPERCOP
|
||||
#include "randombytes.h"
|
||||
int random_bytes_supercop(uint8_t* buf, size_t len)
|
||||
{
|
||||
randombytes(buf, len); /* returns void */
|
||||
return 0;
|
||||
}
|
||||
#endif /* SUPERCOP */
|
||||
|
||||
seeds_t* computeSeeds(uint32_t* privateKey, uint32_t*
|
||||
publicKey, uint32_t* plaintext, const uint8_t* message, size_t messageByteLength, paramset_t* params)
|
||||
{
|
||||
@ -952,7 +907,7 @@ int sign_picnic1(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, co
|
||||
|
||||
|
||||
#if 0 /* Self-test, verify the signature we just created */
|
||||
printf("\n-----------\n");
|
||||
printf("\n-----------\n");
|
||||
int ret = verify(sig, pubKey, plaintext, message, messageByteLength, params);
|
||||
if(ret != EXIT_SUCCESS) {
|
||||
printf("Self-test of signature verification failed\n");
|
||||
@ -961,7 +916,7 @@ int sign_picnic1(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, co
|
||||
else {
|
||||
printf("Self-test succeeded\n");
|
||||
}
|
||||
printf("\n-----------\n");
|
||||
printf("\n-----------\n");
|
||||
#endif
|
||||
|
||||
|
||||
@ -1068,7 +1023,7 @@ static int isChallengeValid(uint8_t* challengeBits, paramset_t* params)
|
||||
|
||||
int arePaddingBitsZero(uint8_t* data, size_t bitLength)
|
||||
{
|
||||
size_t byteLength = numBytes(bitLength);
|
||||
size_t byteLength = numBytes(bitLength);
|
||||
for (size_t i = bitLength; i < byteLength * 8; i++) {
|
||||
uint8_t bit_i = getBit(data, i);
|
||||
if (bit_i != 0) {
|
||||
|
@ -1,414 +0,0 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "picnic_types.h"
|
||||
#include "hash.h"
|
||||
#include "picnic.h"
|
||||
#include "picnic_impl.h"
|
||||
#include "tree.h"
|
||||
|
||||
static int contains(uint16_t* list, size_t len, uint16_t value)
|
||||
{
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
if(list[i] == value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int get_param_set(picnic_params_t picnicParams, paramset_t* paramset);
|
||||
|
||||
void printTreeInfo(const char* label, tree_t* tree)
|
||||
{
|
||||
printf("%s:\n", label);
|
||||
printf("tree->depth = %lu\n", tree->depth);
|
||||
printHex("haveNode", tree->haveNode, tree->numNodes); ; // If we have the seed or hash for node i, haveNode[i] is 1
|
||||
printf("tree->numNodes = %lu\n", tree->numNodes);
|
||||
printf("tree->numLeaves = %lu\n", tree->numLeaves);
|
||||
}
|
||||
|
||||
void printTree(const char* label, tree_t* tree)
|
||||
{
|
||||
printf("%s:\n", label);
|
||||
for(size_t i = 0; i < tree->numNodes; i++) {
|
||||
printf("node[%02lu] (have=%d, exists=%d) ", i, tree->haveNode[i], tree->exists[i]);
|
||||
printHex("", tree->nodes[i], tree->dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int runSeedTest(uint16_t* hideList, size_t hideListSize, size_t numLeaves, paramset_t* params)
|
||||
{
|
||||
uint8_t iSeed[16];
|
||||
uint8_t salt[16];
|
||||
size_t repIndex = 19;
|
||||
int freeHideList = 0;
|
||||
int ret = 1;
|
||||
|
||||
if(numLeaves < hideListSize - 1) {
|
||||
printf("%s invalid input (numLeaves = %lu, hideListSize = %lu)\n", __func__, numLeaves, hideListSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(hideList == NULL) {
|
||||
hideList = malloc(hideListSize*sizeof(uint16_t));
|
||||
freeHideList = 1;
|
||||
uint16_t val;
|
||||
for(size_t i = 0; i < hideListSize; i++) {
|
||||
do{
|
||||
val = ((uint16_t)rand()) % numLeaves;
|
||||
} while(contains(hideList, i, val));
|
||||
hideList[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("hideList: ");
|
||||
for(size_t i = 0; i < hideListSize; i++) {
|
||||
printf("%u, ", hideList[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
memset(iSeed, 0x07, sizeof(iSeed));
|
||||
memset(salt, 0x09, sizeof(salt));
|
||||
|
||||
//printf("%s: Generating seeds\n", __func__);
|
||||
tree_t* tree = generateSeeds(numLeaves, iSeed, salt, repIndex, params);
|
||||
tree_t* tree2 = createTree(numLeaves, params->seedSizeBytes);
|
||||
|
||||
#if 0
|
||||
printTree("tree", tree);
|
||||
#endif
|
||||
|
||||
|
||||
size_t initialOutputSize = (tree->numLeaves)*params->seedSizeBytes;
|
||||
uint8_t* output = malloc(initialOutputSize);
|
||||
|
||||
size_t expectedOutputLen = revealSeedsSize(numLeaves, hideList, hideListSize, params);
|
||||
if(hideListSize > 0 && expectedOutputLen == 0) {
|
||||
printf("Failed to get exepctedOutputLen\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
if(expectedOutputLen % params->seedSizeBytes != 0) {
|
||||
printf("ExepctedOutputLen is not a multiple of the seed length\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//printf("%s: Revealing seeds\n", __func__);
|
||||
size_t outputLen = revealSeeds(tree, hideList, hideListSize, output, initialOutputSize, params);
|
||||
if(outputLen == 0) {
|
||||
printf("Failed to revealSeeds, output buffer too small\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if(outputLen != expectedOutputLen) {
|
||||
printf("Expected output lengthd doesn't match output length\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("%s: numLeaves = %lu, revealed %lu\n", __func__, tree->numLeaves, outputLen/tree->dataSize);
|
||||
#endif
|
||||
|
||||
if(params->numOpenedRounds*ceil_log2(params->numMPCRounds/params->numOpenedRounds) < outputLen/tree->dataSize) {
|
||||
printf("%s: Output length is larger than expected\n", __func__);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
//printf("%s: Reconstructing seeds\n", __func__);
|
||||
int res = reconstructSeeds(tree2, hideList, hideListSize, output, outputLen, salt, repIndex, params);
|
||||
if(res != 0) {
|
||||
printf("%s: Reconstructing seeds FAILED\n", __func__);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("seeds in reconstructed tree:\n");
|
||||
printSeeds(tree2->nodes[0], params->seedSizeBytes, 15 );
|
||||
#endif
|
||||
|
||||
// Check that we have the correct seeds, and that they match
|
||||
size_t firstLeaf = tree->numNodes - tree->numLeaves;
|
||||
for(size_t i = firstLeaf; i < tree->numNodes; i++) {
|
||||
if(contains(hideList, hideListSize, i - firstLeaf)) {
|
||||
if(tree2->haveNode[i]) {
|
||||
printf("%s FAIL: reconstructed tree contains a seed that should have been hidden, node %lu (leaf node %lu)\n", __func__, i, i - firstLeaf);
|
||||
printHex("tree->nodes[i] ", tree->nodes[i], params->seedSizeBytes);
|
||||
printHex("tree2->nodes[i]", tree2->nodes[i], params->seedSizeBytes);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if(!tree2->haveNode[i]){
|
||||
printf("%s FAIL: expected to have seed for node %lu, but don't\n", __func__, i);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
if(!tree->haveNode[i]) {
|
||||
printf("%s FAIL: initial tree is missing node %lu -- not contructed properly?\n", __func__, i);
|
||||
//printTreeInfo("tree", tree);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if(memcmp(tree->nodes[i], tree2->nodes[i], params->seedSizeBytes) != 0) {
|
||||
printf("%s FAIL: reconstructed tree has an incorrect seed node %lu\n", __func__, i);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Exit:
|
||||
if(freeHideList) {
|
||||
free(hideList);
|
||||
}
|
||||
free(output);
|
||||
freeTree(tree);
|
||||
freeTree(tree2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int runMerkleTest(uint16_t* missingLeaves, size_t missingLeavesSize, size_t numLeaves, paramset_t* params)
|
||||
{
|
||||
// uint8_t iSeed[16];
|
||||
uint8_t salt[16];
|
||||
// size_t repIndex = 19;
|
||||
int freeMissingLeaves = 0;
|
||||
int ret = 1;
|
||||
tree_t* tree2 = NULL;
|
||||
|
||||
if(numLeaves < missingLeavesSize - 1) {
|
||||
printf("%s invalid input\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(missingLeaves == NULL) {
|
||||
missingLeaves = malloc(missingLeavesSize*sizeof(uint16_t));
|
||||
freeMissingLeaves = 1;
|
||||
uint16_t val;
|
||||
for(size_t i = 0; i < missingLeavesSize; i++) {
|
||||
do{
|
||||
val = ((uint16_t)rand()) % numLeaves;
|
||||
} while(contains(missingLeaves, i, val));
|
||||
missingLeaves[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("missingLeaves: ");
|
||||
for(size_t i = 0; i < missingLeavesSize; i++) {
|
||||
printf("%u, ", missingLeaves[i]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
// Prover side; all leaves are present
|
||||
|
||||
tree_t* tree = createTree(numLeaves, params->digestSizeBytes);
|
||||
|
||||
uint8_t** leafData = malloc(tree->numLeaves*sizeof(uint8_t*));
|
||||
uint8_t* slab = malloc(tree->numLeaves*tree->dataSize);
|
||||
uint8_t* slabToFree = slab;
|
||||
for(size_t i = 0; i < tree->numLeaves; i++) {
|
||||
leafData[i] = slab;
|
||||
slab += tree->dataSize;
|
||||
memset(leafData[i], (uint8_t)i+1, tree->dataSize);
|
||||
}
|
||||
|
||||
memset(salt, 0x09, sizeof(salt));
|
||||
|
||||
buildMerkleTree(tree, leafData, salt, params);
|
||||
|
||||
#if 0
|
||||
printTree("Tree after buildMerkleTree", tree);
|
||||
#endif
|
||||
|
||||
|
||||
size_t openDataSize = 0;
|
||||
uint8_t* openData = openMerkleTree(tree, missingLeaves, missingLeavesSize, &openDataSize);
|
||||
// root is tree->nodes[0]
|
||||
|
||||
if(params->numOpenedRounds*ceil_log2(params->numMPCRounds/params->numOpenedRounds) < openDataSize/tree->dataSize) {
|
||||
printf("%s: Output length is larger than expected\n", __func__);
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
// prover sends openData, tree->nodes[0] to verifier
|
||||
|
||||
// Verifier side
|
||||
tree2 = createTree(numLeaves, params->digestSizeBytes);
|
||||
|
||||
for(size_t i = 0; i < missingLeavesSize; i++) {
|
||||
leafData[missingLeaves[i]] = NULL;
|
||||
}
|
||||
|
||||
ret = addMerkleNodes(tree2, missingLeaves, missingLeavesSize, openData, openDataSize);
|
||||
if(ret != 0) {
|
||||
printf("Failed to add nodes to Merkle tree tree2\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//printTree("tree2 after addMerkleNodes", tree2);
|
||||
|
||||
ret = verifyMerkleTree(tree2, leafData, salt, params);
|
||||
if(ret != 0) {
|
||||
printf("Failed to verify Merkle tree\n");
|
||||
#if 0
|
||||
printTreeInfo("tree", tree);
|
||||
printTreeInfo("tree2", tree2);
|
||||
printTree("tree", tree);
|
||||
printTree("tree2", tree2);
|
||||
#endif
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if(memcmp(tree->nodes[0], tree2->nodes[0], tree->dataSize) != 0) {
|
||||
printf("Recomputed Merkle tree has different root; verification failed\n");
|
||||
ret = 0;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
//printTree("tree", tree);
|
||||
//printTree("tree2", tree2);
|
||||
|
||||
|
||||
ret = 1;
|
||||
Exit:
|
||||
if(freeMissingLeaves) {
|
||||
free(missingLeaves);
|
||||
}
|
||||
free(openData);
|
||||
free(slabToFree);
|
||||
free(leafData);
|
||||
freeTree(tree);
|
||||
freeTree(tree2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
paramset_t params;
|
||||
size_t tests = 0;
|
||||
size_t passed = 0;
|
||||
|
||||
size_t numIterations = 50;
|
||||
|
||||
printf("Running seed tree tests\n");
|
||||
|
||||
#if 1
|
||||
for (picnic_params_t p = Picnic3_L1; p <= Picnic3_L5; p++) {
|
||||
get_param_set(p, ¶ms);
|
||||
for(size_t i = 0; i < numIterations; i++) {
|
||||
passed += runSeedTest(NULL, params.numOpenedRounds, params.numMPCRounds, ¶ms);
|
||||
tests++;
|
||||
}
|
||||
for(size_t i = 0; i < numIterations; i++) {
|
||||
passed += runSeedTest(NULL, 3, 8, ¶ms);
|
||||
tests++;
|
||||
passed += runSeedTest(NULL, 3, 7, ¶ms);
|
||||
tests++;
|
||||
passed += runSeedTest(NULL, 3, 6, ¶ms);
|
||||
tests++;
|
||||
passed += runSeedTest(NULL, 4, 5, ¶ms);
|
||||
tests++;
|
||||
passed += runSeedTest(NULL, 2, 5, ¶ms);
|
||||
tests++;
|
||||
}
|
||||
|
||||
uint16_t hideList[3] = {2, 3, 6};
|
||||
passed += runSeedTest(hideList, 3, 7, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t hideList2[2] = {2, 3};
|
||||
passed += runSeedTest(hideList2, 2, 6, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t hideList3[2] = {2, 3};
|
||||
passed += runSeedTest(hideList3, 2, 5, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t hideList5[2] = {2, 3};
|
||||
passed += runSeedTest(hideList5, 2, 6, ¶ms);
|
||||
tests++;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
printf("Running Merkle tree tests\n");
|
||||
for (picnic_params_t p = Picnic3_L1; p <= Picnic3_L5; p++) {
|
||||
get_param_set(p, ¶ms);
|
||||
for(size_t i = 0; i < numIterations; i++) {
|
||||
passed += runMerkleTest(NULL, params.numOpenedRounds, params.numMPCRounds, ¶ms);
|
||||
tests++;
|
||||
}
|
||||
for(size_t i = 0; i < numIterations; i++) {
|
||||
passed += runMerkleTest(NULL, 3, 8, ¶ms);
|
||||
tests++;
|
||||
passed += runMerkleTest(NULL, 3, 7, ¶ms);
|
||||
tests++;
|
||||
passed += runMerkleTest(NULL, 3, 6, ¶ms);
|
||||
tests++;
|
||||
passed += runMerkleTest(NULL, 4, 5, ¶ms);
|
||||
tests++;
|
||||
passed += runMerkleTest(NULL, 2, 5, ¶ms);
|
||||
tests++;
|
||||
}
|
||||
|
||||
uint16_t hideList6[3] = {2, 3, 6};
|
||||
passed += runMerkleTest(hideList6, 3, 7, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t hideList4[2] = {2, 3};
|
||||
passed += runMerkleTest(hideList4, 2, 5, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t missingLeaves0[2] = {2, 3};
|
||||
passed += runMerkleTest(missingLeaves0, 2, 6, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t missingLeaves[4] = {4, 5, 6, 7};
|
||||
passed += runMerkleTest(missingLeaves, 4, 8, ¶ms);
|
||||
tests++;
|
||||
|
||||
uint16_t missingLeaves2[5] = {2, 3, 4, 8, 11};
|
||||
passed += runMerkleTest(missingLeaves2, 5, 13, ¶ms);
|
||||
tests++;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
printf("Done, %lu of %lu tests passed\n", passed, tests);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,857 +0,0 @@
|
||||
/*! @file unit_test.c
|
||||
* @brief This program tests the LowMC implementation against known answers.
|
||||
*
|
||||
* This file is part of the reference implementation of the Picnic signature scheme.
|
||||
* See the accompanying documentation for complete details.
|
||||
*
|
||||
* The code is provided under the MIT license, see LICENSE for
|
||||
* more details.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "picnic_impl.h"
|
||||
#include "picnic3_impl.h"
|
||||
#include "picnic.h"
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// The test vectors in test_sign* depend on this value
|
||||
static const uint8_t MSG[500] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,};
|
||||
|
||||
#define MSG_LEN sizeof(MSG)
|
||||
|
||||
// internal function from picnic.c:
|
||||
int get_param_set(picnic_params_t picnicParams, paramset_t* paramset);
|
||||
|
||||
#if 0
|
||||
int printNewKeypair(picnic_params_t parameters)
|
||||
{
|
||||
/* Generate, serialize and pring a keypair to stdout */
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
int ret = 0;
|
||||
|
||||
printf("Creating new key pair for parameter set: %s\n", picnic_get_param_name(parameters) );
|
||||
|
||||
ret = picnic_keygen(parameters, &pk, &sk);
|
||||
|
||||
if (ret != 0) {
|
||||
printf("picnic_keygen failed\n");
|
||||
exit(-1);
|
||||
}
|
||||
printf(" success\n");
|
||||
uint8_t pk_b[PICNIC_MAX_PUBLICKEY_SIZE];
|
||||
ret = picnic_write_public_key(&pk, pk_b, sizeof(pk_b));
|
||||
if (ret <= 0) {
|
||||
printf("Failed to serialize public key\n");
|
||||
exit(-1);
|
||||
}
|
||||
printHex("pk", pk_b, ret);
|
||||
|
||||
uint8_t sk_b[PICNIC_MAX_PRIVATEKEY_SIZE];
|
||||
ret = picnic_write_private_key(&sk, sk_b, sizeof(sk_b));
|
||||
if (ret <= 0) {
|
||||
printf("Failed to write private key\n");
|
||||
exit(-1);
|
||||
}
|
||||
printHex("sk", sk_b, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int run_lowmc_enc_test(picnic_params_t param_name, const char* testname, const uint8_t* key, const uint8_t* plaintext, const uint8_t* ciphertext_expected)
|
||||
{
|
||||
paramset_t paramset;
|
||||
uint8_t ciphertext_actual[32] = { 0 }; /* For all parameter sets the LowMC ciphertext is not more than 32 bytes */
|
||||
|
||||
int ret = get_param_set(param_name, ¶mset);
|
||||
|
||||
if (ret != 0) {
|
||||
printf("%s: Failed to get paramset\n", testname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LowMCEnc((uint32_t*)plaintext, (uint32_t*)ciphertext_actual, (uint32_t*)key, ¶mset);
|
||||
|
||||
if (memcmp(ciphertext_expected, ciphertext_actual, paramset.stateSizeBytes) != 0) {
|
||||
printf("%s: failed, encryption produced wrong ciphertext\n", testname);
|
||||
printf("Got: ");
|
||||
for(size_t i = 0; i < paramset.stateSizeBytes; i++) {
|
||||
printf("%02X, ", ciphertext_actual[i]);
|
||||
}
|
||||
printf("\nExpected: ");
|
||||
for(size_t i = 0; i < paramset.stateSizeBytes; i++) {
|
||||
printf("%02X, ", ciphertext_expected[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL1_1()
|
||||
{
|
||||
uint8_t key[16] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[16] = { 0xAB, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[16] = { 0x0E, 0x30, 0x72, 0x0B, 0x9F, 0x64, 0xD5, 0xC2, 0xA7, 0x77, 0x1C, 0x8C, 0x23, 0x8D, 0x8F, 0x70 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L1_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL1_2()
|
||||
{
|
||||
uint8_t key[16] = { 0xB5, 0xDF, 0x53, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[16] = { 0xF7, 0x7D, 0xB5, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[16] = { 0x0E, 0x59, 0x61, 0xE9, 0x99, 0x21, 0x53, 0xB1, 0x32, 0x45, 0xAF, 0x24, 0x3D, 0xD7, 0xDD, 0xC0 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L1_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL1_3()
|
||||
{
|
||||
|
||||
uint8_t key[16] = { 0x08, 0x4c, 0x2a, 0x6e, 0x19, 0x5d, 0x3b, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[16] = { 0xf7, 0xb3, 0xd5, 0x91, 0xe6, 0xa2, 0xc4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[16] = { 0x91, 0x5c, 0x63, 0x21, 0xd7, 0x86, 0x46, 0xb6, 0xc7, 0x65, 0x43, 0xff, 0xb8, 0x52, 0x3b, 0x4d };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L1_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
|
||||
int LowMC_test_vectorL3_1()
|
||||
{
|
||||
uint8_t key[24] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[24] = { 0xAB, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[24] = { 0xA8, 0x5B, 0x82, 0x44, 0x34, 0x4A, 0x2E, 0x1B, 0x10, 0xA1, 0x7B, 0xAB, 0x04, 0x30, 0x73, 0xF6, 0xBB, 0x64, 0x9A, 0xE6, 0xAF, 0x65, 0x9F, 0x6F };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L3_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL3_2()
|
||||
{
|
||||
uint8_t key[24] = { 0xB5, 0xDF, 0x53, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[24] = { 0xF7, 0x7D, 0xB5, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[24] = { 0x21, 0x0B, 0xBC, 0x4A, 0x43, 0x4B, 0x32, 0xDB, 0x1E, 0x85, 0xAE, 0x7A, 0x27, 0xFE, 0xE9, 0xE4, 0x15, 0x82, 0xFA, 0xC2, 0x1D, 0x03, 0x5A, 0xA1 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L3_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL3_3()
|
||||
{
|
||||
uint8_t key[24] = { 0xF7, 0x7D, 0xB5, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[24] = { 0xB5, 0xDF, 0x53, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[24] = { 0xE4, 0x82, 0xBC, 0xF9, 0xAD, 0x2C, 0x04, 0x48, 0x31, 0x48, 0xD4, 0x6F, 0xBE, 0x1F, 0x8B, 0x51, 0x46, 0x0D, 0xCC, 0x3E, 0x8E, 0xFB, 0x31, 0x01 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L3_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL5_1()
|
||||
{
|
||||
uint8_t key[32] = { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[32] = { 0xAB, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[32] = { 0xB8, 0xF2, 0x0A, 0x88, 0x8A, 0x0A, 0x9E, 0xC4, 0xE4, 0x95, 0xF1, 0xFB, 0x43, 0x9A, 0xBD, 0xDE, 0x18, 0xC1, 0xD3, 0xD2, 0x9C, 0xF2, 0x0D, 0xF4, 0xB1, 0x0A, 0x56, 0x7A, 0xA0, 0x2C, 0x72, 0x67 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L5_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL5_2()
|
||||
{
|
||||
uint8_t key[32] = { 0xF7, 0x7D, 0xB5, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[32] = { 0xB5, 0xDF, 0x53, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[32] = { 0xEE, 0xEC, 0xCE, 0x6A, 0x58, 0x4A, 0x93, 0x30, 0x6D, 0xAE, 0xA0, 0x75, 0x19, 0xB4, 0x7A, 0xD6, 0x40, 0x2C, 0x11, 0xDD, 0x94, 0x2A, 0xA3, 0x16, 0x65, 0x41, 0x44, 0x49, 0x77, 0xA2, 0x14, 0xC5 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L5_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL5_3()
|
||||
{
|
||||
uint8_t key[32] = { 0xB5, 0xDF, 0x53, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t plaintext[32] = { 0xF7, 0x7D, 0xB5, 0x7B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t ciphertext_expected[32] = { 0x03, 0x37, 0x33, 0x26, 0xC0, 0xF5, 0x0E, 0x3B, 0x6B, 0x2E, 0x1C, 0xE8, 0xF9, 0x43, 0x0F, 0xF5, 0xEB, 0x0E, 0xC3, 0x45, 0xC7, 0x27, 0xA4, 0x74, 0x8F, 0xCF, 0x73, 0x17, 0x9D, 0x48, 0xE7, 0x9B };
|
||||
|
||||
return run_lowmc_enc_test(Picnic_L5_FS, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
int LowMC_test_vectorL1_129_1()
|
||||
{
|
||||
|
||||
const uint8_t key[17] = {0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
const uint8_t plaintext[17] = {0xab, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
|
||||
const uint8_t ciphertext_expected[17] = {0x2f, 0xd7, 0xd5, 0x42, 0x5e, 0xe3, 0x5e, 0x66, 0x7c, 0x97, 0x2f, 0x12, 0xfb, 0x15, 0x3e, 0x9d, 0x80};
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L1, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL1_129_2(void) {
|
||||
const uint8_t key[17] = { 0xab, 0x22, 0x42, 0x51, 0x49, 0xaa, 0x61, 0x2d, 0x7f, 0xff, 0x13, 0x72, 0x20, 0x27, 0x5b, 0x16, 0x80 };
|
||||
const uint8_t plaintext[17] = { 0x4b, 0x99, 0x23, 0x53, 0xa6, 0x6, 0x65, 0xbf, 0x99, 0x2d, 0x3, 0x54, 0x82, 0xc1, 0xd2, 0x79, 0x00 };
|
||||
const uint8_t ciphertext_expected[17] = { 0x2a, 0x40, 0x62, 0xd8, 0x35, 0xc5, 0x93, 0xea, 0x19, 0xf8, 0x22, 0xad, 0x24, 0x24, 0x77, 0xd2, 0x80 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L1, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL1_129_3(void) {
|
||||
const uint8_t key[17] = { 0xe7, 0x3a, 0xf2, 0x9c, 0xfc, 0x7a, 0xe5, 0x3e, 0x52, 0x20, 0xd3, 0x1e, 0x2e, 0x59, 0x17, 0xda, 0x80 };
|
||||
const uint8_t plaintext[17] = { 0x30, 0x4b, 0xa7, 0xa8, 0xde, 0x2b, 0x5c, 0xf8, 0x87, 0xf9, 0xa4, 0x8a, 0xb7, 0x56, 0x1b, 0xf6, 0x80 };
|
||||
const uint8_t ciphertext_expected[17] = { 0x5c, 0xd2, 0xc3, 0x55, 0x32, 0x8e, 0xfd, 0xe9, 0xf3, 0x78, 0xc1, 0x61, 0x23, 0xd3, 0x3f, 0xb3, 0x00 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L1, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL1_129_4(void) {
|
||||
const uint8_t key[17] = { 0x30, 0xf3, 0x34, 0x88, 0x53, 0x2d, 0x7e, 0xb8, 0xa5, 0xf8, 0xfb, 0x4f, 0x2e, 0x63, 0xba, 0x56, 0x00 };
|
||||
const uint8_t plaintext[17] = { 0xc2, 0x6a, 0x5d, 0xf9, 0x6, 0x15, 0x8d, 0xcb, 0x6a, 0xc7, 0x89, 0x1d, 0xa9, 0xf4, 0x9f, 0x78, 0x00 };
|
||||
const uint8_t ciphertext_expected[17] = { 0xb, 0x43, 0xb6, 0x5f, 0x7c, 0x53, 0x50, 0x6, 0xcf, 0x27, 0xe8, 0x6f, 0x55, 0x1b, 0xd0, 0x15, 0x80 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L1, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
|
||||
static int LowMC_test_vectorL3_192_1(void) {
|
||||
const uint8_t key[24] = { 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||
const uint8_t plaintext[24] = { 0xab, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||
const uint8_t ciphertext_expected[24] = { 0xf8, 0xf7, 0xa2, 0x25, 0xde, 0x77, 0x12, 0x31, 0x29, 0x10, 0x7a, 0x20, 0xf5, 0x54, 0x3a, 0xfa, 0x78, 0x33, 0x7, 0x66, 0x53, 0xba, 0x2b, 0x29 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L3, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL3_192_2(void) {
|
||||
const uint8_t key[24] = { 0x81, 0xb8, 0x5d, 0xfe, 0x40, 0xf6, 0x12, 0x27, 0x5a, 0xa3, 0xf9, 0x19, 0x91, 0x39, 0xeb, 0xaa, 0xe8, 0xdf, 0xf8, 0x36, 0x6f, 0x2d, 0xd3, 0x4e };
|
||||
const uint8_t plaintext[24] = { 0xb8, 0x65, 0xcc, 0xf3, 0xfc, 0xda, 0x8d, 0xdb, 0xed, 0x52, 0x7d, 0xc3, 0x4d, 0xd4, 0x15, 0xd, 0x4a, 0x48, 0x2d, 0xcb, 0xf7, 0xe9, 0x64, 0x3c };
|
||||
const uint8_t ciphertext_expected[24] = { 0x95, 0xef, 0x9e, 0xd7, 0xc3, 0x78, 0x72, 0xa7, 0xb4, 0x60, 0x2a, 0x3f, 0xa9, 0xc4, 0x6e, 0xbc, 0xb8, 0x42, 0x54, 0xed, 0xe, 0x44, 0xee, 0x9f };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L3, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL3_192_3(void) {
|
||||
const uint8_t key[24] = { 0x24, 0x5, 0x97, 0x8f, 0xda, 0xad, 0x9b, 0x6d, 0x8d, 0xcd, 0xd1, 0x8a, 0xc, 0x2c, 0xe, 0xc6, 0x8b, 0x69, 0xdd, 0xa, 0x37, 0x54, 0xfe, 0x38, };
|
||||
const uint8_t plaintext[24] = { 0x33, 0xe8, 0xb4, 0x55, 0x2e, 0x95, 0xef, 0x52, 0x79, 0x49, 0x77, 0x6, 0xbc, 0xe0, 0x1e, 0xcb, 0x4a, 0xcb, 0x86, 0x1, 0x41, 0xb7, 0xfc, 0x43, };
|
||||
const uint8_t ciphertext_expected[24] = { 0xdd, 0xaf, 0xf, 0x9d, 0x9e, 0xdd, 0x57, 0x20, 0x69, 0xa8, 0x94, 0x9f, 0xae, 0xa0, 0xd1, 0xfd, 0x2d, 0x91, 0xef, 0x26, 0x2b, 0x41, 0x1c, 0xaf, };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L3, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL3_192_4(void) {
|
||||
const uint8_t key[24] = { 0x56, 0x9d, 0x7d, 0x82, 0x23, 0x0, 0x94, 0x3d, 0x94, 0x83, 0x47, 0x74, 0x27, 0xe8, 0x8e, 0xa2, 0x27, 0xa2, 0xe3, 0x17, 0x2c, 0x4, 0xbc, 0xd3};
|
||||
const uint8_t plaintext[24] = { 0xae, 0xeb, 0x9d, 0x5b, 0x61, 0xa2, 0xa5, 0x6d, 0xd5, 0x98, 0xf7, 0xda, 0x26, 0xdf, 0xd7, 0x8c, 0xc9, 0x92, 0xe0, 0xae, 0xa3, 0xfc, 0x2e, 0x39 };
|
||||
const uint8_t ciphertext_expected[24] = { 0x86, 0x98, 0x70, 0xae, 0x65, 0x47, 0xad, 0xa, 0xfe, 0xf2, 0x77, 0x93, 0x17, 0xd, 0x96, 0xbc, 0x78, 0xe0, 0x40, 0x9, 0x69, 0x44, 0x80, 0x8f };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L3, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL5_255_1(void) {
|
||||
const uint8_t key[32] = { 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||
const uint8_t plaintext[32] = { 0xab, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
|
||||
const uint8_t ciphertext_expected[32] = { 0xd4, 0x72, 0x1d, 0x84, 0x6d, 0xd1, 0x4d, 0xba, 0x3a, 0x2c, 0x41, 0x50, 0x1c, 0x2, 0xda, 0x28, 0x2e, 0xca, 0xfd, 0x72, 0xdf, 0x77, 0x99, 0x2f, 0x39, 0x67, 0xef, 0xd6, 0xe8, 0xf3, 0xf3, 0x56 };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L5, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL5_255_2(void) {
|
||||
const uint8_t key[32] = { 0x7c, 0x20, 0xbe, 0x53, 0xb6, 0xd6, 0x0, 0x81, 0x49, 0xe1, 0x9a, 0x34, 0xb9, 0x7d, 0x96, 0x84, 0xa0, 0x91, 0x4c, 0xaf,0x9f, 0x7f, 0x38, 0xb2, 0x49, 0x98, 0x11, 0x36, 0x9c, 0x3f, 0x53, 0xda};
|
||||
const uint8_t plaintext[32] = { 0x88, 0x63, 0xf1, 0x29, 0xc0, 0x38, 0x7a,0xe5, 0xa4, 0x2, 0xa4, 0x9b, 0xd6, 0x49, 0x27, 0xc4, 0xc6, 0x59, 0x64,0xfb, 0x85, 0x31, 0xb0, 0xd7, 0x61, 0xb1, 0x61, 0xb4, 0xc9, 0x7b, 0x75,0x5e, };
|
||||
const uint8_t ciphertext_expected[32] = { 0x3, 0xb6, 0xe4, 0xb6, 0x3c, 0xc8,0xb0, 0x82, 0x68, 0xb6, 0x78, 0x1d, 0x5a, 0x62, 0x9d, 0x6e, 0x3, 0x2,0xc, 0x1c, 0x4, 0x8d, 0x46, 0x84, 0x16, 0x1b, 0x90, 0xad, 0x73, 0x33,0x91, 0x26, };
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L5, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL5_255_3(void) {
|
||||
const uint8_t key[32] = {0x6d, 0xf9, 0xe7, 0x8d, 0xf, 0xc1, 0xb8, 0x70, 0xda, 0xbe, 0x52,0x5, 0x14, 0xb9, 0x59, 0x63, 0x6a, 0x42, 0x30, 0x4b, 0xf4, 0x3a,0x24, 0x8, 0x52, 0x45, 0x6, 0xc8, 0x1e, 0xa3, 0xb, 0x14};
|
||||
const uint8_t plaintext[32] = {0x9e, 0x51, 0x78, 0x42, 0x5, 0x20, 0xb8, 0xcc, 0xa5, 0x29, 0x59,0x5b, 0x80, 0xc4, 0x70, 0x3b, 0x2d, 0xcf, 0x2a, 0x7, 0x30, 0x64,0x3a, 0x6f, 0x41, 0x27, 0x98, 0x60, 0x5f, 0x5, 0x2b, 0x68};
|
||||
const uint8_t ciphertext_expected[32] = {0xf, 0x19, 0xfc, 0xc8, 0xbc, 0x18, 0x86, 0x9a, 0xab, 0x8e, 0x4f,0xe8, 0x1e, 0x97, 0x67, 0xd1, 0x8c, 0xfe, 0x71, 0x50, 0x81, 0x92,0x9f, 0x92, 0x96, 0x3b, 0x40, 0x0, 0x0, 0x6, 0x26, 0xf8};
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L5, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
static int LowMC_test_vectorL5_255_4(void) {
|
||||
const uint8_t key[32] = {0xb0, 0x71, 0xc6, 0xd4, 0xa3, 0x77, 0xe5, 0x51, 0x25, 0x4c, 0x5d,0xc4, 0x1, 0xa3, 0xd0, 0x8a, 0xcb, 0x99, 0x60, 0x9f, 0x41, 0x8a,0x8c, 0x22, 0x7, 0xf5, 0x12, 0x2b, 0x5a, 0x17, 0xfe, 0x9a,};
|
||||
const uint8_t plaintext[32] = {0xf7, 0x61, 0x6d, 0xc5, 0x14, 0xfd, 0xe, 0x10, 0x28, 0x56, 0x1d,0x9, 0x8a, 0xaf, 0xa5, 0x4c, 0x34, 0xbe, 0x72, 0x8c, 0xf2, 0x4a,0x50, 0x24, 0xdf, 0x17, 0xb9, 0xcc, 0x2e, 0x33, 0xfb, 0xfa,};
|
||||
const uint8_t ciphertext_expected[32] = {0x44, 0x48, 0xc7, 0xa, 0xc3, 0x86, 0x30, 0x21, 0xbe, 0x23, 0x2c, 0x63, 0x38, 0x16, 0x87, 0xcd,0x5d, 0xef, 0xb5, 0xb, 0xa2, 0x8d, 0x7b, 0x26, 0x8e, 0x19, 0x72, 0x7b, 0xae, 0xbc, 0x67, 0x9a,};
|
||||
|
||||
return run_lowmc_enc_test(Picnic3_L5, __func__, key, plaintext, ciphertext_expected);
|
||||
}
|
||||
|
||||
|
||||
int test_serialization_L1()
|
||||
{
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
picnic_publickey_t pk2;
|
||||
picnic_privatekey_t sk2;
|
||||
uint8_t pk_buf[PICNIC_MAX_PUBLICKEY_SIZE];
|
||||
uint8_t sk_buf[PICNIC_MAX_PRIVATEKEY_SIZE];
|
||||
|
||||
int ret = picnic_keygen(Picnic_L1_FS, &pk, &sk);
|
||||
|
||||
if(ret != 0) {
|
||||
printf("Keygen failed, %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_write_public_key(&pk, pk_buf, sizeof(pk_buf));
|
||||
if(ret <= 1) {
|
||||
printf("Failed to serialize public key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_write_private_key(&sk, sk_buf, sizeof(sk_buf));
|
||||
if(ret <= 1) {
|
||||
printf("Failed to serialize private key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_read_public_key(&pk2, pk_buf, sizeof(pk_buf));
|
||||
if(ret != 0) {
|
||||
printf("Failed to read public key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_read_private_key(&sk2, sk_buf, sizeof(sk_buf));
|
||||
if(ret != 0) {
|
||||
printf("Failed to read private key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ret = picnic_validate_keypair(&sk2, &pk2);
|
||||
if(ret != 0) {
|
||||
printf("Failed to validate key pair 2\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_validate_keypair(&sk2, &pk);
|
||||
if(ret != 0) {
|
||||
printf("Failed to validate key pair 3\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_validate_keypair(&sk, &pk2);
|
||||
if(ret != 0) {
|
||||
printf("Failed to validate key pair 4\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int test_serialize_roundtrip_picnic3(picnic_params_t parameters)
|
||||
{
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
paramset_t paramset;
|
||||
signature2_t sig, sig2;
|
||||
|
||||
int ret = get_param_set(parameters, ¶mset);
|
||||
if (ret != 0) {
|
||||
printf("invalid parameter set\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_keygen(parameters, &pk, &sk);
|
||||
if (ret != 0) {
|
||||
printf("picnic_keygen failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t message[MSG_LEN];
|
||||
memset(message, 0x07, sizeof(message));
|
||||
uint8_t* signature = NULL;
|
||||
|
||||
size_t signature_len = picnic_signature_size(parameters);
|
||||
signature = (uint8_t*)malloc(signature_len);
|
||||
if (signature == NULL) {
|
||||
printf("failed to allocate signature\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
allocateSignature2(&sig, ¶mset);
|
||||
|
||||
/* Compute a signature, then check that serialize(deserialize(sig)) == serialize(sig) */
|
||||
ret = sign_picnic3((uint32_t*)sk.data, (uint32_t*)sk.pk.ciphertext, (uint32_t*)sk.pk.plaintext, message, MSG_LEN, &sig, ¶mset);
|
||||
if (ret != EXIT_SUCCESS) {
|
||||
printf("%s: sign failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ret = serializeSignature2(&sig, signature, signature_len, ¶mset);
|
||||
if (ret == -1) {
|
||||
printf("%s: serialize failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
signature_len = ret;
|
||||
|
||||
allocateSignature2(&sig2, ¶mset);
|
||||
ret = deserializeSignature2(&sig2, signature, signature_len, ¶mset);
|
||||
if (ret != EXIT_SUCCESS) {
|
||||
printf("%s: deserialize failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* signature2 = (uint8_t*)malloc(signature_len);
|
||||
if (signature2 == NULL) {
|
||||
printf("%s: failed to allocate signature\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ret = serializeSignature2(&sig2, signature2, signature_len, ¶mset);
|
||||
if (ret == -1) {
|
||||
printf("%s: serialize failed (2)\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(memcmp(signature, signature2, signature_len) != 0) {
|
||||
printf("Round-trip serialization test failed (params %u)\n", (unsigned int)parameters);
|
||||
// printHex("Sig one", signature, signature_len);
|
||||
// printHex("Sig two", signature2, signature_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(signature);
|
||||
free(signature2);
|
||||
freeSignature2(&sig, ¶mset);
|
||||
freeSignature2(&sig2, ¶mset);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static int contains(uint16_t* list, size_t len, size_t value)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (list[i] == value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int indexOf(uint16_t* list, size_t len, size_t value)
|
||||
{
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
if (list[i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
assert(!"indexOf called on list where value is not found. (caller bug)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int compare_proofs(proof2_t* proof1, proof2_t* proof2, paramset_t* params, int compare_aux)
|
||||
{
|
||||
if(proof1->seedInfoLen != proof2->seedInfoLen ||
|
||||
memcmp(proof1->seedInfo, proof2->seedInfo, proof1->seedInfoLen) != 0) {
|
||||
printf("%s: seedInfo differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(compare_aux) {
|
||||
if(!(proof1->aux == NULL && proof2->aux == NULL)) {
|
||||
if((proof1->aux == NULL && proof2->aux != NULL) ||
|
||||
(proof2->aux == NULL && proof1->aux != NULL) ||
|
||||
memcmp(proof1->aux, proof2->aux, params->andSizeBytes) != 0 ) {
|
||||
printf("%s: aux differs\n", __func__);
|
||||
printHex("aux1", proof1->aux, params->andSizeBytes);
|
||||
printHex("aux2", proof2->aux, params->andSizeBytes);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(memcmp(proof1->C, proof2->C, params->digestSizeBytes) != 0) {
|
||||
printf("%s: C differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(memcmp(proof1->input, proof2->input, params->stateSizeBytes) != 0) {
|
||||
printf("%s: input differs\n", __func__);
|
||||
printHex("input1", proof1->input, params->stateSizeBytes);
|
||||
printHex("input2", proof2->input, params->stateSizeBytes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(memcmp(proof1->msgs, proof2->msgs, params->andSizeBytes) != 0) {
|
||||
printf("%s: msgs differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int compare_signatures(signature2_t* sig1, signature2_t* sig2, paramset_t* params)
|
||||
{
|
||||
|
||||
if(memcmp(sig1->salt, sig2->salt, params->saltSizeBytes) != 0) {
|
||||
printf("%s: salt differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(sig1->iSeedInfoLen != sig2->iSeedInfoLen ||
|
||||
memcmp(sig1->iSeedInfo, sig2->iSeedInfo, sig1->iSeedInfoLen) != 0 ) {
|
||||
printf("%s: iSeedInfo differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(sig1->cvInfoLen != sig2->cvInfoLen ||
|
||||
memcmp(sig1->cvInfo, sig2->cvInfo, sig1->cvInfoLen) != 0) {
|
||||
printf("%s: iSeedInfo differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(memcmp(sig1->challengeC, sig2->challengeC, params->numOpenedRounds*sizeof(uint16_t)) != 0) {
|
||||
printf("%s: challengeC differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(memcmp(sig1->challengeP, sig2->challengeP, params->numOpenedRounds*sizeof(uint16_t)) != 0) {
|
||||
printf("%s: challengeP differs\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (size_t t = 0; t < params->numMPCRounds; t++) {
|
||||
if (contains(sig1->challengeC, params->numOpenedRounds, t)) {
|
||||
size_t P_t = sig1->challengeP[indexOf(sig1->challengeC, params->numOpenedRounds, t)];
|
||||
int compare_aux = (P_t != (params->numMPCParties - 1));
|
||||
if(compare_proofs(&sig1->proofs[t], &sig2->proofs[t], params, compare_aux) != 0) {
|
||||
printf("%s: proofs %u differ\n", __func__, (unsigned int) t);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int test_sig_serialize_picnic3(picnic_params_t parameters)
|
||||
{
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
paramset_t paramset;
|
||||
signature2_t sig, sig2;
|
||||
|
||||
int ret = get_param_set(parameters, ¶mset);
|
||||
if (ret != 0) {
|
||||
printf("invalid parameter set\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_keygen(parameters, &pk, &sk);
|
||||
if (ret != 0) {
|
||||
printf("picnic_keygen failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t message[MSG_LEN];
|
||||
memset(message, 0x07, sizeof(message));
|
||||
uint8_t* signature = NULL;
|
||||
|
||||
size_t signature_len = picnic_signature_size(parameters);
|
||||
signature = (uint8_t*)malloc(signature_len);
|
||||
if (signature == NULL) {
|
||||
printf("failed to allocate signature\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
allocateSignature2(&sig, ¶mset);
|
||||
|
||||
/* Compute a signature object sig, then sig2 = deserialize(serialize(sig)), ensure sig == sig2 */
|
||||
ret = sign_picnic3((uint32_t*)sk.data, (uint32_t*)sk.pk.ciphertext, (uint32_t*)sk.pk.plaintext, message, MSG_LEN, &sig, ¶mset);
|
||||
if (ret != EXIT_SUCCESS) {
|
||||
printf("%s: signing failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
ret = serializeSignature2(&sig, signature, signature_len, ¶mset);
|
||||
if (ret == -1) {
|
||||
printf("%s: serialization failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
signature_len = ret;
|
||||
|
||||
allocateSignature2(&sig2, ¶mset);
|
||||
ret = deserializeSignature2(&sig2, signature, signature_len, ¶mset);
|
||||
if (ret != EXIT_SUCCESS) {
|
||||
printf("%s: deserialization failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( compare_signatures(&sig, &sig2, ¶mset) != 0) {
|
||||
printf("%s: signatures differ\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
freeSignature2(&sig, ¶mset);
|
||||
freeSignature2(&sig2, ¶mset);
|
||||
free(signature);
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* tests for deterministic picnic3 */
|
||||
int do_test_sign(
|
||||
uint8_t* pk_buf, size_t pk_buf_len,
|
||||
uint8_t* sk_buf, size_t sk_buf_len,
|
||||
uint8_t* expected_challenge, size_t expected_challenge_len,
|
||||
uint8_t* expected_salt, size_t expected_salt_len,
|
||||
size_t expected_sig_len)
|
||||
{
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
ret = picnic_read_public_key(&pk, pk_buf, pk_buf_len);
|
||||
if (ret != 0) {
|
||||
printf("%s: Failed to read public key\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_read_private_key(&sk, sk_buf, sk_buf_len);
|
||||
if (ret != 0) {
|
||||
printf("%s: Failed to read private key\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_validate_keypair(&sk, &pk);
|
||||
if (ret != 0) {
|
||||
printf("%s: Keypair invalid\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* signature = NULL;
|
||||
|
||||
size_t signature_len = picnic_signature_size(pk.params);
|
||||
signature = (uint8_t*)malloc(signature_len);
|
||||
if (signature == NULL) {
|
||||
printf("%s: failed to allocate signature\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_sign(&sk, MSG, MSG_LEN, signature, &signature_len);
|
||||
if (ret != 0) {
|
||||
printf("%s: picnic_sign failed (params = %d)\n", __func__, pk.params);
|
||||
return 0;
|
||||
}
|
||||
if(signature_len != expected_sig_len) {
|
||||
printf("%s: signature has length %lu bytes, but expected %lu (params = %d)\n", __func__, signature_len, expected_sig_len, pk.params);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(memcmp(signature, expected_challenge, expected_challenge_len) != 0) {
|
||||
printf("%s: signature does not have the expected challenge value\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
if(memcmp(signature + expected_challenge_len, expected_salt, expected_salt_len) != 0) {
|
||||
printf("%s: signature does not have the expected salt\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = picnic_verify(&pk, MSG, MSG_LEN, signature, signature_len);
|
||||
if (ret != 0) {
|
||||
printf("%s: picnic_verify failed\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(signature);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_sign_Picnic3_L1()
|
||||
{
|
||||
uint8_t pk[35] = {0x07, 0x8D, 0xCB, 0x2E, 0x06, 0x2E, 0xE1, 0x48, 0xF8, 0x81, 0xBD, 0xA2, 0xAD, 0x95, 0x39, 0x00, 0x31, 0x00, 0x05, 0xBB, 0x82, 0x75, 0xF0, 0x00, 0x5F, 0xAE, 0x73, 0x1C, 0xFE, 0x1A, 0xE6, 0xCA, 0xC6, 0x15, 0x00};
|
||||
uint8_t sk[52] = {0x07, 0xA3, 0x4F, 0xEB, 0x0A, 0x24, 0x6F, 0xD7, 0xFC, 0x5B, 0xC6, 0x1E, 0x07, 0xFD, 0x73, 0x7A, 0xCF, 0x00, 0x8D, 0xCB, 0x2E, 0x06, 0x2E, 0xE1, 0x48, 0xF8, 0x81, 0xBD, 0xA2, 0xAD, 0x95, 0x39, 0x00, 0x31, 0x00, 0x05, 0xBB, 0x82, 0x75, 0xF0, 0x00, 0x5F, 0xAE, 0x73, 0x1C, 0xFE, 0x1A, 0xE6, 0xCA, 0xC6, 0x15, 0x00};
|
||||
uint8_t expected_challenge[32] = {0x81, 0xE6, 0x74, 0x22, 0x2D, 0xC9, 0x77, 0xFF, 0xAB, 0xAC, 0x14, 0x71, 0xA5, 0xAB, 0xCB, 0xA5, 0x9D, 0x6E, 0x6B, 0x7A, 0x70, 0x5E, 0xE5, 0x16, 0xEF, 0x09, 0xD6, 0x30, 0x6C, 0x86, 0x41, 0x26};
|
||||
uint8_t expected_salt[32] = {0xCE, 0x7F, 0x9E, 0x58, 0xE0, 0xCD, 0x54, 0x5D, 0xF9, 0x49, 0xDE, 0x41, 0xD0, 0x28, 0x56, 0x8A, 0xA6, 0xCB, 0x88, 0xEF, 0xC5, 0x06, 0x1D, 0xC7, 0xC7, 0x7A, 0xF8, 0x5A, 0xE0, 0x08, 0x7A, 0x1A};
|
||||
size_t expected_sig_len = 12395;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
int test_sign_Picnic3_L3()
|
||||
{
|
||||
uint8_t pk[49] = {0x08, 0xAC, 0x52, 0x30, 0x73, 0x96, 0x70, 0x34, 0x7A, 0x12, 0x84, 0x0E, 0x58, 0x17, 0x6A, 0x5C, 0x88, 0x84, 0x71, 0xBC, 0x7E, 0xAF, 0x68, 0x7E, 0x5B, 0xCD, 0x5C, 0x79, 0xBE, 0x19, 0x5A, 0xEC, 0xF6, 0x55, 0x31, 0x96, 0xE0, 0x86, 0xA1, 0x7C, 0xD6, 0xE5, 0xB6, 0x0B, 0x37, 0x79, 0x16, 0x15, 0x24};
|
||||
uint8_t sk[73] = {0x08, 0x98, 0xE1, 0x7B, 0xA4, 0x50, 0xA9, 0xF2, 0x5D, 0xC7, 0x48, 0x24, 0x4B, 0xF5, 0x3E, 0xE1, 0xB2, 0x8D, 0xA9, 0x6F, 0x17, 0xBC, 0xC3, 0x2F, 0xA0, 0xAC, 0x52, 0x30, 0x73, 0x96, 0x70, 0x34, 0x7A, 0x12, 0x84, 0x0E, 0x58, 0x17, 0x6A, 0x5C, 0x88, 0x84, 0x71, 0xBC, 0x7E, 0xAF, 0x68, 0x7E, 0x5B, 0xCD, 0x5C, 0x79, 0xBE, 0x19, 0x5A, 0xEC, 0xF6, 0x55, 0x31, 0x96, 0xE0, 0x86, 0xA1, 0x7C, 0xD6, 0xE5, 0xB6, 0x0B, 0x37, 0x79, 0x16, 0x15, 0x24};
|
||||
uint8_t expected_challenge[48] = {0x2B, 0xAC, 0xC4, 0x1D, 0x18, 0x11, 0x97, 0x42, 0xA0, 0x92, 0xB9, 0xC6, 0x5F, 0x51, 0xE7, 0x85, 0x57, 0x59, 0x0F, 0x01, 0x30, 0x48, 0x30, 0xA5, 0x03, 0x35, 0x13, 0x72, 0x84, 0xDB, 0x47, 0x2B, 0x9F, 0x93, 0xB3, 0xF2, 0x3A, 0x91, 0x09, 0x5A, 0x38, 0x11, 0xC0, 0x82, 0xE2, 0xB8, 0xA8, 0x6E};
|
||||
uint8_t expected_salt[32] = {0xA0, 0x8F, 0x16, 0xAF, 0x30, 0x3E, 0xD7, 0x79, 0xE6, 0x53, 0x6C, 0x9A, 0xE6, 0xE7, 0xC4, 0xC0, 0xB8, 0x64, 0xC1, 0xD6, 0xA4, 0x05, 0x70, 0x9A, 0x95, 0x76, 0xAF, 0x00, 0xAE, 0x00, 0x9C, 0xD9};
|
||||
size_t expected_sig_len = 25712;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
int test_sign_Picnic3_L5()
|
||||
{
|
||||
uint8_t pk[65] = {0x09, 0x19, 0x75, 0x3E, 0x8D, 0x8F, 0xB6, 0x00, 0x5F, 0x6E, 0x2E, 0xA2, 0xB5, 0x4D, 0xA4, 0x3E, 0xD0, 0xAD, 0xAE, 0x0A, 0x2E, 0x53, 0x97, 0xA4, 0x7E, 0xEB, 0x8F, 0xB4, 0x33, 0x18, 0x30, 0x83, 0x52, 0xF9, 0x90, 0x33, 0x6B, 0x82, 0xC5, 0x03, 0xB9, 0x86, 0x36, 0x83, 0x34, 0xE7, 0x81, 0xD5, 0x04, 0x76, 0x40, 0x26, 0x21, 0x25, 0x48, 0x39, 0x97, 0x36, 0x15, 0xC0, 0x6A, 0x8C, 0x35, 0x53, 0x08};
|
||||
uint8_t sk[97] = {0x09, 0xCE, 0x58, 0xA7, 0x51, 0x82, 0xC7, 0x51, 0x1C, 0x62, 0x78, 0x26, 0x6C, 0xAC, 0x38, 0x1E, 0xEF, 0x6F, 0x4F, 0xE2, 0x5A, 0x7F, 0x95, 0x7D, 0xE4, 0x13, 0xD8, 0x43, 0x48, 0xCB, 0x19, 0x83, 0x64, 0x19, 0x75, 0x3E, 0x8D, 0x8F, 0xB6, 0x00, 0x5F, 0x6E, 0x2E, 0xA2, 0xB5, 0x4D, 0xA4, 0x3E, 0xD0, 0xAD, 0xAE, 0x0A, 0x2E, 0x53, 0x97, 0xA4, 0x7E, 0xEB, 0x8F, 0xB4, 0x33, 0x18, 0x30, 0x83, 0x52, 0xF9, 0x90, 0x33, 0x6B, 0x82, 0xC5, 0x03, 0xB9, 0x86, 0x36, 0x83, 0x34, 0xE7, 0x81, 0xD5, 0x04, 0x76, 0x40, 0x26, 0x21, 0x25, 0x48, 0x39, 0x97, 0x36, 0x15, 0xC0, 0x6A, 0x8C, 0x35, 0x53, 0x08};
|
||||
uint8_t expected_challenge[64] = {0x5B, 0xD1, 0x10, 0xA5, 0x25, 0x00, 0x1E, 0x15, 0xDE, 0xE0, 0xD7, 0xA0, 0x54, 0xF5, 0xDE, 0xF2, 0xB9, 0x0F, 0x03, 0x61, 0xC5, 0x6E, 0x34, 0x99, 0xE0, 0x6A, 0xAA, 0x12, 0x14, 0xBE, 0x1E, 0xD7, 0xDD, 0x92, 0x6F, 0xE5, 0x8E, 0x92, 0xDD, 0x97, 0x33, 0x70, 0x3F, 0x24, 0xE7, 0x28, 0x91, 0xBC, 0xB4, 0x7B, 0xB8, 0xE9, 0x68, 0x77, 0xCF, 0x6C, 0xDC, 0xDA, 0x51, 0x00, 0x01, 0xDB, 0x23, 0x11};
|
||||
uint8_t expected_salt[32] = {0x0C, 0x8B, 0x86, 0x35, 0x9D, 0x1B, 0xE6, 0x1D, 0x35, 0x35, 0xAC, 0x68, 0xCC, 0xF3, 0x36, 0x39, 0x73, 0x70, 0xB7, 0xF9, 0x16, 0x20, 0x80, 0xA7, 0xBF, 0xBB, 0x59, 0xFD, 0xF6, 0x03, 0x41, 0xE2};
|
||||
size_t expected_sig_len = 48576;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
int test_sign_Picnic_L1_full()
|
||||
{
|
||||
|
||||
uint8_t pk[35] = {0x0A, 0xF0, 0xE4, 0x68, 0xF4, 0x66, 0xB3, 0xC1, 0x63, 0x7B, 0xED, 0xAE, 0xBE, 0x4E, 0xC9, 0xEA, 0xF3, 0x80, 0x88, 0xD7, 0x6C, 0xBC, 0xC3, 0xEC, 0x71, 0xE0, 0x0E, 0x0D, 0x42, 0x7C, 0x9A, 0xB0, 0x91, 0x0A, 0x00};
|
||||
uint8_t sk[52] = {0x0A, 0x2B, 0x08, 0x4A, 0xAB, 0x0E, 0x55, 0xFB, 0xAA, 0x63, 0x3C, 0x13, 0x72, 0x72, 0xD0, 0xA5, 0x8A, 0x80, 0xF0, 0xE4, 0x68, 0xF4, 0x66, 0xB3, 0xC1, 0x63, 0x7B, 0xED, 0xAE, 0xBE, 0x4E, 0xC9, 0xEA, 0xF3, 0x80, 0x88, 0xD7, 0x6C, 0xBC, 0xC3, 0xEC, 0x71, 0xE0, 0x0E, 0x0D, 0x42, 0x7C, 0x9A, 0xB0, 0x91, 0x0A, 0x00};
|
||||
uint8_t expected_challenge[55] = {0x88, 0x62, 0x95, 0x02, 0x80, 0xA4, 0x94, 0x06, 0x52, 0x81, 0x94, 0x65, 0x10, 0x04, 0x5A, 0x5A, 0x26, 0x06, 0x48, 0x25, 0x92, 0xA4, 0x60, 0x45, 0x28, 0xA8, 0x04, 0x50, 0x58, 0x66, 0x84, 0x06, 0x44, 0x22, 0x4A, 0x66, 0x46, 0xA9, 0x41, 0x44, 0x19, 0x11, 0x56, 0x15, 0x04, 0x29, 0x15, 0x11, 0x68, 0x1A, 0x2A, 0x1A, 0x86, 0xA1, 0x88};
|
||||
uint8_t expected_salt[32] = {0x15, 0x4A, 0x74, 0xAD, 0x05, 0xD1, 0x1D, 0xDD, 0xEE, 0xC8, 0x7C, 0x93, 0x38, 0xC1, 0x49, 0x6E, 0xF1, 0xA8, 0xAB, 0xB7, 0xF5, 0x55, 0x30, 0x15, 0xBE, 0xE2, 0x0B, 0x58, 0x9B, 0x97, 0xC4, 0x9A};
|
||||
size_t expected_sig_len = 30786;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
int test_sign_Picnic_L3_full()
|
||||
{
|
||||
|
||||
uint8_t pk[49] = {0x0B, 0x31, 0x32, 0x8A, 0x63, 0xE2, 0x7B, 0x39, 0x33, 0x1A, 0x29, 0x22, 0xAA, 0xEB, 0x05, 0xBC, 0xAB, 0xCB, 0x94, 0x89, 0x03, 0xAC, 0x30, 0x9A, 0xD0, 0x6C, 0x00, 0x63, 0x40, 0x0D, 0xA0, 0xDA, 0x99, 0x19, 0x9F, 0xE6, 0xCA, 0x3E, 0x6D, 0xBC, 0x73, 0x30, 0xEF, 0xF9, 0x64, 0x3E, 0x85, 0x7D, 0x97};
|
||||
uint8_t sk[73] = {0x0B, 0x79, 0x68, 0x54, 0xF1, 0x54, 0x2C, 0x4F, 0xB8, 0xD2, 0x26, 0xBE, 0x04, 0x33, 0xDD, 0x18, 0xF1, 0x04, 0x86, 0x90, 0xDA, 0x92, 0xE3, 0x5A, 0xCE, 0x31, 0x32, 0x8A, 0x63, 0xE2, 0x7B, 0x39, 0x33, 0x1A, 0x29, 0x22, 0xAA, 0xEB, 0x05, 0xBC, 0xAB, 0xCB, 0x94, 0x89, 0x03, 0xAC, 0x30, 0x9A, 0xD0, 0x6C, 0x00, 0x63, 0x40, 0x0D, 0xA0, 0xDA, 0x99, 0x19, 0x9F, 0xE6, 0xCA, 0x3E, 0x6D, 0xBC, 0x73, 0x30, 0xEF, 0xF9, 0x64, 0x3E, 0x85, 0x7D, 0x97};
|
||||
uint8_t expected_challenge[83] = {0x44, 0xA2, 0x25, 0x45, 0x51, 0x60, 0x1A, 0x91, 0x5A, 0x64, 0x49, 0x04, 0x4A, 0x0A, 0x98, 0x81, 0x90, 0x82, 0x85, 0x0A, 0x09, 0x6A, 0x89, 0x8A, 0x85, 0x10, 0x96, 0x85, 0x04, 0x19, 0xA5, 0x69, 0xA8, 0x92, 0xA1, 0x45, 0x40, 0x45, 0xA6, 0x1A, 0x29, 0x84, 0x28, 0x68, 0x14, 0x81, 0x40, 0x00, 0xA9, 0x60, 0x51, 0x61, 0x29, 0x68, 0x16, 0x11, 0x22, 0x15, 0x85, 0x46, 0x60, 0x66, 0x22, 0xA1, 0x88, 0xA4, 0x98, 0x4A, 0x41, 0x95, 0x6A, 0xAA, 0x81, 0x80, 0x64, 0x28, 0x2A, 0x95, 0x42, 0x16, 0x19, 0x9A, 0x00};
|
||||
uint8_t expected_salt[32] = {0xA4, 0xB4, 0x3E, 0x72, 0xD2, 0xE7, 0x70, 0x9E, 0xAD, 0x11, 0xB2, 0x64, 0xC4, 0x97, 0x29, 0x9F, 0x5D, 0x49, 0x43, 0x1A, 0xFF, 0x22, 0x5D, 0xAD, 0xCD, 0x99, 0xD1, 0x6D, 0xBD, 0x9E, 0x58, 0xE1};
|
||||
size_t expected_sig_len = 68611;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
int test_sign_Picnic_L5_full()
|
||||
{
|
||||
uint8_t pk[65] = {0x0C, 0x2A, 0xF8, 0xCE, 0xBD, 0x72, 0x34, 0x30, 0x9D, 0x94, 0xB3, 0x08, 0xF7, 0xAD, 0xE1, 0x54, 0x13, 0xB6, 0xBB, 0x60, 0xBA, 0xCE, 0xF6, 0x31, 0x2B, 0xB5, 0xAA, 0x09, 0x25, 0x37, 0x0E, 0x2D, 0x00, 0x30, 0xAF, 0x6F, 0x08, 0x32, 0x92, 0xEB, 0x93, 0x6C, 0x1E, 0x89, 0xE1, 0x90, 0xCB, 0x08, 0x89, 0x6F, 0x70, 0xFB, 0xBD, 0x1D, 0xDC, 0x52, 0xEB, 0x26, 0xC4, 0xD2, 0xFE, 0xF7, 0xDC, 0xE4, 0x64};
|
||||
uint8_t sk[97] = {0x0C, 0xF4, 0x76, 0x0B, 0x37, 0xBA, 0x6F, 0xEB, 0x62, 0xD1, 0x5E, 0xAC, 0x5F, 0x96, 0xDE, 0x8C, 0x22, 0x2B, 0x99, 0x80, 0xB5, 0x9B, 0x0F, 0x05, 0xF7, 0xFB, 0x6F, 0x18, 0xCD, 0x31, 0x6A, 0xB0, 0x6A, 0x2A, 0xF8, 0xCE, 0xBD, 0x72, 0x34, 0x30, 0x9D, 0x94, 0xB3, 0x08, 0xF7, 0xAD, 0xE1, 0x54, 0x13, 0xB6, 0xBB, 0x60, 0xBA, 0xCE, 0xF6, 0x31, 0x2B, 0xB5, 0xAA, 0x09, 0x25, 0x37, 0x0E, 0x2D, 0x00, 0x30, 0xAF, 0x6F, 0x08, 0x32, 0x92, 0xEB, 0x93, 0x6C, 0x1E, 0x89, 0xE1, 0x90, 0xCB, 0x08, 0x89, 0x6F, 0x70, 0xFB, 0xBD, 0x1D, 0xDC, 0x52, 0xEB, 0x26, 0xC4, 0xD2, 0xFE, 0xF7, 0xDC, 0xE4, 0x64};
|
||||
uint8_t expected_challenge[110] = {0x24, 0xA2, 0x94, 0x5A, 0x50, 0x54, 0x92, 0x58, 0x42, 0x61, 0x56, 0x09, 0x29, 0x84, 0x48, 0x89, 0x26, 0x04, 0x46, 0x60, 0x10, 0x44, 0x16, 0x48, 0x45, 0x18, 0x20, 0x81, 0x0A, 0x68, 0x60, 0x02, 0xA1, 0x19, 0x56, 0x89, 0x15, 0x22, 0x60, 0x54, 0x84, 0x41, 0xA5, 0x42, 0x29, 0x65, 0x60, 0xAA, 0x66, 0x8A, 0x41, 0x84, 0x12, 0x00, 0x98, 0x00, 0x0A, 0x54, 0x25, 0x19, 0x52, 0x15, 0x60, 0x52, 0x41, 0x81, 0x58, 0xA1, 0x80, 0xA2, 0x25, 0x44, 0x89, 0x51, 0x06, 0x64, 0x48, 0x41, 0x81, 0x52, 0x29, 0xA1, 0x80, 0x18, 0x42, 0xA6, 0x44, 0x98, 0x02, 0x9A, 0x95, 0x4A, 0x54, 0x14, 0x52, 0x42, 0x19, 0x95, 0x01, 0x62, 0x06, 0x4A, 0x95, 0x55, 0x52, 0xA4, 0x52, 0x60, 0x11, 0x60};
|
||||
uint8_t expected_salt[32] = {0x26, 0x66, 0xE8, 0x95, 0xAB, 0x6F, 0x25, 0x46, 0x9C, 0x01, 0x34, 0xC3, 0xA6, 0x71, 0x09, 0x2B, 0xD3, 0x63, 0xB9, 0x03, 0xFC, 0x80, 0xDD, 0x69, 0x8E, 0x05, 0xC4, 0x82, 0x89, 0xCC, 0x16, 0xCE};
|
||||
size_t expected_sig_len = 121262;
|
||||
|
||||
return do_test_sign(pk, sizeof(pk), sk, sizeof(sk), expected_challenge, sizeof(expected_challenge), expected_salt, sizeof(expected_salt), expected_sig_len);
|
||||
}
|
||||
|
||||
static int picnic_test_modified_signatures(picnic_params_t parameters) {
|
||||
const size_t max_signature_size = picnic_signature_size(parameters);
|
||||
if (!max_signature_size) {
|
||||
/* not supported */
|
||||
return 0;
|
||||
}
|
||||
|
||||
picnic_publickey_t pk;
|
||||
picnic_privatekey_t sk;
|
||||
|
||||
int ret = picnic_keygen(parameters, &pk, &sk);
|
||||
if (ret != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* signature = malloc(max_signature_size);
|
||||
uint8_t* message = malloc(MSG_LEN);
|
||||
if (!signature || !message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fill message with some data */
|
||||
memset(message, rand() & 0xFF, MSG_LEN);
|
||||
|
||||
size_t signature_len = max_signature_size;
|
||||
ret = picnic_sign(&sk, message, MSG_LEN, signature, &signature_len);
|
||||
if (ret != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* must verify */
|
||||
ret = picnic_verify(&pk, message, MSG_LEN, signature, signature_len);
|
||||
if (ret != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// printf("Signature is %lu bytes long\n", signature_len);
|
||||
for (size_t l = 0; l < signature_len; l += signature_len/50) {
|
||||
|
||||
signature[l] += 1;
|
||||
|
||||
/* must fail */
|
||||
ret = picnic_verify(&pk, message, MSG_LEN, signature, signature_len);
|
||||
if (!ret) {
|
||||
printf("Failed when mauling byte number %lu, byte value = %u\n", l, signature[l]);
|
||||
printHex("signature", signature, signature_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
signature[l] -= 1;
|
||||
}
|
||||
|
||||
free(message);
|
||||
free(signature);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int passed = 0;
|
||||
int tests_run = 0;
|
||||
|
||||
// printNewKeypair(Picnic_L1_full);
|
||||
passed += LowMC_test_vectorL1_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL1_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL1_3(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_3(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_3(); tests_run++;
|
||||
passed += test_serialization_L1(); tests_run++;
|
||||
|
||||
passed += LowMC_test_vectorL1_129_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL1_129_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL1_129_3(); tests_run++;
|
||||
passed += LowMC_test_vectorL1_129_4(); tests_run++;
|
||||
|
||||
passed += LowMC_test_vectorL3_192_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_192_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_192_3(); tests_run++;
|
||||
passed += LowMC_test_vectorL3_192_4(); tests_run++;
|
||||
|
||||
passed += LowMC_test_vectorL5_255_1(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_255_2(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_255_3(); tests_run++;
|
||||
passed += LowMC_test_vectorL5_255_4(); tests_run++;
|
||||
|
||||
passed += test_sign_Picnic3_L1(); tests_run++;
|
||||
passed += test_sign_Picnic3_L3(); tests_run++;
|
||||
passed += test_sign_Picnic3_L5(); tests_run++;
|
||||
passed += test_sign_Picnic_L1_full(); tests_run++;
|
||||
passed += test_sign_Picnic_L3_full(); tests_run++;
|
||||
passed += test_sign_Picnic_L5_full(); tests_run++;
|
||||
|
||||
for(int i = Picnic3_L1; i <= Picnic3_L5; i++) {
|
||||
passed += test_serialize_roundtrip_picnic3(i); tests_run++;
|
||||
passed += test_sig_serialize_picnic3(i); tests_run++;
|
||||
}
|
||||
|
||||
(void) argv; // unused
|
||||
if(argc > 1) { /* If any command line args are given, run the extended, slow tests */
|
||||
for(int i = Picnic_L1_FS; i < PARAMETER_SET_MAX_INDEX; i++) {
|
||||
printf("Running extended sig tests for params %s\n", picnic_get_param_name(i));
|
||||
int ret = picnic_test_modified_signatures(i);
|
||||
if(ret != 1) {
|
||||
printf("Failed\n");
|
||||
}
|
||||
passed += ret;
|
||||
tests_run++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Ran %d tests, %d passed\n", tests_run, passed);
|
||||
|
||||
return tests_run - passed;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <pqc/pqc.h>
|
||||
|
||||
TEST(Kyber,KEMOneOff) {
|
||||
TEST(RoundTrip,KEM) {
|
||||
|
||||
for (int i=0; i<PQC_ALG_KEM_MAX; i++) {
|
||||
const params_t *p = pqc_kem_alg_by_id(i);
|
||||
@ -25,9 +25,9 @@ TEST(Kyber,KEMOneOff) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Kyber,SIGNOneOff) {
|
||||
TEST(RoundTrip,SIGN) {
|
||||
|
||||
for (int i=0; i<PQC_ALG_SIG_MAX; i++) {
|
||||
for (int i=PICNIC3L1; i<PQC_ALG_SIG_MAX; i++) {
|
||||
const params_t *p = pqc_sig_alg_by_id(i);
|
||||
|
||||
uint8_t msg[1234];
|
||||
|
불러오는 중...
Reference in New Issue
Block a user