Skip to content

Commit

Permalink
Update spec and implementation to version 3.0
Browse files Browse the repository at this point in the history
- Add version 3.0 of the specification document, under /spec.
- Version 3.0 replaces pincic2-* with picnic3-* and adds three new
  parameter sets picnic-*-full. Details of picnic3 are in the paper
  spec/picnic3-eprint.pdf
- Update implementation to match version 3.0 of the spec.
- Update design document to version 2.2, with updated QROM analysis
  based on the work of Don, Fehr, Majenz and Schaffner (see ePrint
  2019/190)

Signed-off-by: Greg Zaverucha <[email protected]>
  • Loading branch information
zaverucha committed Apr 15, 2020
1 parent 49ec978 commit c56abd3
Show file tree
Hide file tree
Showing 28 changed files with 1,525 additions and 730 deletions.
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
Greg Zaverucha
Sebastian Ramacher
Daniel Kales
Steven Goldfeder

This reference implementation is derived from the earlier Picnic implementation
at https://github.com/Microsoft/Picnic by Steven Goldfeder and Greg Zaverucha.
Expand Down
19 changes: 7 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ SHA3LIB=libshake.a
SHA3_PATH=sha3
LDFLAGS= $(SHA3_PATH)/$(SHA3LIB)

SOURCES= picnic_impl.c picnic2_impl.c picnic.c lowmc_constants.c
PICNIC_OBJECTS= picnic_impl.o picnic2_impl.o picnic.o lowmc_constants.o hash.o picnic_types.o tree.o
SOURCES= picnic_impl.c picnic3_impl.c picnic.c lowmc_constants.c
PICNIC_OBJECTS= picnic_impl.o picnic3_impl.o picnic.o lowmc_constants.o hash.o picnic_types.o tree.o
PICNIC_LIB= libpicnic.a
EXECUTABLE_EXAMPLE=example
EXECUTABLE_TESTVECTORS=create_test_vectors
EXECUTABLE_UNITTEST=unit_test
EXECUTABLE_BENCHMARK=bench
EXECUTABLE_KATSTEST=kats_test
EXECUTABLE_TREETEST=tree_test

Expand All @@ -27,22 +26,19 @@ $(SHA3LIB):
debug: CFLAGS = $(CFLAGS_DEBUG)
debug: all

$(EXECUTABLE_EXAMPLE): $(PICNIC_LIB)
$(EXECUTABLE_EXAMPLE): $(EXECUTABLE_EXAMPLE).c $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

$(EXECUTABLE_UNITTEST): $(PICNIC_LIB)
$(EXECUTABLE_UNITTEST): $(EXECUTABLE_UNITTEST).c $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

$(EXECUTABLE_TREETEST): $(PICNIC_LIB)
$(EXECUTABLE_TREETEST): $(EXECUTABLE_TREETEST).c $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

$(EXECUTABLE_TESTVECTORS): $(PICNIC_LIB)
$(EXECUTABLE_TESTVECTORS): $(EXECUTABLE_TESTVECTORS).c $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

$(EXECUTABLE_BENCHMARK): $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

$(EXECUTABLE_KATSTEST): $(PICNIC_LIB)
$(EXECUTABLE_KATSTEST): $(EXECUTABLE_KATSTEST).c $(PICNIC_LIB)
$(CC) $(@).c $(CFLAGS) $(PICNIC_LIB) -o $@ $(LDFLAGS)

.c.o:
Expand All @@ -60,7 +56,6 @@ clean:
rm $(EXECUTABLE_TREETEST) 2>/dev/null || true
rm $(EXECUTABLE_KATSTEST) 2>/dev/null || true
rm $(EXECUTABLE_TESTVECTORS) 2>/dev/null || true
rm $(EXECUTABLE_BENCHMARK) 2>/dev/null || true
rm $(PICNIC_LIB) 2>/dev/null || true
$(MAKE) -C $(SHA3_PATH) clean

5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Picnic signature scheme is a family of digital signature schemes secure
against attacks by quantum computers. This is a reference implementation of these schemes.
The scheme and parameter sets are specified in the [Picnic Specification Document](https://github.com/Microsoft/Picnic/blob/master/spec).

A research papers describing the signature scheme are also available on the [Picnic website](https://microsoft.github.io/Picnic/).
Research papers describing the signature scheme are also available on the [Picnic website](https://microsoft.github.io/Picnic/).

The library is provided under the MIT License. The authors are Steven Goldfeder and Greg Zaverucha.

Expand All @@ -15,8 +15,7 @@ The library builds a static library. The public API surface is defined in [picn
Tested on Ubuntu Linux, and the Windows Subsystem for Linux on Windows 10 (build 1709).

1. `make`
This will build the project. `make debug` will build with symbols and address
sanitizer.
This will build the project. `make debug` will build with symbols.

2. `./example`
Runs an example program that exercises the keygen, sign, verify and
Expand Down
12 changes: 8 additions & 4 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
#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)
{
Expand All @@ -26,11 +30,11 @@ void HashUpdate(HashInstance* ctx, const uint8_t* data, size_t byteLen)

void HashInit(HashInstance* ctx, paramset_t* params, uint8_t hashPrefix)
{
if (params->stateSizeBits == 128) { /* L1 */
Keccak_HashInitialize_SHAKE128(ctx);
if (params->stateSizeBits == 128 || params->stateSizeBits == 129) {
Keccak_HashInitialize_SHAKE128(ctx); /* L1 */
}
else { /* L3, L5 */
Keccak_HashInitialize_SHAKE256(ctx);
else {
Keccak_HashInitialize_SHAKE256(ctx); /* L3, L5 */
}

if (hashPrefix != HASH_PREFIX_NONE) {
Expand Down
10 changes: 10 additions & 0 deletions kats/kat_l1_full.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions kats/kat_l3_full.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions kats/kat_l5_full.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions kats/kat_picnic3_l1.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions kats/kat_picnic3_l3.txt

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions kats/kat_picnic3_l5.txt

Large diffs are not rendered by default.

69 changes: 50 additions & 19 deletions kats_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@
#define LOWMC_BLOCK_SIZE_Picnic_L3_UR 24
#define LOWMC_BLOCK_SIZE_Picnic_L5_FS 32
#define LOWMC_BLOCK_SIZE_Picnic_L5_UR 32
#define LOWMC_BLOCK_SIZE_Picnic2_L1_FS 16
#define LOWMC_BLOCK_SIZE_Picnic2_L3_FS 24
#define LOWMC_BLOCK_SIZE_Picnic2_L5_FS 32
#define LOWMC_BLOCK_SIZE_Picnic3_L1 17
#define LOWMC_BLOCK_SIZE_Picnic3_L3 24
#define LOWMC_BLOCK_SIZE_Picnic3_L5 32
#define LOWMC_BLOCK_SIZE_Picnic_L1_full 17
#define LOWMC_BLOCK_SIZE_Picnic_L3_full 24
#define LOWMC_BLOCK_SIZE_Picnic_L5_full 32


#define LOWMC_BLOCK_SIZE(p) PICNIC_CONCAT(LOWMC_BLOCK_SIZE, p)

Expand Down Expand Up @@ -264,37 +268,64 @@ static int picnic_test_vector_L5UR(void) {
PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_FS));
}

static int picnic2_test_vector_L1FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic2_l1_fs.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic2_L1_FS),
PICNIC_PRIVATE_KEY_SIZE(Picnic2_L1_FS));
static int picnic3_test_vector_L1FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic3_l1.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic3_L1),
PICNIC_PRIVATE_KEY_SIZE(Picnic3_L1));
}

static int picnic3_test_vector_L3FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic3_l3.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic3_L3),
PICNIC_PRIVATE_KEY_SIZE(Picnic3_L3));
}

static int picnic3_test_vector_L5FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic3_l5.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic3_L5),
PICNIC_PRIVATE_KEY_SIZE(Picnic3_L5));
}

static int picnic2_test_vector_L3FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic2_l3_fs.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic2_L3_FS),
PICNIC_PRIVATE_KEY_SIZE(Picnic2_L3_FS));
static int picnic_test_vector_L1full(void) {
return run_test_vectors_from_file(KATDIR "/kat_l1_full.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic_L1_full),
PICNIC_PRIVATE_KEY_SIZE(Picnic_L1_full));
}

static int picnic2_test_vector_L5FS(void) {
return run_test_vectors_from_file(KATDIR "/kat_picnic2_l5_fs.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic2_L5_FS),
PICNIC_PRIVATE_KEY_SIZE(Picnic2_L5_FS));
static int picnic_test_vector_L3full(void) {
return run_test_vectors_from_file(KATDIR "/kat_l3_full.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic_L3_full),
PICNIC_PRIVATE_KEY_SIZE(Picnic_L3_full));
}

static int picnic_test_vector_L5full(void) {
return run_test_vectors_from_file(KATDIR "/kat_l5_full.txt", PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_full),
PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_full));
}


typedef int (*test_fn_t)(void);

static const test_fn_t tests[] = {picnic_test_vector_L1FS, picnic_test_vector_L1UR,
picnic_test_vector_L3FS, picnic_test_vector_L3UR,
picnic_test_vector_L5FS, picnic_test_vector_L5UR,
picnic2_test_vector_L1FS, picnic2_test_vector_L3FS,
picnic2_test_vector_L5FS};
#if 1
static const test_fn_t tests[] = { NULL, // 0
picnic_test_vector_L1FS, // 1
picnic_test_vector_L1UR, // 2
picnic_test_vector_L3FS,
picnic_test_vector_L3UR,
picnic_test_vector_L5FS,
picnic_test_vector_L5UR,
picnic3_test_vector_L1FS, //7
picnic3_test_vector_L3FS,
picnic3_test_vector_L5FS,
picnic_test_vector_L1full, //9
picnic_test_vector_L3full,
picnic_test_vector_L5full};
#endif
//static const test_fn_t tests[] = {picnic3_test_vector_L1FS};

static const size_t num_tests = sizeof(tests) / sizeof(tests[0]);

int main(void) {
int ret = 0;
for (size_t s = 0; s < num_tests; ++s) {
for (size_t s = 1; s < num_tests; ++s) {
const int t = tests[s]();
if (!t) {
printf("ERR: Picnic KAT test %zu FAILED (%d)\n", s, t);
printf("ERR: Picnic KAT test %s %zu FAILED (%d)\n", picnic_get_param_name(s), s, t );
ret = -1;
}
}
Expand Down
127 changes: 124 additions & 3 deletions lowmc_constants.c

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions lowmc_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@

#define WORD_SIZE_BITS 32 // the word size for the implementation. Not a LowMC parameter
#define LOWMC_MAX_STATE_SIZE 64
#define LOWMC_MAX_WORDS (LOWMC_MAX_STATE_SIZE/sizeof(uint32_t))
#define LOWMC_MAX_KEY_BITS 256
#define LOWMC_MAX_AND_GATES (3*38*10 + 4) /* Rounded to nearest byte */

/* Return the LowMC linear matrix for this round */
const uint32_t* LMatrix(uint32_t round, paramset_t* params);
/* Return the LowMC inverse linear layer matrix for this round */
const uint32_t* LMatrixInv(uint32_t round, paramset_t* params);

/* Return the LowMC key matrix for this round */
const uint32_t* KMatrix(uint32_t round, paramset_t* params);
/* Return the LowMC inverse key matrix for this round */
const uint32_t* KMatrixInv(uint32_t round, paramset_t* params);

/* Return the LowMC round constant for this round */
const uint32_t* RConstant(uint32_t round, paramset_t* params);
Expand Down
Loading

0 comments on commit c56abd3

Please sign in to comment.