mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-12-06 00:01:28 -05:00
Updated picnic to v.2.1.2 (#650)
* Updated picnic to v.2.1.2 * Enabled avx2 sha3 code
This commit is contained in:
parent
7e9571a972
commit
920a2747b3
@ -31,7 +31,7 @@ Implementation
|
||||
--------------
|
||||
|
||||
- **Source of implementation:** https://github.com/IAIK/Picnic
|
||||
- **Implementation version:** https://github.com/IAIK/Picnic/tree/v2.1.1
|
||||
- **Implementation version:** https://github.com/IAIK/Picnic/tree/v2.1.2
|
||||
- **License:** MIT License
|
||||
- **Language:** C
|
||||
- **Constant-time:** Yes
|
||||
|
||||
@ -20,35 +20,53 @@ set(SRCS sig_picnic.c
|
||||
external/mzd_additional.c
|
||||
external/picnic.c
|
||||
external/picnic_impl.c
|
||||
external/picnic_instances.c
|
||||
external/picnic2_impl.c
|
||||
external/picnic2_simulate.c
|
||||
external/picnic2_simulate_mul.c
|
||||
external/picnic2_tree.c
|
||||
external/picnic2_types.c
|
||||
external/sha3/KeccakHash.c
|
||||
external/sha3/KeccakSpongeWidth1600.c
|
||||
external/sha3/KeccakHashtimes4.c
|
||||
external/sha3/KeccakSpongeWidth1600times4.c
|
||||
external/sha3/opt64/KeccakP-1600-opt64.c
|
||||
external/sha3/opt64/KeccakP-1600-times4-on1.c)
|
||||
|
||||
external/sha3/KeccakSpongeWidth1600.c)
|
||||
if(OQS_USE_AVX2_INSTRUCTIONS)
|
||||
set(SRCS ${SRCS}
|
||||
external/sha3/avx2/KeccakP-1600-AVX2.s
|
||||
external/sha3/avx2/KeccakP-1600-times4-SIMD256.c
|
||||
external/sha3/KeccakSpongeWidth1600times4.c
|
||||
external/sha3/KeccakHashtimes4.c)
|
||||
else()
|
||||
set(SRCS ${SRCS}
|
||||
external/sha3/opt64/KeccakP-1600-opt64.c)
|
||||
endif()
|
||||
add_library(picnic OBJECT ${SRCS})
|
||||
target_include_directories(picnic PRIVATE external
|
||||
external/sha3
|
||||
external/sha3/opt64)
|
||||
external/sha3)
|
||||
if(OQS_USE_AVX2_INSTRUCTIONS)
|
||||
target_include_directories(picnic PRIVATE external/sha3/avx2)
|
||||
else()
|
||||
target_include_directories(picnic PRIVATE external/sha3/opt64)
|
||||
endif()
|
||||
target_compile_definitions(picnic PRIVATE PICNIC_STATIC
|
||||
OPTIMIZED_LINEAR_LAYER_EVALUATION
|
||||
REDUCED_ROUND_KEY_COMPUTATION
|
||||
WITH_ZKBPP
|
||||
WITH_KKW
|
||||
WITH_LOWMC_128_128_20
|
||||
WITH_LOWMC_192_192_30
|
||||
WITH_LOWMC_256_256_38
|
||||
WITH_OPT
|
||||
WITH_POPCNT)
|
||||
WITH_OPT)
|
||||
if(NOT WIN32)
|
||||
target_compile_definitions(picnic PRIVATE HAVE_POSIX_MEMALIGN)
|
||||
endif()
|
||||
|
||||
if(OQS_USE_AVX2_INSTRUCTIONS AND OQS_USE_SSE2_INSTRUCTIONS)
|
||||
target_compile_definitions(picnic PRIVATE WITH_AVX2)
|
||||
if(OQS_USE_SSE2_INSTRUCTIONS)
|
||||
target_compile_definitions(picnic PRIVATE WITH_SSE2)
|
||||
endif()
|
||||
if(OQS_USE_AVX2_INSTRUCTIONS AND OQS_USE_BMI2_INSTRUCTIONS)
|
||||
target_compile_definitions(picnic PRIVATE WITH_AVX2)
|
||||
endif()
|
||||
#FIXMEOQS: enable NEON detection
|
||||
#if(OQS_USE_NEON_INSTRUCTIONS)
|
||||
# target_compile_definitions(picnic PRIVATE WITH_NEON)
|
||||
#endif()
|
||||
|
||||
|
||||
65
src/sig/picnic/external/CHANGELOG.md
vendored
Normal file
65
src/sig/picnic/external/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
Version 2.1.2 -- 2019-10-03
|
||||
---------------------------
|
||||
|
||||
* Enable to build with ZKB++- or KKW-based instances only.
|
||||
* Fix ARM NEON optimizations.
|
||||
* Slightly reduce heap usage.
|
||||
* Remove more unused code.
|
||||
|
||||
Version 2.1.1 -- 2019-08-07
|
||||
---------------------------
|
||||
|
||||
* Various small improvements and bug fixes.
|
||||
|
||||
Version 2.1 -- 2019-07-29
|
||||
-------------------------
|
||||
|
||||
* Remove M4RM-based implementation.
|
||||
* Fix input size in Picnic2's commitment implementation.
|
||||
* Additional improvements and optimizations of the Picnic2 code.
|
||||
|
||||
Version 2.0 -- 2019-04-08
|
||||
-------------------------
|
||||
|
||||
* Implement Picnic 2.
|
||||
* Use 4-times parallel SHAKE3 for faster PRF evaluation, commitment generation, etc.
|
||||
* Fix size of salts to 32 bytes.
|
||||
|
||||
Version 1.3.1 -- 2018-12-21
|
||||
---------------------------
|
||||
|
||||
* Reduce heap usage.
|
||||
|
||||
Version 1.3 -- 2018-12-21
|
||||
-------------------------
|
||||
|
||||
* Implement linear layer optimizations to speed up LowMC evaluations. Besides the runtime improvements, this optimization also greatly reduces the memory size of the LowMC instances.
|
||||
* Provide LowMC instances with m=1 to demonstrate feasibility of those instances.
|
||||
* Slightly improve internal storage of matrices to require less memory.
|
||||
* Remove unused code and support for dynamic LowMC instances.
|
||||
|
||||
Version 1.2 -- 2018-12-05
|
||||
-------------------------
|
||||
|
||||
* Implement RRKC optimizations for round constants.
|
||||
* Compatibility fixes for Mac OS X.
|
||||
* Reduce memory usage when using Fiat-Shamir and Unruh transform in the same process.
|
||||
* Fix deviations from specification. The KDF was missing the output length as input and the public key was incorrectly serialized. Note that this change requires an update of the test vectors.
|
||||
* Update SHA3 implementation and fix endiannes bug on big-endian.
|
||||
* Record state before Sbox evaluation and drop one branch of XOR computations. This optimization is based based on an idea by Markus Schofnegger.
|
||||
* Add per-signature salt to random tapes generation. Prevents a seed-guessing attack reported by Itai Dinur.
|
||||
|
||||
Version 1.1 -- 2018-06-29
|
||||
-------------------------
|
||||
|
||||
* Compatibility fixes for Visual Studio, clang and MinGW.
|
||||
* Various improvements to the SIMD versions of the matrix operations.
|
||||
* Default to constant-time matrix multiplication algorithms without lookup tables.
|
||||
* Add option to feed extra randomness to initial seed expansion to counter fault attacks.
|
||||
* Version submitted for inclusion in SUPERCOP.
|
||||
|
||||
Version 1.0 -- 2017-11-28
|
||||
-------------------------
|
||||
|
||||
* Initial release.
|
||||
* Version submitted to the NIST PQC project.
|
||||
1
src/sig/picnic/external/LICENSE
vendored
1
src/sig/picnic/external/LICENSE
vendored
@ -1,3 +1,4 @@
|
||||
Copyright (c) 2019 AIT Austrian Institute of Technology
|
||||
Copyright (c) 2016-2018 Graz University of Technology
|
||||
Copyright (c) 2017 Angela Promitzer
|
||||
|
||||
|
||||
8
src/sig/picnic/external/README.md
vendored
8
src/sig/picnic/external/README.md
vendored
@ -11,7 +11,7 @@ Research paper describing the signature scheme and the optimizations are also av
|
||||
Packages
|
||||
--------
|
||||
|
||||
Packages for Ubuntu bionic and cosmis are available via a [PPA](https://launchpad.net/~s-ramacher/+archive/ubuntu/picnic/).
|
||||
Packages for Ubuntu bionic, disco, and eoan are available via a [PPA](https://launchpad.net/~s-ramacher/+archive/ubuntu/picnic/).
|
||||
|
||||
Building
|
||||
--------
|
||||
@ -25,6 +25,8 @@ make
|
||||
```
|
||||
|
||||
The cmake based build system supports the following flags:
|
||||
* ``WITH_ZKBPP``: Enable ZKB++-based Picnic instances.
|
||||
* ``WITH_KKW``: Enable KKW-based Picnic instances.
|
||||
* ``WITH_SIMD_OPT``: Enable SIMD optimizations.
|
||||
* ``WITH_AVX2``: Use AVX2 if available.
|
||||
* ``WITH_SSE2``: Use SSE2 if available.
|
||||
@ -32,7 +34,7 @@ The cmake based build system supports the following flags:
|
||||
* ``WITH_MARCH_NATIVE``: Build with -march=native -mtune=native (if supported).
|
||||
* ``WITH_LTO``: Enable link-time optimization (if supported).
|
||||
* ``WITH_LOWMC_OPT={OFF,ORKC,OLLE}``: Enable optimized round key computation (ORKC) or optimized linear layer evaluation (OLLE) optimizations.
|
||||
* ``WITH_LOWMC_M1``: Enable LowMC instances with 1 Sbox minimizing the signature sizes.
|
||||
* ``WITH_LOWMC_M1``: Enable LowMC instances with 1 Sbox minimizing the signature sizes (only useful if built with ``WITH_ZKBPP`` on).
|
||||
|
||||
Building on Windows
|
||||
-------------------
|
||||
@ -59,6 +61,8 @@ SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
|
||||
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||
SET(CMAKE_DLLTOOL x86_64-w64-mingw32-dlltool)
|
||||
# use wine to execute tests
|
||||
set(CMAKE_CROSSCOMPILING_EMULATOR wine)
|
||||
|
||||
# target environment
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/)
|
||||
|
||||
2
src/sig/picnic/external/aligned_alloc.c
vendored
2
src/sig/picnic/external/aligned_alloc.c
vendored
@ -18,7 +18,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_MEMALIGN) && defined(__linux__)
|
||||
/* always availalbe on Linux */
|
||||
/* always available on Linux */
|
||||
#define HAVE_MEMALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
2
src/sig/picnic/external/bitstream.c
vendored
2
src/sig/picnic/external/bitstream.c
vendored
@ -88,6 +88,7 @@ uint32_t bitstream_get_bits_32(bitstream_t* bs, unsigned int num_bits) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(PICNIC_STATIC)
|
||||
void bitstream_put_bits(bitstream_t* bs, uint64_t value, unsigned int num_bits) {
|
||||
ASSUME(1 <= num_bits && num_bits <= 64);
|
||||
|
||||
@ -112,6 +113,7 @@ void bitstream_put_bits(bitstream_t* bs, uint64_t value, unsigned int num_bits)
|
||||
*p = (value & ((1 << num_bits) - 1)) << (8 - num_bits);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void bitstream_put_bits_8(bitstream_t* bs, uint8_t value, unsigned int num_bits) {
|
||||
ASSUME(1 <= num_bits && num_bits <= 8);
|
||||
|
||||
3
src/sig/picnic/external/bitstream.h
vendored
3
src/sig/picnic/external/bitstream.h
vendored
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#ifndef BITSTREAM_H
|
||||
#define BITSTREAM_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@ -24,7 +25,9 @@ typedef struct {
|
||||
uint64_t bitstream_get_bits(bitstream_t* bs, unsigned int num_bits);
|
||||
uint8_t bitstream_get_bits_8(bitstream_t* bs, unsigned int num_bits);
|
||||
uint32_t bitstream_get_bits_32(bitstream_t* bs, unsigned int num_bits);
|
||||
#if defined(PICNIC_STATIC)
|
||||
void bitstream_put_bits(bitstream_t* bs, uint64_t value, unsigned int num_bits);
|
||||
#endif
|
||||
void bitstream_put_bits_8(bitstream_t* bs, uint8_t value, unsigned int num_bits);
|
||||
void bitstream_put_bits_32(bitstream_t* bs, uint32_t value, unsigned int num_bits);
|
||||
|
||||
|
||||
2
src/sig/picnic/external/compat.h
vendored
2
src/sig/picnic/external/compat.h
vendored
@ -24,7 +24,7 @@
|
||||
#if defined(HAVE_ALIGNED_ALLOC)
|
||||
#include <stdlib.h>
|
||||
|
||||
#define aligned_free free
|
||||
#define aligned_free(ptr) free((ptr))
|
||||
#else
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
12
src/sig/picnic/external/cpu.c
vendored
12
src/sig/picnic/external/cpu.c
vendored
@ -9,9 +9,7 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
#else
|
||||
|
||||
/* If cmake checks were not run, define some known values. */
|
||||
|
||||
@ -22,7 +20,11 @@
|
||||
#if !defined(HAVE_ASM_HWCAP_H) && defined(__linux__) && defined(__arm__)
|
||||
#define HAVE_ASM_HWCAP_H
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#if !defined(BUILTIN_CPU_SUPPORTED)
|
||||
#if defined(__arm__) && defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H)
|
||||
#include <asm/hwcap.h>
|
||||
#include <sys/auxv.h>
|
||||
@ -141,3 +143,7 @@ bool cpu_supports(unsigned int caps) {
|
||||
|
||||
return cpu_caps & caps;
|
||||
}
|
||||
#endif
|
||||
|
||||
// OQS note: add a dummy definition to avoid empty translation unit (which might occur with -Werror=pedantic)
|
||||
typedef int avoid_empty_translation_unit;
|
||||
|
||||
7
src/sig/picnic/external/cpu.h
vendored
7
src/sig/picnic/external/cpu.h
vendored
@ -10,6 +10,12 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
#if defined(__GNUC__) && !(defined(__APPLE__) && (__clang_major__ <= 8)) && \
|
||||
!defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
#define BUILTIN_CPU_SUPPORTED
|
||||
#endif
|
||||
|
||||
#if !defined(BUILTIN_CPU_SUPPORTED)
|
||||
#include <stdbool.h>
|
||||
#include "oqs_picnic_macros.h"
|
||||
|
||||
@ -26,5 +32,6 @@
|
||||
* Helper function in case __builtin_cpu_supports is not available.
|
||||
*/
|
||||
bool cpu_supports(unsigned int caps);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
64
src/sig/picnic/external/kdf_shake.h
vendored
64
src/sig/picnic/external/kdf_shake.h
vendored
@ -37,12 +37,17 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "picnic_impl.h"
|
||||
#include "macros.h"
|
||||
#include "endian_compat.h"
|
||||
|
||||
typedef Keccak_HashInstance hash_context ATTR_ALIGNED(32);
|
||||
|
||||
static inline void hash_init(hash_context* ctx, const picnic_instance_t* pp) {
|
||||
if (pp->digest_size == 32) {
|
||||
/**
|
||||
* Initialize hash context based on the digest size used by Picnic. If the size is 32 bytes,
|
||||
* SHAKE128 is used, otherwise SHAKE256 is used.
|
||||
*/
|
||||
static inline void hash_init(hash_context* ctx, size_t digest_size) {
|
||||
if (digest_size == 32) {
|
||||
Keccak_HashInitialize_SHAKE128(ctx);
|
||||
} else {
|
||||
Keccak_HashInitialize_SHAKE256(ctx);
|
||||
@ -53,9 +58,14 @@ static inline void hash_update(hash_context* ctx, const uint8_t* data, size_t si
|
||||
Keccak_HashUpdate(ctx, data, size << 3);
|
||||
}
|
||||
|
||||
static inline void hash_init_prefix(hash_context* ctx, const picnic_instance_t* pp,
|
||||
static inline void hash_update_uint16_le(hash_context* ctx, uint16_t data) {
|
||||
const uint16_t data_le = htole16(data);
|
||||
hash_update(ctx, (const uint8_t*)&data_le, sizeof(data_le));
|
||||
}
|
||||
|
||||
static inline void hash_init_prefix(hash_context* ctx, size_t digest_size,
|
||||
const uint8_t prefix) {
|
||||
hash_init(ctx, pp);
|
||||
hash_init(ctx, digest_size);
|
||||
hash_update(ctx, &prefix, sizeof(prefix));
|
||||
}
|
||||
|
||||
@ -69,9 +79,10 @@ static inline void hash_squeeze(hash_context* ctx, uint8_t* buffer, size_t bufle
|
||||
|
||||
typedef hash_context kdf_shake_t;
|
||||
|
||||
#define kdf_shake_init(ctx, pp) hash_init((ctx), (pp))
|
||||
#define kdf_shake_init_prefix(ctx, pp, prefix) hash_init_prefix((ctx), (pp), (prefix))
|
||||
#define kdf_shake_init(ctx, digest_size) hash_init((ctx), (digest_size))
|
||||
#define kdf_shake_init_prefix(ctx, digest_size, prefix) hash_init_prefix((ctx), (digest_size), (prefix))
|
||||
#define kdf_shake_update_key(ctx, key, keylen) hash_update((ctx), (key), (keylen))
|
||||
#define kdf_shake_update_key_uint16_le(ctx, key) hash_update_uint16_le((ctx), (key))
|
||||
#define kdf_shake_finalize_key(ctx) hash_final((ctx))
|
||||
#define kdf_shake_get_randomness(ctx, dst, count) hash_squeeze((ctx), (dst), (count))
|
||||
#define kdf_shake_clear(ctx)
|
||||
@ -82,9 +93,9 @@ typedef struct hash_context_x4_s {
|
||||
hash_context instances[4];
|
||||
} hash_context_x4;
|
||||
|
||||
static inline void hash_init_x4(hash_context_x4* ctx, const picnic_instance_t* pp) {
|
||||
static inline void hash_init_x4(hash_context_x4* ctx, size_t digest_size) {
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
hash_init(&ctx->instances[i], pp);
|
||||
hash_init(&ctx->instances[i], digest_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,10 +105,10 @@ static inline void hash_update_x4(hash_context_x4* ctx, const uint8_t** data, si
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hash_init_prefix_x4(hash_context_x4* ctx, const picnic_instance_t* pp,
|
||||
static inline void hash_init_prefix_x4(hash_context_x4* ctx, size_t digest_size,
|
||||
const uint8_t prefix) {
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
hash_init_prefix(&ctx->instances[i], pp, prefix);
|
||||
hash_init_prefix(&ctx->instances[i], digest_size, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,8 +127,8 @@ static inline void hash_squeeze_x4(hash_context_x4* ctx, uint8_t** buffer, size_
|
||||
/* Instances that work with 4 states in parallel. */
|
||||
typedef Keccak_HashInstancetimes4 hash_context_x4 ATTR_ALIGNED(32);
|
||||
|
||||
static inline void hash_init_x4(hash_context_x4* ctx, const picnic_instance_t* pp) {
|
||||
if (pp->digest_size == 32) {
|
||||
static inline void hash_init_x4(hash_context_x4* ctx, size_t digest_size) {
|
||||
if (digest_size == 32) {
|
||||
Keccak_HashInitializetimes4_SHAKE128(ctx);
|
||||
} else {
|
||||
Keccak_HashInitializetimes4_SHAKE256(ctx);
|
||||
@ -128,9 +139,9 @@ static inline void hash_update_x4(hash_context_x4* ctx, const uint8_t** data, si
|
||||
Keccak_HashUpdatetimes4(ctx, data, size << 3);
|
||||
}
|
||||
|
||||
static inline void hash_init_prefix_x4(hash_context_x4* ctx, const picnic_instance_t* pp,
|
||||
static inline void hash_init_prefix_x4(hash_context_x4* ctx, size_t digest_size,
|
||||
const uint8_t prefix) {
|
||||
hash_init_x4(ctx, pp);
|
||||
hash_init_x4(ctx, digest_size);
|
||||
const uint8_t* prefixes[] = {&prefix, &prefix, &prefix, &prefix};
|
||||
hash_update_x4(ctx, prefixes, sizeof(prefix));
|
||||
}
|
||||
@ -144,11 +155,30 @@ static inline void hash_squeeze_x4(hash_context_x4* ctx, uint8_t** buffer, size_
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void hash_update_x4_uint16_le(hash_context_x4* ctx, uint16_t data) {
|
||||
const uint16_t data_le = htole16(data);
|
||||
const uint8_t* ptr[4] = {(const uint8_t*)&data_le, (const uint8_t*)&data_le,
|
||||
(const uint8_t*)&data_le, (const uint8_t*)&data_le};
|
||||
hash_update_x4(ctx, ptr, sizeof(data_le));
|
||||
}
|
||||
|
||||
static inline void hash_update_x4_uint16s_le(hash_context_x4* ctx, const uint16_t data[4]) {
|
||||
const uint16_t data0_le = htole16(data[0]);
|
||||
const uint16_t data1_le = htole16(data[1]);
|
||||
const uint16_t data2_le = htole16(data[2]);
|
||||
const uint16_t data3_le = htole16(data[3]);
|
||||
const uint8_t* ptr[4] = {(const uint8_t*)&data0_le, (const uint8_t*)&data1_le,
|
||||
(const uint8_t*)&data2_le, (const uint8_t*)&data3_le};
|
||||
hash_update_x4(ctx, ptr, sizeof(data[0]));
|
||||
}
|
||||
|
||||
typedef hash_context_x4 kdf_shake_x4_t;
|
||||
|
||||
#define kdf_shake_x4_init(ctx, pp) hash_init_x4((ctx), (pp))
|
||||
#define kdf_shake_x4_init_prefix(ctx, pp, prefix) hash_init_prefix_x4((ctx), (pp), (prefix))
|
||||
#define kdf_shake_x4_init(ctx, digest_size) hash_init_x4((ctx), (digest_size))
|
||||
#define kdf_shake_x4_init_prefix(ctx, digest_size, prefix) hash_init_prefix_x4((ctx), (digest_size), (prefix))
|
||||
#define kdf_shake_x4_update_key(ctx, key, keylen) hash_update_x4((ctx), (key), (keylen))
|
||||
#define kdf_shake_x4_update_key_uint16_le(ctx, key) hash_update_x4_uint16_le((ctx), (key))
|
||||
#define kdf_shake_x4_update_key_uint16s_le(ctx, keys) hash_update_x4_uint16s_le((ctx), (keys))
|
||||
#define kdf_shake_x4_finalize_key(ctx) hash_final_x4((ctx))
|
||||
#define kdf_shake_x4_get_randomness(ctx, dst, count) hash_squeeze_x4((ctx), (dst), (count))
|
||||
#define kdf_shake_x4_clear(ctx)
|
||||
|
||||
11
src/sig/picnic/external/lowmc.c
vendored
11
src/sig/picnic/external/lowmc.c
vendored
@ -13,10 +13,11 @@
|
||||
|
||||
#include "io.h"
|
||||
#include "lowmc.h"
|
||||
#include "lowmc_pars.h"
|
||||
#include "mzd_additional.h"
|
||||
#include "picnic2_impl.h"
|
||||
|
||||
#include "mzd_additional.h"
|
||||
#if defined(WITH_KKW)
|
||||
#include "picnic2_impl.h"
|
||||
#endif
|
||||
#if defined(WITH_OPT)
|
||||
#include "simd.h"
|
||||
#endif
|
||||
@ -287,6 +288,7 @@ lowmc_implementation_f lowmc_get_implementation(const lowmc_t* lowmc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(WITH_ZKBPP)
|
||||
lowmc_store_implementation_f lowmc_store_get_implementation(const lowmc_t* lowmc) {
|
||||
#if defined(WITH_LOWMC_M1)
|
||||
ASSUME(lowmc->m == 10 || lowmc->m == 1);
|
||||
@ -412,7 +414,9 @@ lowmc_store_implementation_f lowmc_store_get_implementation(const lowmc_t* lowmc
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_KKW)
|
||||
lowmc_compute_aux_implementation_f lowmc_compute_aux_get_implementation(const lowmc_t* lowmc) {
|
||||
#if defined(WITH_LOWMC_M1)
|
||||
ASSUME(lowmc->m == 10 || lowmc->m == 1);
|
||||
@ -483,3 +487,4 @@ lowmc_compute_aux_implementation_f lowmc_compute_aux_get_implementation(const lo
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
6
src/sig/picnic/external/lowmc.c.i
vendored
6
src/sig/picnic/external/lowmc.c.i
vendored
@ -21,11 +21,14 @@
|
||||
#define XOR_MC XOR_MC_10
|
||||
#include "lowmc_impl.c.i"
|
||||
|
||||
#if defined(WITH_ZKBPP)
|
||||
#undef N_LOWMC
|
||||
#define N_LOWMC CONCAT(LOWMC, store_10)
|
||||
#define RECORD_STATE
|
||||
#include "lowmc_impl.c.i"
|
||||
#endif
|
||||
|
||||
#if defined(WITH_KKW)
|
||||
#undef N_LOWMC
|
||||
#undef RECORD_STATE
|
||||
#undef SBOX
|
||||
@ -34,6 +37,7 @@
|
||||
#define N_LOWMC CONCAT(LOWMC, compute_aux_10)
|
||||
#define PICNIC2_AUX_COMPUTATION
|
||||
#include "lowmc_impl.c.i"
|
||||
#endif
|
||||
|
||||
#undef LOWMC_INSTANCE
|
||||
#undef LOWMC_M
|
||||
@ -64,10 +68,12 @@
|
||||
#define XOR_MC XOR_MC_1
|
||||
#include "lowmc_impl.c.i"
|
||||
|
||||
#if defined(WITH_ZKBPP)
|
||||
#undef N_LOWMC
|
||||
#define N_LOWMC CONCAT(LOWMC, store_1)
|
||||
#define RECORD_STATE
|
||||
#include "lowmc_impl.c.i"
|
||||
#endif
|
||||
|
||||
#undef LOWMC_INSTANCE
|
||||
#undef LOWMC_M
|
||||
|
||||
5
src/sig/picnic/external/lowmc_pars.h
vendored
5
src/sig/picnic/external/lowmc_pars.h
vendored
@ -16,6 +16,11 @@
|
||||
|
||||
typedef mzd_local_t lowmc_key_t;
|
||||
|
||||
#define MAX_LOWMC_BLOCK_SIZE 32
|
||||
#define MAX_LOWMC_BLOCK_SIZE_BITS (MAX_LOWMC_BLOCK_SIZE * 8)
|
||||
#define MAX_LOWMC_KEY_SIZE MAX_LOWMC_BLOCK_SIZE
|
||||
#define MAX_LOWMC_KEY_SIZE_BITS (MAX_LOWMC_KEY_SIZE * 8)
|
||||
|
||||
/**
|
||||
* Masks for 10 S-boxes.
|
||||
*/
|
||||
|
||||
2
src/sig/picnic/external/macros.h
vendored
2
src/sig/picnic/external/macros.h
vendored
@ -200,7 +200,7 @@ static inline uint64_t parity64_uint64(uint64_t in) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* helper functions to ocmpute number of leading zeroes */
|
||||
/* helper functions to compute number of leading zeroes */
|
||||
#if GNUC_CHECK(4, 7) || __has_builtin(__builtin_clz)
|
||||
ATTR_CONST
|
||||
static inline uint32_t clz(uint32_t x) {
|
||||
|
||||
13
src/sig/picnic/external/mpc_lowmc.c
vendored
13
src/sig/picnic/external/mpc_lowmc.c
vendored
@ -11,7 +11,6 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "lowmc_pars.h"
|
||||
#include "mpc_lowmc.h"
|
||||
#include "mzd_additional.h"
|
||||
|
||||
@ -639,26 +638,38 @@ static void mzd_share_uint64_256(mzd_local_t* r, const mzd_local_t* v1, const mz
|
||||
|
||||
#if defined(WITH_OPT)
|
||||
#if defined(WITH_SSE2) || defined(WITH_NEON)
|
||||
#if defined(WITH_SSE2)
|
||||
#define FN_ATTR ATTR_TARGET_SSE2
|
||||
#else
|
||||
#define FN_ATTR
|
||||
#endif
|
||||
|
||||
FN_ATTR
|
||||
static void mzd_share_s128_128(mzd_local_t* r, const mzd_local_t* v1, const mzd_local_t* v2,
|
||||
const mzd_local_t* v3) {
|
||||
mzd_xor_s128_128(r, v1, v2);
|
||||
mzd_xor_s128_128(r, r, v3);
|
||||
}
|
||||
|
||||
FN_ATTR
|
||||
static void mzd_share_s128_256(mzd_local_t* r, const mzd_local_t* v1, const mzd_local_t* v2,
|
||||
const mzd_local_t* v3) {
|
||||
mzd_xor_s128_256(r, v1, v2);
|
||||
mzd_xor_s128_256(r, r, v3);
|
||||
}
|
||||
|
||||
#undef FN_ATTR
|
||||
#endif
|
||||
|
||||
#if defined(WITH_AVX2)
|
||||
ATTR_TARGET_AVX2
|
||||
static void mzd_share_s256_128(mzd_local_t* r, const mzd_local_t* v1, const mzd_local_t* v2,
|
||||
const mzd_local_t* v3) {
|
||||
mzd_xor_s256_128(r, v1, v2);
|
||||
mzd_xor_s256_128(r, r, v3);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
static void mzd_share_s256_256(mzd_local_t* r, const mzd_local_t* v1, const mzd_local_t* v2,
|
||||
const mzd_local_t* v3) {
|
||||
mzd_xor_s256_256(r, v1, v2);
|
||||
|
||||
5
src/sig/picnic/external/mpc_lowmc.h
vendored
5
src/sig/picnic/external/mpc_lowmc.h
vendored
@ -13,7 +13,6 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "lowmc.h"
|
||||
#include "lowmc_pars.h"
|
||||
|
||||
/* Share count for proofs */
|
||||
#define SC_PROOF 3
|
||||
@ -31,8 +30,8 @@ typedef struct {
|
||||
mzd_local_t* s[SC_PROOF];
|
||||
} in_out_shares_t;
|
||||
|
||||
typedef void (*zkbpp_lowmc_implementation_f)(mpc_lowmc_key_t const*, mzd_local_t const*, view_t*,
|
||||
in_out_shares_t*, rvec_t*, recorded_state_t*);
|
||||
typedef void (*zkbpp_lowmc_implementation_f)(mzd_local_t const*, view_t*, in_out_shares_t*, rvec_t*,
|
||||
recorded_state_t*);
|
||||
typedef void (*zkbpp_lowmc_verify_implementation_f)(mzd_local_t const*, view_t*, in_out_shares_t*,
|
||||
rvec_t*, unsigned int);
|
||||
typedef void (*zkbpp_share_implementation_f)(mzd_local_t*, const mzd_local_t*, const mzd_local_t*,
|
||||
|
||||
6
src/sig/picnic/external/mpc_lowmc_impl.c.i
vendored
6
src/sig/picnic/external/mpc_lowmc_impl.c.i
vendored
@ -29,8 +29,8 @@
|
||||
#if defined(FN_ATTR)
|
||||
FN_ATTR
|
||||
#endif
|
||||
static void N_SIGN(mpc_lowmc_key_t const* lowmc_key, mzd_local_t const* p, view_t* views,
|
||||
in_out_shares_t* in_out_shares, rvec_t* rvec, recorded_state_t* recorded_state) {
|
||||
static void N_SIGN(mzd_local_t const* p, view_t* views, in_out_shares_t* in_out_shares,
|
||||
rvec_t* rvec, recorded_state_t* recorded_state) {
|
||||
#define reduced_shares (SC_PROOF - 1)
|
||||
#define MPC_LOOP_CONST_C(function, result, first, second, sc, c) \
|
||||
MPC_LOOP_CONST_C_0(function, result, first, second, sc)
|
||||
@ -41,7 +41,7 @@ static void N_SIGN(mpc_lowmc_key_t const* lowmc_key, mzd_local_t const* p, view_
|
||||
#define shares SC_PROOF
|
||||
#define sbox SBOX_SIGN
|
||||
|
||||
MPC_LOOP_SHARED_1(COPY, in_out_shares->s, lowmc_key, SC_PROOF);
|
||||
mpc_lowmc_key_t const* lowmc_key = &in_out_shares->s[0];
|
||||
++in_out_shares;
|
||||
|
||||
mzd_local_t x[SC_PROOF][((LOWMC_N) + 255) / 256];
|
||||
|
||||
45
src/sig/picnic/external/mzd_additional.c
vendored
45
src/sig/picnic/external/mzd_additional.c
vendored
@ -430,11 +430,7 @@ void mzd_mul_v_parity_uint64_256_3(mzd_local_t* c, mzd_local_t const* v, mzd_loc
|
||||
#if defined(WITH_SSE2) || defined(WITH_NEON)
|
||||
ATTR_TARGET_S128 ATTR_CONST static inline word128 mm128_compute_mask(const word idx,
|
||||
const size_t bit) {
|
||||
#if defined(WITH_SSE2)
|
||||
return _mm_set1_epi64x(-((idx >> bit) & 1));
|
||||
#else
|
||||
return vdupq_n_u64(-((idx >> bit) & 1));
|
||||
#endif
|
||||
return mm128_broadcast_u64(-((idx >> bit) & 1));
|
||||
}
|
||||
|
||||
ATTR_TARGET_S128
|
||||
@ -734,7 +730,7 @@ void mzd_addmul_v_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {_mm256_castsi128_si256(cblock->w128[0]),
|
||||
_mm256_setzero_si256()};
|
||||
mm256_zero};
|
||||
for (unsigned int w = 2; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 8, idx >>= 8, Ablock += 4) {
|
||||
@ -744,9 +740,9 @@ void mzd_addmul_v_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask_2(idx, 6));
|
||||
}
|
||||
}
|
||||
cval[0] = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cval[0] = mm256_xor(cval[0], cval[1]);
|
||||
cblock->w128[0] =
|
||||
_mm_xor_si128(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
mm128_xor(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -755,7 +751,7 @@ void mzd_mul_v_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
const word* vptr = CONST_BLOCK(v, 0)->w64;
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {_mm256_setzero_si256(), _mm256_setzero_si256()};
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero};
|
||||
for (unsigned int w = 2; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 8, idx >>= 8, Ablock += 4) {
|
||||
@ -765,9 +761,9 @@ void mzd_mul_v_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask_2(idx, 6));
|
||||
}
|
||||
}
|
||||
cval[0] = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cval[0] = mm256_xor(cval[0], cval[1]);
|
||||
cblock->w128[0] =
|
||||
_mm_xor_si128(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
mm128_xor(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -776,7 +772,7 @@ void mzd_addmul_v_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
const word* vptr = CONST_BLOCK(v, 0)->w64;
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, _mm256_setzero_si256()};
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, mm256_zero};
|
||||
for (unsigned int w = 3; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 4, idx >>= 4, Ablock += 4) {
|
||||
@ -786,7 +782,7 @@ void mzd_addmul_v_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask(idx, 3));
|
||||
}
|
||||
}
|
||||
cblock->w256 = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cblock->w256 = mm256_xor(cval[0], cval[1]);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -795,7 +791,7 @@ void mzd_mul_v_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
const word* vptr = CONST_BLOCK(v, 0)->w64;
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {_mm256_setzero_si256(), _mm256_setzero_si256()};
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero};
|
||||
for (unsigned int w = 3; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 4, idx >>= 4, Ablock += 4) {
|
||||
@ -805,7 +801,7 @@ void mzd_mul_v_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask(idx, 3));
|
||||
}
|
||||
}
|
||||
cblock->w256 = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cblock->w256 = mm256_xor(cval[0], cval[1]);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -814,7 +810,7 @@ void mzd_addmul_v_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
const word* vptr = CONST_BLOCK(v, 0)->w64;
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, _mm256_setzero_si256()};
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, mm256_zero};
|
||||
for (unsigned int w = 4; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 4, idx >>= 4, Ablock += 4) {
|
||||
@ -824,7 +820,7 @@ void mzd_addmul_v_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask(idx, 3));
|
||||
}
|
||||
}
|
||||
cblock->w256 = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cblock->w256 = mm256_xor(cval[0], cval[1]);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -833,7 +829,7 @@ void mzd_mul_v_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
const word* vptr = CONST_BLOCK(v, 0)->w64;
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {_mm256_setzero_si256(), _mm256_setzero_si256()};
|
||||
word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero};
|
||||
for (unsigned int w = 4; w; --w, ++vptr) {
|
||||
word idx = *vptr;
|
||||
for (unsigned int i = sizeof(word) * 8; i; i -= 4, idx >>= 4, Ablock += 4) {
|
||||
@ -843,7 +839,7 @@ void mzd_mul_v_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const*
|
||||
cval[1] = mm256_xor_mask(cval[1], Ablock[3].w256, mm256_compute_mask(idx, 3));
|
||||
}
|
||||
}
|
||||
cblock->w256 = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cblock->w256 = mm256_xor(cval[0], cval[1]);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
@ -1336,13 +1332,13 @@ void mzd_addmul_v_s256_30_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t
|
||||
}
|
||||
cval[0] = mm256_xor_mask(cval[0], Ablock[0].w256, mm256_compute_mask_2(idx, 0));
|
||||
|
||||
cval[0] = _mm256_xor_si256(cval[0], cval[1]);
|
||||
cval[0] = mm256_xor(cval[0], cval[1]);
|
||||
cblock->w128[0] =
|
||||
_mm_xor_si128(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
mm128_xor(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1));
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
static void mzd_addmul_v_s256_30_256_idx(mzd_local_t* c, mzd_local_t const* A, word idx) {
|
||||
static inline void mzd_addmul_v_s256_30_256_idx(mzd_local_t* c, mzd_local_t const* A, word idx) {
|
||||
block_t* cblock = BLOCK(c, 0);
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
@ -1385,7 +1381,7 @@ void mzd_addmul_v_s256_3_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t c
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
static void mzd_addmul_v_s256_3_256_idx(mzd_local_t* c, mzd_local_t const* A, const word idx) {
|
||||
static inline void mzd_addmul_v_s256_3_256_idx(mzd_local_t* c, mzd_local_t const* A, const word idx) {
|
||||
block_t* cblock = BLOCK(c, 0);
|
||||
const block_t* Ablock = CONST_BLOCK(A, 0);
|
||||
|
||||
@ -1431,14 +1427,17 @@ static inline void mzd_shuffle_pext_30_idx(mzd_local_t* x, const word mask, unsi
|
||||
BLOCK(x, 0)->w64[idx] = a | _pext_u64(w, ~mask);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
void mzd_shuffle_pext_128_30(mzd_local_t* x, const word mask) {
|
||||
mzd_shuffle_pext_30_idx(x, mask, 1);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
void mzd_shuffle_pext_192_30(mzd_local_t* x, const word mask) {
|
||||
mzd_shuffle_pext_30_idx(x, mask, 2);
|
||||
}
|
||||
|
||||
ATTR_TARGET_AVX2
|
||||
void mzd_shuffle_pext_256_30(mzd_local_t* x, const word mask) {
|
||||
mzd_shuffle_pext_30_idx(x, mask, 3);
|
||||
}
|
||||
|
||||
36
src/sig/picnic/external/picnic.c
vendored
36
src/sig/picnic/external/picnic.c
vendored
@ -18,8 +18,13 @@
|
||||
|
||||
#include "io.h"
|
||||
#include "lowmc.h"
|
||||
#include "picnic_instances.h"
|
||||
#if defined(WITH_ZKBPP)
|
||||
#include "picnic_impl.h"
|
||||
#endif
|
||||
#if defined(WITH_KKW)
|
||||
#include "picnic2_impl.h"
|
||||
#endif
|
||||
#include <oqs/rand.h>
|
||||
|
||||
// Public and private keys are serialized as follows:
|
||||
@ -93,10 +98,8 @@ int PICNIC_CALLING_CONVENTION picnic_keygen(picnic_params_t param, picnic_public
|
||||
sk->data[0] = param;
|
||||
// random secret key
|
||||
OQS_randombytes(sk_sk, input_size);
|
||||
|
||||
// random plain text
|
||||
OQS_randombytes(sk_pt, output_size);
|
||||
|
||||
// encrypt plaintext under secret key
|
||||
if (picnic_sk_to_pk(sk, pk)) {
|
||||
return -1;
|
||||
@ -205,11 +208,20 @@ int PICNIC_CALLING_CONVENTION picnic_sign(const picnic_privatekey_t* sk, const u
|
||||
const uint8_t* sk_c = SK_C(sk);
|
||||
const uint8_t* sk_pt = SK_PT(sk);
|
||||
|
||||
if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS)
|
||||
if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS) {
|
||||
#if defined(WITH_KKW)
|
||||
return impl_sign_picnic2(instance, sk_pt, sk_sk, sk_c, message, message_len, signature,
|
||||
signature_len);
|
||||
else
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(WITH_ZKBPP)
|
||||
return impl_sign(instance, sk_pt, sk_sk, sk_c, message, message_len, signature, signature_len);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int PICNIC_CALLING_CONVENTION picnic_verify(const picnic_publickey_t* pk, const uint8_t* message,
|
||||
@ -230,11 +242,21 @@ int PICNIC_CALLING_CONVENTION picnic_verify(const picnic_publickey_t* pk, const
|
||||
const uint8_t* pk_c = PK_C(pk);
|
||||
const uint8_t* pk_pt = PK_PT(pk);
|
||||
|
||||
if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS)
|
||||
if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS) {
|
||||
#if defined(WITH_KKW)
|
||||
return impl_verify_picnic2(instance, pk_pt, pk_c, message, message_len, signature,
|
||||
signature_len);
|
||||
else
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(WITH_ZKBPP)
|
||||
return impl_verify(instance, pk_pt, pk_c, message, message_len, signature, signature_len);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const char* PICNIC_CALLING_CONVENTION picnic_get_param_name(picnic_params_t parameters) {
|
||||
@ -364,4 +386,4 @@ int PICNIC_CALLING_CONVENTION picnic_read_private_key(picnic_privatekey_t* key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* cropped unused picnic_visualize_keys */
|
||||
/* OQS note: cropped unused visualization functions */
|
||||
|
||||
19
src/sig/picnic/external/picnic.h
vendored
19
src/sig/picnic/external/picnic.h
vendored
@ -35,6 +35,7 @@ extern "C" {
|
||||
#define PICNIC_CONCAT2(a, b) a##_##b
|
||||
#define PICNIC_CONCAT(a, b) PICNIC_CONCAT2(a, b)
|
||||
|
||||
/* Block sizes of the LowMC ciphers per parameter */
|
||||
#define LOWMC_BLOCK_SIZE_Picnic_L1_FS 16
|
||||
#define LOWMC_BLOCK_SIZE_Picnic_L1_UR 16
|
||||
#define LOWMC_BLOCK_SIZE_Picnic_L3_FS 24
|
||||
@ -47,14 +48,10 @@ extern "C" {
|
||||
|
||||
#define LOWMC_BLOCK_SIZE(p) PICNIC_CONCAT(LOWMC_BLOCK_SIZE, p)
|
||||
|
||||
#define SALT_SIZE 32
|
||||
#define MAX_LOWMC_ROUNDS 38
|
||||
#define MAX_LOWMC_SBOXES 10
|
||||
#define MAX_ROUNDS 438
|
||||
|
||||
#define PICNIC_PRIVATE_KEY_SIZE(p) (1 + 3 * LOWMC_BLOCK_SIZE(p))
|
||||
#define PICNIC_PUBLIC_KEY_SIZE(p) (1 + 2 * LOWMC_BLOCK_SIZE(p))
|
||||
|
||||
/* Max. signature sizes per parameter */
|
||||
#define PICNIC_SIGNATURE_SIZE_Picnic_L1_FS 34032
|
||||
#define PICNIC_SIGNATURE_SIZE_Picnic_L1_UR 53961
|
||||
#define PICNIC_SIGNATURE_SIZE_Picnic_L3_FS 76732
|
||||
@ -73,7 +70,7 @@ extern "C" {
|
||||
|
||||
#define PICNIC_SIGNATURE_SIZE(p) PICNIC_CONCAT(PICNIC_SIGNATURE_SIZE, p)
|
||||
|
||||
#define MAX_LOWMC_BLOCK_SIZE LOWMC_BLOCK_SIZE(Picnic_L5_UR)
|
||||
#define PICNIC_MAX_LOWMC_BLOCK_SIZE LOWMC_BLOCK_SIZE(Picnic_L5_UR)
|
||||
#define PICNIC_MAX_PRIVATEKEY_SIZE PICNIC_PRIVATE_KEY_SIZE(Picnic_L5_UR)
|
||||
#define PICNIC_MAX_PUBLICKEY_SIZE PICNIC_PUBLIC_KEY_SIZE(Picnic_L5_UR)
|
||||
#define PICNIC_MAX_SIGNATURE_SIZE PICNIC_SIGNATURE_SIZE(Picnic_L5_UR)
|
||||
@ -108,7 +105,7 @@ typedef struct {
|
||||
|
||||
/** Private key */
|
||||
typedef struct {
|
||||
uint8_t data[1 + 3 * MAX_LOWMC_BLOCK_SIZE];
|
||||
uint8_t data[PICNIC_MAX_PRIVATEKEY_SIZE];
|
||||
} picnic_privatekey_t;
|
||||
|
||||
/**
|
||||
@ -206,7 +203,7 @@ PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_verify(const picnic_publickey
|
||||
*
|
||||
* @param[in] key The public key to serialize
|
||||
* @param[out] buf The buffer to write the key to.
|
||||
* Must have size at least PICNIC_MAX_PUBLICKEY_SIZE + 1 bytes.
|
||||
* Must have size at least PICNIC_MAX_PUBLICKEY_SIZE bytes.
|
||||
* @param[in] buflen The length of buf, in bytes
|
||||
*
|
||||
* @return Returns the number of bytes written.
|
||||
@ -219,7 +216,7 @@ PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_write_public_key(const picnic
|
||||
*
|
||||
* @param[out] key The public key object to be populated.
|
||||
* @param[in] buf The buffer to read the public key from.
|
||||
* Must be at least PICNIC_MAX_PUBLICKEY_SIZE + 1 bytes.
|
||||
* Must be at least PICNIC_MAX_PUBLICKEY_SIZE bytes.
|
||||
* @param[in] buflen The length of buf, in bytes
|
||||
*
|
||||
* @return Returns 0 on success, or a nonzero value indicating an error.
|
||||
@ -233,7 +230,7 @@ PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_read_public_key(picnic_public
|
||||
*
|
||||
* @param[in] key The private key to serialize
|
||||
* @param[out] buf The buffer to write the key to.
|
||||
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE + 1 bytes.
|
||||
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE bytes.
|
||||
* @param[in] buflen The length of buf, in bytes
|
||||
*
|
||||
* @return Returns the number of bytes written.
|
||||
@ -246,7 +243,7 @@ PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_write_private_key(const picni
|
||||
*
|
||||
* @param[out] key The private key object to be populated
|
||||
* @param[in] buf The buffer to read the key from.
|
||||
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE + 1 bytes.
|
||||
* Must have size at least PICNIC_MAX_PRIVATEKEY_SIZE bytes.
|
||||
* @param[in] buflen The length of buf, in bytes
|
||||
*
|
||||
* @return Returns 0 on success, or a nonzero value indicating an error.
|
||||
|
||||
138
src/sig/picnic/external/picnic2_impl.c
vendored
138
src/sig/picnic/external/picnic2_impl.c
vendored
@ -10,6 +10,10 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@ -25,12 +29,17 @@
|
||||
#include "picnic2_simulate_mul.h"
|
||||
#include "picnic2_tree.h"
|
||||
#include "picnic2_types.h"
|
||||
#include "picnic_impl.h"
|
||||
|
||||
#define LOWMC_MAX_KEY_BITS 256
|
||||
#define LOWMC_MAX_AND_GATES (3 * 38 * 10 + 4) /* Rounded to nearest byte */
|
||||
#define MAX_AUX_BYTES ((LOWMC_MAX_AND_GATES + LOWMC_MAX_KEY_BITS) / 8 + 1)
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#define SIZET_FMT "%Iu"
|
||||
#else
|
||||
#define SIZET_FMT "%zu"
|
||||
#endif
|
||||
|
||||
/* Helper functions */
|
||||
|
||||
ATTR_CONST
|
||||
@ -47,23 +56,15 @@ static void createRandomTapes(randomTape_t* tapes, uint8_t** seeds, uint8_t* sal
|
||||
allocateRandomTape(tapes, params);
|
||||
assert(params->num_MPC_parties % 4 == 0);
|
||||
for (size_t i = 0; i < params->num_MPC_parties; i += 4) {
|
||||
hash_init_x4(&ctx, params);
|
||||
hash_init_x4(&ctx, params->digest_size);
|
||||
|
||||
const uint8_t* seeds_ptr[4] = {seeds[i], seeds[i + 1], seeds[i + 2], seeds[i + 3]};
|
||||
hash_update_x4(&ctx, seeds_ptr, params->seed_size);
|
||||
const uint8_t* salt_ptr[4] = {salt, salt, salt, salt};
|
||||
hash_update_x4(&ctx, salt_ptr, SALT_SIZE);
|
||||
uint16_t tLE = htole16((uint16_t)t);
|
||||
const uint8_t* tLE_ptr[4] = {(const uint8_t*)&tLE, (const uint8_t*)&tLE, (const uint8_t*)&tLE,
|
||||
(const uint8_t*)&tLE};
|
||||
hash_update_x4(&ctx, tLE_ptr, sizeof(uint16_t));
|
||||
uint16_t iLE0 = htole16((uint16_t)(i + 0));
|
||||
uint16_t iLE1 = htole16((uint16_t)(i + 1));
|
||||
uint16_t iLE2 = htole16((uint16_t)(i + 2));
|
||||
uint16_t iLE3 = htole16((uint16_t)(i + 3));
|
||||
const uint8_t* iLE_ptr[4] = {(const uint8_t*)&iLE0, (const uint8_t*)&iLE1,
|
||||
(const uint8_t*)&iLE2, (const uint8_t*)&iLE3};
|
||||
hash_update_x4(&ctx, iLE_ptr, sizeof(uint16_t));
|
||||
hash_update_x4_uint16_le(&ctx, t);
|
||||
const uint16_t i_arr[4] = {i + 0, i + 1, i + 2, i + 3};
|
||||
hash_update_x4_uint16s_le(&ctx, i_arr);
|
||||
hash_final_x4(&ctx);
|
||||
|
||||
uint8_t* out_ptr[4] = {tapes->tape[i], tapes->tape[i + 1], tapes->tape[i + 2],
|
||||
@ -141,7 +142,7 @@ void sbox_layer_10_uint64_aux(uint64_t* d, randomTape_t* tapes) {
|
||||
*d = (in & MASK_MASK) ^ (t0 >> 2) ^ (t1 >> 1) ^ t2;
|
||||
}
|
||||
|
||||
/* Input is the tapes for one parallel repetition; i.e., tapes[t]
|
||||
/* Input is the tapes for one parallel repitition; i.e., tapes[t]
|
||||
* Updates the random tapes of all players with the mask values for the output of
|
||||
* AND gates, and computes the N-th party's share such that the AND gate invariant
|
||||
* holds on the mask values.
|
||||
@ -178,17 +179,15 @@ static void commit(uint8_t* digest, const uint8_t* seed, const uint8_t* aux, con
|
||||
/* Compute C[t][j]; as digest = H(seed||[aux]) aux is optional */
|
||||
hash_context ctx;
|
||||
|
||||
hash_init(&ctx, params);
|
||||
hash_init(&ctx, params->digest_size);
|
||||
hash_update(&ctx, seed, params->seed_size);
|
||||
if (aux != NULL) {
|
||||
size_t tapeLenBytes = params->view_size;
|
||||
hash_update(&ctx, aux, tapeLenBytes);
|
||||
}
|
||||
hash_update(&ctx, salt, SALT_SIZE);
|
||||
const uint16_t tLE = htole16((uint16_t)t);
|
||||
hash_update(&ctx, (const uint8_t*)&tLE, sizeof(uint16_t));
|
||||
const uint16_t jLE = htole16((uint16_t)j);
|
||||
hash_update(&ctx, (const uint8_t*)&jLE, sizeof(uint16_t));
|
||||
hash_update_uint16_le(&ctx, t);
|
||||
hash_update_uint16_le(&ctx, j);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, digest, params->digest_size);
|
||||
}
|
||||
@ -198,21 +197,13 @@ static void commit_x4(uint8_t** digest, const uint8_t** seed, const uint8_t* sal
|
||||
/* Compute C[t][j]; as digest = H(seed||[aux]) aux is optional */
|
||||
hash_context_x4 ctx;
|
||||
|
||||
hash_init_x4(&ctx, params);
|
||||
hash_init_x4(&ctx, params->digest_size);
|
||||
hash_update_x4(&ctx, seed, params->seed_size);
|
||||
const uint8_t* salt_ptr[4] = {salt, salt, salt, salt};
|
||||
hash_update_x4(&ctx, salt_ptr, SALT_SIZE);
|
||||
const uint16_t tLE = htole16((uint16_t)t);
|
||||
const uint8_t* tLE_ptr[4] = {(const uint8_t*)&tLE, (const uint8_t*)&tLE, (const uint8_t*)&tLE,
|
||||
(const uint8_t*)&tLE};
|
||||
hash_update_x4(&ctx, tLE_ptr, sizeof(uint16_t));
|
||||
const uint16_t jLE0 = htole16((uint16_t)(j + 0));
|
||||
const uint16_t jLE1 = htole16((uint16_t)(j + 1));
|
||||
const uint16_t jLE2 = htole16((uint16_t)(j + 2));
|
||||
const uint16_t jLE3 = htole16((uint16_t)(j + 3));
|
||||
const uint8_t* jLE_ptr[4] = {(const uint8_t*)&jLE0, (const uint8_t*)&jLE1, (const uint8_t*)&jLE2,
|
||||
(const uint8_t*)&jLE3};
|
||||
hash_update_x4(&ctx, jLE_ptr, sizeof(uint16_t));
|
||||
hash_update_x4_uint16_le(&ctx, t);
|
||||
const uint16_t j_arr[4] = {j + 0, j + 1, j + 2, j + 3};
|
||||
hash_update_x4_uint16s_le(&ctx, j_arr);
|
||||
hash_final_x4(&ctx);
|
||||
hash_squeeze_x4(&ctx, digest, params->digest_size);
|
||||
}
|
||||
@ -220,7 +211,7 @@ static void commit_x4(uint8_t** digest, const uint8_t** seed, const uint8_t* sal
|
||||
static void commit_h(uint8_t* digest, const commitments_t* C, const picnic_instance_t* params) {
|
||||
hash_context ctx;
|
||||
|
||||
hash_init(&ctx, params);
|
||||
hash_init(&ctx, params->digest_size);
|
||||
for (size_t i = 0; i < params->num_MPC_parties; i++) {
|
||||
hash_update(&ctx, C->hashes[i], params->digest_size);
|
||||
}
|
||||
@ -231,7 +222,7 @@ static void commit_h(uint8_t* digest, const commitments_t* C, const picnic_insta
|
||||
static void commit_h_x4(uint8_t** digest, const commitments_t* C, const picnic_instance_t* params) {
|
||||
hash_context_x4 ctx;
|
||||
|
||||
hash_init_x4(&ctx, params);
|
||||
hash_init_x4(&ctx, params->digest_size);
|
||||
for (size_t i = 0; i < params->num_MPC_parties; i++) {
|
||||
const uint8_t* data[4] = {
|
||||
C[0].hashes[i],
|
||||
@ -250,7 +241,7 @@ static void commit_v(uint8_t* digest, const uint8_t* input, const msgs_t* msgs,
|
||||
const picnic_instance_t* params) {
|
||||
hash_context ctx;
|
||||
|
||||
hash_init(&ctx, params);
|
||||
hash_init(&ctx, params->digest_size);
|
||||
hash_update(&ctx, input, params->input_size);
|
||||
for (size_t i = 0; i < params->num_MPC_parties; i++) {
|
||||
hash_update(&ctx, msgs->msgs[i], numBytes(msgs->pos));
|
||||
@ -263,7 +254,7 @@ static void commit_v_x4(uint8_t** digest, const uint8_t** input, const msgs_t* m
|
||||
const picnic_instance_t* params) {
|
||||
hash_context_x4 ctx;
|
||||
|
||||
hash_init_x4(&ctx, params);
|
||||
hash_init_x4(&ctx, params->digest_size);
|
||||
hash_update_x4(&ctx, input, params->input_size);
|
||||
for (size_t i = 0; i < params->num_MPC_parties; i++) {
|
||||
assert(msgs[0].pos == msgs[1].pos && msgs[2].pos == msgs[3].pos && msgs[0].pos == msgs[2].pos);
|
||||
@ -353,7 +344,7 @@ static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, u
|
||||
|
||||
assert(params->num_opened_rounds < params->num_rounds);
|
||||
|
||||
hash_init(&ctx, params);
|
||||
hash_init(&ctx, params->digest_size);
|
||||
for (size_t t = 0; t < params->num_rounds; t++) {
|
||||
hash_update(&ctx, Ch->hashes[t], params->digest_size);
|
||||
}
|
||||
@ -369,7 +360,8 @@ static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, u
|
||||
// Populate C
|
||||
uint32_t bitsPerChunkC = ceil_log2(params->num_rounds);
|
||||
uint32_t bitsPerChunkP = ceil_log2(params->num_MPC_parties);
|
||||
uint16_t* chunks = calloc(params->digest_size * 8 / MIN(bitsPerChunkP,bitsPerChunkC), sizeof(uint16_t));
|
||||
uint16_t* chunks =
|
||||
calloc(params->digest_size * 8 / MIN(bitsPerChunkP, bitsPerChunkC), sizeof(uint16_t));
|
||||
|
||||
size_t countC = 0;
|
||||
while (countC < params->num_opened_rounds) {
|
||||
@ -383,7 +375,7 @@ static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, u
|
||||
}
|
||||
}
|
||||
|
||||
hash_init_prefix(&ctx, params, HASH_PREFIX_1);
|
||||
hash_init_prefix(&ctx, params->digest_size, HASH_PREFIX_1);
|
||||
hash_update(&ctx, h, params->digest_size);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, h, params->digest_size);
|
||||
@ -404,7 +396,7 @@ static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, u
|
||||
}
|
||||
}
|
||||
|
||||
hash_init_prefix(&ctx, params, HASH_PREFIX_1);
|
||||
hash_init_prefix(&ctx, params->digest_size, HASH_PREFIX_1);
|
||||
hash_update(&ctx, h, params->digest_size);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, h, params->digest_size);
|
||||
@ -431,7 +423,7 @@ static uint16_t* getMissingLeavesList(uint16_t* challengeC, const picnic_instanc
|
||||
int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* plaintext,
|
||||
const uint8_t* message, size_t messageByteLength,
|
||||
const picnic_instance_t* params) {
|
||||
commitments_t C[4] = {0,};
|
||||
commitments_t C[4];
|
||||
allocateCommitments2(&C[0], params, params->num_MPC_parties);
|
||||
allocateCommitments2(&C[1], params, params->num_MPC_parties);
|
||||
allocateCommitments2(&C[2], params, params->num_MPC_parties);
|
||||
@ -446,14 +438,14 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
tree_t* iSeedsTree = createTree(params->num_rounds, params->seed_size);
|
||||
int ret = reconstructSeeds(iSeedsTree, sig->challengeC, params->num_opened_rounds, sig->iSeedInfo,
|
||||
sig->iSeedInfoLen, sig->salt, 0, params);
|
||||
const size_t last = params->num_MPC_parties - 1;
|
||||
const size_t last = params->num_MPC_parties - 1;
|
||||
lowmc_simulate_online_f simulateOnline = params->impls.lowmc_simulate_online;
|
||||
|
||||
commitments_t Ch = {0};
|
||||
commitments_t Ch;
|
||||
allocateCommitments2(&Ch, params, params->num_rounds);
|
||||
commitments_t Cv = {0};
|
||||
commitments_t Cv;
|
||||
allocateCommitments2(&Cv, params, params->num_rounds);
|
||||
shares_t* mask_shares = allocateShares(params->lowmc->n);
|
||||
shares_t* mask_shares = allocateShares(params->lowmc->n);
|
||||
mzd_local_t* m_plaintext = mzd_local_init_ex(1, params->lowmc->n, false);
|
||||
mzd_local_t* m_maskedKey = mzd_local_init_ex(1, params->lowmc->k, false);
|
||||
mzd_from_char_array(m_plaintext, (const uint8_t*)plaintext, params->output_size);
|
||||
@ -480,7 +472,7 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
sig->proofs[t].seedInfoLen, sig->salt, t, params);
|
||||
if (ret != 0) {
|
||||
#if !defined(NDEBUG)
|
||||
printf("Failed to reconstruct seeds for round %lu\n", t);
|
||||
printf("Failed to reconstruct seeds for round " SIZET_FMT "\n", t);
|
||||
#endif
|
||||
ret = -1;
|
||||
goto Exit;
|
||||
@ -488,12 +480,11 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
}
|
||||
/* Commit */
|
||||
|
||||
/* Compute random tapes for all parties. One party for each repetition
|
||||
/* Compute random tapes for all parties. One party for each repitition
|
||||
* challengeC will have a bogus seed; but we won't use that party's
|
||||
* random tape. */
|
||||
createRandomTapes(&tapes[t], getLeaves(seeds[t]), sig->salt, t, params);
|
||||
|
||||
|
||||
if (!contains(sig->challengeC, params->num_opened_rounds, t)) {
|
||||
/* We're given iSeed, have expanded the seeds, compute aux from scratch so we can comnpte
|
||||
* Com[t] */
|
||||
@ -501,9 +492,9 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
for (size_t j = 0; j < params->num_MPC_parties; j += 4) {
|
||||
const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1),
|
||||
getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)};
|
||||
commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
commit_x4(C[t % 4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
}
|
||||
commit(C[t%4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last,
|
||||
commit(C[t % 4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last,
|
||||
params);
|
||||
/* after we have checked the tape, we do not need it anymore for this opened iteration */
|
||||
freeRandomTape(&tapes[t]);
|
||||
@ -514,18 +505,18 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
for (size_t j = 0; j < params->num_MPC_parties; j += 4) {
|
||||
const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1),
|
||||
getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)};
|
||||
commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
commit_x4(C[t % 4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
}
|
||||
if (last != unopened) {
|
||||
commit(C[t%4].hashes[last], getLeaf(seeds[t], last), sig->proofs[t].aux, sig->salt, t, last,
|
||||
params);
|
||||
commit(C[t % 4].hashes[last], getLeaf(seeds[t], last), sig->proofs[t].aux, sig->salt, t,
|
||||
last, params);
|
||||
}
|
||||
|
||||
memcpy(C[t%4].hashes[unopened], sig->proofs[t].C, params->digest_size);
|
||||
memcpy(C[t % 4].hashes[unopened], sig->proofs[t].C, params->digest_size);
|
||||
}
|
||||
/* hash commitments every four iterations if possible, for the last few do single commitments */
|
||||
if(t >= params->num_rounds / 4 * 4) {
|
||||
commit_h(Ch.hashes[t], &C[t%4], params);
|
||||
if (t >= params->num_rounds / 4 * 4) {
|
||||
commit_h(Ch.hashes[t], &C[t % 4], params);
|
||||
} else if ((t + 1) % 4 == 0) {
|
||||
size_t t4 = t / 4 * 4;
|
||||
commit_h_x4(&Ch.hashes[t4], &C[0], params);
|
||||
@ -548,13 +539,12 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl
|
||||
|
||||
tapesToWords(mask_shares, &tapes[t]);
|
||||
mzd_from_char_array(m_maskedKey, sig->proofs[t].input, params->input_size);
|
||||
ret = simulateOnline(m_maskedKey, mask_shares, &tapes[t], msgs,
|
||||
m_plaintext, pubKey, params);
|
||||
ret = simulateOnline(m_maskedKey, mask_shares, &tapes[t], msgs, m_plaintext, pubKey, params);
|
||||
|
||||
freeRandomTape(&tapes[t]);
|
||||
if (ret != 0) {
|
||||
#if !defined(NDEBUG)
|
||||
printf("MPC simulation failed for round %lu, signature invalid\n", t);
|
||||
printf("MPC simulation failed for round " SIZET_FMT ", signature invalid\n", t);
|
||||
#endif
|
||||
ret = -1;
|
||||
goto Exit;
|
||||
@ -624,13 +614,12 @@ static void computeSaltAndRootSeed(uint8_t* saltAndRoot, size_t saltAndRootLengt
|
||||
const picnic_instance_t* params) {
|
||||
hash_context ctx;
|
||||
|
||||
hash_init(&ctx, params);
|
||||
hash_init(&ctx, params->digest_size);
|
||||
hash_update(&ctx, (const uint8_t*)privateKey, params->input_size);
|
||||
hash_update(&ctx, message, messageByteLength);
|
||||
hash_update(&ctx, (const uint8_t*)pubKey, params->input_size);
|
||||
hash_update(&ctx, (const uint8_t*)plaintext, params->input_size);
|
||||
const uint16_t stateSizeLE = htole16((uint16_t)params->lowmc->n);
|
||||
hash_update(&ctx, (const uint8_t*)&stateSizeLE, sizeof(uint16_t));
|
||||
hash_update_uint16_le(&ctx, (uint16_t)params->lowmc->n);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, saltAndRoot, saltAndRootLength);
|
||||
}
|
||||
@ -673,7 +662,6 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext,
|
||||
|
||||
mzd_from_char_array(m_plaintext, (const uint8_t*)plaintext, params->output_size);
|
||||
|
||||
|
||||
for (size_t t = 0; t < params->num_rounds; t++) {
|
||||
seeds[t] = generateSeeds(params->num_MPC_parties, iSeeds[t], sig->salt, t, params);
|
||||
createRandomTapes(&tapes[t], getLeaves(seeds[t]), sig->salt, t, params);
|
||||
@ -684,10 +672,10 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext,
|
||||
for (size_t j = 0; j < params->num_MPC_parties; j += 4) {
|
||||
const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1),
|
||||
getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)};
|
||||
commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
commit_x4(C[t % 4].hashes + j, seed_ptr, sig->salt, t, j, params);
|
||||
}
|
||||
const size_t last = params->num_MPC_parties - 1;
|
||||
commit(C[t%4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last,
|
||||
commit(C[t % 4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last,
|
||||
params);
|
||||
|
||||
/* Simulate the online phase of the MPC */
|
||||
@ -699,7 +687,8 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext,
|
||||
(params->input_size / 4)); // maskedKey += privateKey
|
||||
mzd_from_char_array(m_maskedKey, (const uint8_t*)maskedKey, params->input_size);
|
||||
|
||||
int rv = simulateOnline(m_maskedKey, mask_shares, &tapes[t], &msgs[t], m_plaintext, pubKey, params);
|
||||
int rv =
|
||||
simulateOnline(m_maskedKey, mask_shares, &tapes[t], &msgs[t], m_plaintext, pubKey, params);
|
||||
if (rv != 0) {
|
||||
#if !defined(NDEBUG)
|
||||
printf("MPC simulation failed, aborting signature\n");
|
||||
@ -707,18 +696,17 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext,
|
||||
ret = -1;
|
||||
}
|
||||
/* free the expanded random tape and associated buffers to reduce memory usage,
|
||||
however, we are keeping the calculated aux bits for later (hence partial) */
|
||||
however, we are keeping the calculated aux bits for later (hence partial) */
|
||||
partialFreeRandomTape(&tapes[t]);
|
||||
/* hash commitments every four iterations if possible, for the last few do single commitments */
|
||||
if(t >= params->num_rounds / 4 * 4) {
|
||||
commit_h(Ch.hashes[t], &C[t%4], params);
|
||||
if (t >= params->num_rounds / 4 * 4) {
|
||||
commit_h(Ch.hashes[t], &C[t % 4], params);
|
||||
commit_v(Cv.hashes[t], inputs[t], &msgs[t], params);
|
||||
} else if ((t + 1) % 4 == 0) {
|
||||
size_t t4 = t / 4 * 4;
|
||||
commit_h_x4(&Ch.hashes[t4], &C[0], params);
|
||||
commit_v_x4(&Cv.hashes[t4], (const uint8_t**)&inputs[t4], &msgs[t4], params);
|
||||
}
|
||||
|
||||
}
|
||||
freeShares(mask_shares);
|
||||
mzd_local_free(m_maskedKey);
|
||||
@ -776,12 +764,12 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext,
|
||||
|
||||
/* recompute commitment of unopened party since we did not store it for memory optimization */
|
||||
if (proofs[t].unOpenedIndex == params->num_MPC_parties - 1) {
|
||||
commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex),
|
||||
tapes[t].aux_bits, sig->salt, t, proofs[t].unOpenedIndex, params);
|
||||
commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex), tapes[t].aux_bits,
|
||||
sig->salt, t, proofs[t].unOpenedIndex, params);
|
||||
} else {
|
||||
commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex),
|
||||
NULL, sig->salt, t, proofs[t].unOpenedIndex, params);
|
||||
}
|
||||
commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex), NULL, sig->salt, t,
|
||||
proofs[t].unOpenedIndex, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -907,7 +895,7 @@ static int deserializeSignature2(signature2_t* sig, const uint8_t* sigBytes, siz
|
||||
/* Fail if the signature does not have the exact number of bytes we expect */
|
||||
if (sigBytesLen != bytesRequired) {
|
||||
#if !defined(NDEBUG)
|
||||
printf("%s: sigBytesLen = %lu, expected bytesRequired = %lu\n", __func__, sigBytesLen,
|
||||
printf("%s: sigBytesLen = " SIZET_FMT ", expected bytesRequired = " SIZET_FMT "\n", __func__, sigBytesLen,
|
||||
bytesRequired);
|
||||
#endif
|
||||
return EXIT_FAILURE;
|
||||
|
||||
2
src/sig/picnic/external/picnic2_impl.h
vendored
2
src/sig/picnic/external/picnic2_impl.h
vendored
@ -15,7 +15,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "picnic_impl.h"
|
||||
#include "picnic_instances.h"
|
||||
|
||||
typedef struct proof2_t {
|
||||
uint16_t unOpenedIndex; // P[t], index of the party that is not opened.
|
||||
|
||||
14
src/sig/picnic/external/picnic2_simulate.c
vendored
14
src/sig/picnic/external/picnic2_simulate.c
vendored
@ -10,17 +10,22 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#if !defined(_MSC_VER)
|
||||
#include <stdalign.h>
|
||||
#endif
|
||||
|
||||
#include "io.h"
|
||||
#include "picnic2_simulate.h"
|
||||
#include "picnic2_simulate_mul.h"
|
||||
#include "compat.h"
|
||||
#include "io.h"
|
||||
|
||||
static void wordToMsgsNoTranspose(uint64_t w, msgs_t* msgs) {
|
||||
((uint64_t*)msgs->msgs[msgs->pos % 64])[msgs->pos / 64] = w;
|
||||
@ -28,7 +33,7 @@ static void wordToMsgsNoTranspose(uint64_t w, msgs_t* msgs) {
|
||||
}
|
||||
|
||||
static void msgsTranspose(msgs_t* msgs) {
|
||||
uint64_t* buffer = aligned_alloc(32, 64 * sizeof(uint64_t));
|
||||
uint64_t buffer[64] ATTR_ALIGNED(32);
|
||||
size_t pos;
|
||||
for (pos = 0; pos < msgs->pos / 64; pos++) {
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
@ -47,7 +52,6 @@ static void msgsTranspose(msgs_t* msgs) {
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
((uint64_t*)msgs->msgs[i])[pos] = buffer[i];
|
||||
}
|
||||
aligned_free(buffer);
|
||||
}
|
||||
|
||||
/* For each word in shares; write player i's share to their stream of msgs */
|
||||
|
||||
36
src/sig/picnic/external/picnic2_simulate.c.i
vendored
36
src/sig/picnic/external/picnic2_simulate.c.i
vendored
@ -10,25 +10,6 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#if !defined(_MSC_VER)
|
||||
#include <stdalign.h>
|
||||
#endif
|
||||
|
||||
#include "kdf_shake.h"
|
||||
#include "macros.h"
|
||||
#include "picnic_impl.h"
|
||||
#include "picnic2_impl.h"
|
||||
#include "picnic.h"
|
||||
#include "picnic2_types.h"
|
||||
#include "picnic2_tree.h"
|
||||
#include "io.h"
|
||||
|
||||
#if defined(FN_ATTR)
|
||||
FN_ATTR
|
||||
#endif
|
||||
@ -36,11 +17,7 @@ static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_
|
||||
const mzd_local_t* plaintext, const uint32_t* pubKey,
|
||||
const picnic_instance_t* params) {
|
||||
int ret = 0;
|
||||
mzd_local_t* state = mzd_local_init_ex(1, LOWMC_N, false);
|
||||
mzd_local_t* state2 = mzd_local_init_ex(1, LOWMC_N, false);
|
||||
mzd_local_t* roundKey = mzd_local_init_ex(1, LOWMC_N, false);
|
||||
mzd_local_t* nl_part = mzd_local_init_ex(1, (LOWMC_R * 32), false);
|
||||
shares_t* nl_part_masks = allocateShares(LOWMC_R * 32);
|
||||
mzd_local_t state[((LOWMC_N) + 255) / 256];
|
||||
shares_t* key_masks = allocateShares(LOWMC_N); // Make a copy to use when computing each round key
|
||||
shares_t* mask2_shares = allocateShares(LOWMC_N);
|
||||
uint8_t* unopened_msgs = NULL;
|
||||
@ -53,6 +30,9 @@ static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_
|
||||
copyShares(key_masks, mask_shares);
|
||||
|
||||
#if defined(REDUCED_ROUND_KEY_COMPUTATION)
|
||||
mzd_local_t nl_part[((LOWMC_R * 32) + 255) / 256];
|
||||
shares_t* nl_part_masks = allocateShares(LOWMC_R * 32);
|
||||
|
||||
MPC_MUL(state, maskedKey, LOWMC_INSTANCE.k0_matrix,
|
||||
mask_shares); // roundKey = maskedKey * KMatrix[0]
|
||||
|
||||
@ -61,6 +41,7 @@ static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_
|
||||
MPC_MUL_MC(nl_part, maskedKey, LOWMC_INSTANCE.precomputed_non_linear_part_matrix,
|
||||
LOWMC_INSTANCE.precomputed_constant_non_linear, nl_part_masks, key_masks);
|
||||
#if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION)
|
||||
mzd_local_t state2[((LOWMC_N) + 255) / 256];
|
||||
for (uint32_t r = 0; r < LOWMC_R - 1; r++) {
|
||||
mpc_sbox(state, mask_shares, tapes, msgs, unopened_msgs, params);
|
||||
mpc_xor_masks_nl(mask_shares, mask_shares, nl_part_masks, r*32 + 2, 30);
|
||||
@ -97,7 +78,9 @@ static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_
|
||||
mask_shares); // state = state * LMatrix (r-1)
|
||||
}
|
||||
#endif
|
||||
freeShares(nl_part_masks);
|
||||
#else
|
||||
mzd_local_t roundKey[((LOWMC_N) + 255) / 256];
|
||||
MPC_MUL(roundKey, maskedKey, LOWMC_INSTANCE.k0_matrix,
|
||||
mask_shares); // roundKey = maskedKey * KMatrix[0]
|
||||
XOR(state, roundKey, plaintext);
|
||||
@ -149,13 +132,8 @@ static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_
|
||||
msgsTranspose(msgs);
|
||||
|
||||
free(unopened_msgs);
|
||||
mzd_local_free(state);
|
||||
mzd_local_free(state2);
|
||||
mzd_local_free(roundKey);
|
||||
mzd_local_free(nl_part);
|
||||
freeShares(key_masks);
|
||||
freeShares(mask2_shares);
|
||||
freeShares(nl_part_masks);
|
||||
|
||||
Exit:
|
||||
return ret;
|
||||
|
||||
102
src/sig/picnic/external/picnic2_simulate_mul.c
vendored
102
src/sig/picnic/external/picnic2_simulate_mul.c
vendored
@ -219,6 +219,7 @@ static const block_t nl_part_block_masks[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(PICNIC_STATIC)
|
||||
/* transpose a 64x64 bit matrix using Eklundh's algorithm
|
||||
this variant assumes that the bit with index 0 is the lsb of byte 0
|
||||
e.g., 76543210 fedcba98 ...
|
||||
@ -254,6 +255,7 @@ void transpose_64_64_lsb(const uint64_t* in, uint64_t* out) {
|
||||
width /= 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* transpose a 64x64 bit matrix using Eklundh's algorithm
|
||||
this variant assumes that the bit with index 0 is the msb of byte 0
|
||||
@ -268,9 +270,8 @@ static void transpose_64_64_uint64(const uint64_t* in, uint64_t* out) {
|
||||
const uint32_t logn = 6;
|
||||
|
||||
// copy in to out and transpose in-place
|
||||
memcpy(out, in, 64 * sizeof(uint64_t));
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
out[i] = bswap64(out[i]);
|
||||
out[i] = bswap64(in[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < logn; i++) {
|
||||
@ -299,6 +300,21 @@ static void transpose_64_64_uint64(const uint64_t* in, uint64_t* out) {
|
||||
|
||||
#if defined(WITH_OPT)
|
||||
#if defined(WITH_SSE2) || defined(WITH_NEON)
|
||||
ATTR_TARGET_S128
|
||||
static inline void memcpy_bswap64_64_s128(word128* out, const word128* in) {
|
||||
#if defined(WITH_NEON)
|
||||
for (size_t i = 0; i < 32; ++i) {
|
||||
out[i] = vreinterpretq_u64_u8(vrev64q_u8(vreinterpretq_u8_u64(in[i])));
|
||||
}
|
||||
#elif defined(WITH_SSE2)
|
||||
for (size_t i = 0; i < 32; ++i) {
|
||||
word128 tmp = _mm_or_si128(_mm_slli_epi16(in[i], 8), _mm_srli_epi16(in[i], 8));
|
||||
tmp = _mm_shufflelo_epi16(tmp, _MM_SHUFFLE(0, 1, 2, 3));
|
||||
out[i] = _mm_shufflehi_epi16(tmp, _MM_SHUFFLE(0, 1, 2, 3));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* transpose a 64x64 bit matrix using Eklundh's algorithm
|
||||
this variant assumes that the bit with index 0 is the msb of byte 0
|
||||
e.g., 01234567 89abcdef ...
|
||||
@ -313,17 +329,12 @@ static void transpose_64_64_s128(const uint64_t* in, uint64_t* out) {
|
||||
const uint32_t logn = 6;
|
||||
|
||||
// copy in to out and transpose in-place
|
||||
memcpy(out, in, 64 * sizeof(uint64_t));
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
out[i] = bswap64(out[i]);
|
||||
}
|
||||
|
||||
word128* out128 = (word128*)out;
|
||||
const word128* in128 = (const word128*)in;
|
||||
memcpy_bswap64_64_s128(out128, in128);
|
||||
|
||||
for (uint32_t i = 0; i < logn - 1; i++) {
|
||||
word128 mask = _mm_set1_epi64x(TRANSPOSE_MASKS64[i]);
|
||||
word128 inv_mask = mm128_xor(mask, _mm_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF)));
|
||||
|
||||
const word128 mask = mm128_broadcast_u64(TRANSPOSE_MASKS64[i]);
|
||||
for (uint32_t j = 0; j < nswaps; j++) {
|
||||
for (uint32_t k = 0; k < width; k += 2) {
|
||||
// uint32_t i1 = k/2 + width * j;
|
||||
@ -334,16 +345,15 @@ static void transpose_64_64_s128(const uint64_t* in, uint64_t* out) {
|
||||
word128 t1 = out128[i1 / 2];
|
||||
word128 t2 = out128[i2 / 2];
|
||||
|
||||
out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), _mm_srli_epi64(mm128_and(t2, mask), width));
|
||||
out128[i2 / 2] =
|
||||
mm128_xor(mm128_and(t2, inv_mask), _mm_slli_epi64(mm128_and(t1, inv_mask), width));
|
||||
out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), mm128_sr_u64(mm128_and(t2, mask), width));
|
||||
out128[i2 / 2] = mm128_xor(mm128_nand(mask, t2), mm128_sl_u64(mm128_nand(mask, t1), width));
|
||||
}
|
||||
}
|
||||
nswaps *= 2;
|
||||
width /= 2;
|
||||
}
|
||||
uint64_t mask = TRANSPOSE_MASKS64[5];
|
||||
uint64_t inv_mask = ~mask;
|
||||
const uint64_t mask = TRANSPOSE_MASKS64[5];
|
||||
const uint64_t inv_mask = ~mask;
|
||||
for (uint32_t j = 0; j < nswaps; j++) {
|
||||
for (uint32_t k = 0; k < width; k++) {
|
||||
uint32_t i1 = k + 2 * width * j;
|
||||
@ -356,13 +366,25 @@ static void transpose_64_64_s128(const uint64_t* in, uint64_t* out) {
|
||||
out[i2] = (t2 & inv_mask) ^ ((t1 & inv_mask) << width);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
out[i] = bswap64(out[i]);
|
||||
}
|
||||
|
||||
memcpy_bswap64_64_s128(out128, out128);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_AVX2)
|
||||
ATTR_TARGET_AVX2
|
||||
static inline void memcpy_bswap64_64_s256(word256* out, const word256* in) {
|
||||
const word256 shuffle = _mm256_set_epi8(
|
||||
// two bswap64s in first lane
|
||||
8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7,
|
||||
// two bswap64s in second lane
|
||||
8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
out[i] = _mm256_shuffle_epi8(in[i], shuffle);
|
||||
}
|
||||
}
|
||||
|
||||
/* transpose a 64x64 bit matrix using Eklundh's algorithm
|
||||
this variant assumes that the bit with index 0 is the msb of byte 0
|
||||
e.g., 01234567 89abcdef ...
|
||||
@ -374,20 +396,16 @@ static void transpose_64_64_s256(const uint64_t* in, uint64_t* out) {
|
||||
UINT64_C(0xF0F0F0F0F0F0F0F0), UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xAAAAAAAAAAAAAAAA)};
|
||||
|
||||
uint32_t width = 32, nswaps = 1;
|
||||
const uint32_t logn = 6;
|
||||
|
||||
// copy in to out and transpose in-place
|
||||
memcpy(out, in, 64 * sizeof(uint64_t));
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
out[i] = bswap64(out[i]);
|
||||
}
|
||||
static const uint32_t logn = 6;
|
||||
|
||||
const word256* in256 = (const word256*)in;
|
||||
word256* out256 = (word256*)out;
|
||||
|
||||
for (uint32_t i = 0; i < logn - 2; i++) {
|
||||
word256 mask = _mm256_set1_epi64x(TRANSPOSE_MASKS64[i]);
|
||||
word256 inv_mask = mm256_xor(mask, _mm256_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF)));
|
||||
// copy in to out and swap bytes
|
||||
memcpy_bswap64_64_s256(out256, in256);
|
||||
|
||||
for (uint32_t i = 0; i < logn - 2; i++) {
|
||||
const word256 mask = _mm256_set1_epi64x(TRANSPOSE_MASKS64[i]);
|
||||
for (uint32_t j = 0; j < nswaps; j++) {
|
||||
for (uint32_t k = 0; k < width; k += 4) {
|
||||
uint32_t i1 = k + 2 * width * j;
|
||||
@ -399,16 +417,15 @@ static void transpose_64_64_s256(const uint64_t* in, uint64_t* out) {
|
||||
out256[i1 / 4] =
|
||||
mm256_xor(mm256_and(t1, mask), _mm256_srli_epi64(mm256_and(t2, mask), width));
|
||||
out256[i2 / 4] =
|
||||
mm256_xor(mm256_and(t2, inv_mask), _mm256_slli_epi64(mm256_and(t1, inv_mask), width));
|
||||
mm256_xor(mm256_nand(mask, t2), _mm256_slli_epi64(mm256_nand(mask, t1), width));
|
||||
}
|
||||
}
|
||||
nswaps *= 2;
|
||||
width /= 2;
|
||||
}
|
||||
{
|
||||
word128* out128 = (word128*)out;
|
||||
word128 mask = _mm_set1_epi64x(TRANSPOSE_MASKS64[4]);
|
||||
word128 inv_mask = mm128_xor(mask, _mm_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF)));
|
||||
word128* out128 = (word128*)out;
|
||||
const word128 mask = mm128_broadcast_u64(TRANSPOSE_MASKS64[4]);
|
||||
|
||||
for (uint32_t j = 0; j < nswaps; j++) {
|
||||
for (uint32_t k = 0; k < width; k += 2) {
|
||||
@ -418,17 +435,16 @@ static void transpose_64_64_s256(const uint64_t* in, uint64_t* out) {
|
||||
word128 t1 = out128[i1 / 2];
|
||||
word128 t2 = out128[i2 / 2];
|
||||
|
||||
out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), _mm_srli_epi64(mm128_and(t2, mask), width));
|
||||
out128[i2 / 2] =
|
||||
mm128_xor(mm128_and(t2, inv_mask), _mm_slli_epi64(mm128_and(t1, inv_mask), width));
|
||||
out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), mm128_sr_u64(mm128_and(t2, mask), width));
|
||||
out128[i2 / 2] = mm128_xor(mm128_nand(mask, t2), mm128_sl_u64(mm128_nand(mask, t1), width));
|
||||
}
|
||||
}
|
||||
nswaps *= 2;
|
||||
width /= 2;
|
||||
}
|
||||
|
||||
uint64_t mask = TRANSPOSE_MASKS64[5];
|
||||
uint64_t inv_mask = ~mask;
|
||||
const uint64_t mask = TRANSPOSE_MASKS64[5];
|
||||
const uint64_t inv_mask = ~mask;
|
||||
for (uint32_t j = 0; j < nswaps; j++) {
|
||||
for (uint32_t k = 0; k < width; k++) {
|
||||
uint32_t i1 = k + 2 * width * j;
|
||||
@ -441,15 +457,13 @@ static void transpose_64_64_s256(const uint64_t* in, uint64_t* out) {
|
||||
out[i2] = (t2 & inv_mask) ^ ((t1 & inv_mask) << width);
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < 64; i++) {
|
||||
out[i] = bswap64(out[i]);
|
||||
}
|
||||
|
||||
memcpy_bswap64_64_s256(out256, out256);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void transpose_64_64(const uint64_t* in, uint64_t* out) {
|
||||
|
||||
#if defined(WITH_OPT)
|
||||
#if defined(WITH_AVX2)
|
||||
if (CPU_SUPPORTS_AVX2) {
|
||||
@ -511,12 +525,6 @@ void xor_word_array(uint32_t* out, const uint32_t* in1, const uint32_t* in2, uin
|
||||
}
|
||||
}
|
||||
|
||||
void xor_array_RC(uint8_t* out, const uint8_t* in1, const uint8_t* in2, uint32_t length) {
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
out[i] = in1[i] ^ in2[length - 1 - i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Get one bit from a byte array */
|
||||
uint8_t getBit(const uint8_t* array, uint32_t bitNumber) {
|
||||
return (array[bitNumber / 8] >> (7 - (bitNumber % 8))) & 0x01;
|
||||
|
||||
@ -111,11 +111,12 @@ void copyShares(shares_t* dst, shares_t* src);
|
||||
uint8_t getBit(const uint8_t* array, uint32_t bitNumber);
|
||||
void setBit(uint8_t* bytes, uint32_t bitNumber, uint8_t val);
|
||||
void xor_word_array(uint32_t* out, const uint32_t* in1, const uint32_t* in2, uint32_t length);
|
||||
void xor_array_RC(uint8_t* out, const uint8_t* in1, const uint8_t* in2, uint32_t length);
|
||||
uint64_t tapesToWord(randomTape_t* tapes);
|
||||
uint64_t tapesToParityOfWord(randomTape_t* tapes, uint8_t without_last);
|
||||
void reconstructShares(uint32_t* output, shares_t* shares);
|
||||
#if defined(PICNIC_STATIC)
|
||||
void transpose_64_64_lsb(const uint64_t* in, uint64_t* out);
|
||||
#endif
|
||||
void transpose_64_64(const uint64_t* in, uint64_t* out);
|
||||
|
||||
#endif
|
||||
|
||||
35
src/sig/picnic/external/picnic2_tree.c
vendored
35
src/sig/picnic/external/picnic2_tree.c
vendored
@ -10,6 +10,10 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
@ -19,7 +23,6 @@
|
||||
#include "picnic.h"
|
||||
#include "picnic2_tree.h"
|
||||
#include "picnic2_types.h"
|
||||
#include "picnic_impl.h"
|
||||
|
||||
static int contains(size_t* list, size_t len, size_t value) {
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
@ -117,13 +120,11 @@ static void hashSeed(uint8_t* digest, const uint8_t* inputSeed, uint8_t* salt, u
|
||||
size_t repIndex, size_t nodeIndex, const picnic_instance_t* params) {
|
||||
hash_context ctx;
|
||||
|
||||
hash_init_prefix(&ctx, params, hashPrefix);
|
||||
hash_init_prefix(&ctx, params->digest_size, hashPrefix);
|
||||
hash_update(&ctx, inputSeed, params->seed_size);
|
||||
hash_update(&ctx, salt, SALT_SIZE);
|
||||
uint16_t repIndexLE = htole16((uint16_t)repIndex);
|
||||
hash_update(&ctx, (uint8_t*)&repIndexLE, sizeof(uint16_t));
|
||||
uint16_t nodeIndexLE = htole16((uint16_t)nodeIndex);
|
||||
hash_update(&ctx, (uint8_t*)&nodeIndexLE, sizeof(uint16_t));
|
||||
hash_update_uint16_le(&ctx, repIndex);
|
||||
hash_update_uint16_le(&ctx, nodeIndex);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, digest, 2 * params->seed_size);
|
||||
}
|
||||
@ -133,19 +134,16 @@ static void hashSeed_x4(uint8_t** digest, const uint8_t** inputSeed, uint8_t* sa
|
||||
const picnic_instance_t* params) {
|
||||
hash_context_x4 ctx;
|
||||
|
||||
hash_init_prefix_x4(&ctx, params, hashPrefix);
|
||||
hash_init_prefix_x4(&ctx, params->digest_size, hashPrefix);
|
||||
hash_update_x4(&ctx, inputSeed, params->seed_size);
|
||||
|
||||
const uint8_t* salts[4] = {salt, salt, salt, salt};
|
||||
hash_update_x4(&ctx, salts, SALT_SIZE);
|
||||
uint16_t repIndexLE = htole16((uint16_t)repIndex);
|
||||
const uint8_t* reps[4] = {(uint8_t*)&repIndexLE, (uint8_t*)&repIndexLE, (uint8_t*)&repIndexLE,
|
||||
(uint8_t*)&repIndexLE};
|
||||
hash_update_x4(&ctx, reps, sizeof(uint16_t));
|
||||
uint16_t nodeIndexLE[4] = {htole16((uint16_t)nodeIndex), htole16((uint16_t)nodeIndex + 1),
|
||||
htole16((uint16_t)nodeIndex + 2), htole16((uint16_t)nodeIndex + 3)};
|
||||
const uint8_t* nodes[4] = {(uint8_t*)&nodeIndexLE[0], (uint8_t*)&nodeIndexLE[1],
|
||||
(uint8_t*)&nodeIndexLE[2], (uint8_t*)&nodeIndexLE[3]};
|
||||
hash_update_x4(&ctx, nodes, sizeof(uint16_t));
|
||||
hash_update_x4_uint16_le(&ctx, repIndex);
|
||||
|
||||
const uint16_t nodes[4] = {nodeIndex, nodeIndex + 1, nodeIndex + 2, nodeIndex + 3};
|
||||
hash_update_x4_uint16s_le(&ctx, nodes);
|
||||
|
||||
hash_final_x4(&ctx);
|
||||
hash_squeeze_x4(&ctx, digest, 2 * params->seed_size);
|
||||
}
|
||||
@ -423,7 +421,7 @@ static void computeParentHash(tree_t* tree, size_t child, uint8_t* salt,
|
||||
/* Compute parent data = H(left child data || [right child data] || salt || parent idx) */
|
||||
hash_context ctx;
|
||||
|
||||
hash_init_prefix(&ctx, params, HASH_PREFIX_3);
|
||||
hash_init_prefix(&ctx, params->digest_size, HASH_PREFIX_3);
|
||||
hash_update(&ctx, tree->nodes[2 * parent + 1], params->digest_size);
|
||||
if (hasRightChild(tree, parent)) {
|
||||
/* One node may not have a right child when there's an odd number of leaves */
|
||||
@ -431,8 +429,7 @@ static void computeParentHash(tree_t* tree, size_t child, uint8_t* salt,
|
||||
}
|
||||
|
||||
hash_update(&ctx, salt, SALT_SIZE);
|
||||
uint16_t parentLE = htole16((uint16_t)parent);
|
||||
hash_update(&ctx, (uint8_t*)&parentLE, sizeof(uint16_t));
|
||||
hash_update_uint16_le(&ctx, parent);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, tree->nodes[parent], params->digest_size);
|
||||
tree->haveNode[parent] = 1;
|
||||
|
||||
3
src/sig/picnic/external/picnic2_tree.h
vendored
3
src/sig/picnic/external/picnic2_tree.h
vendored
@ -12,6 +12,9 @@
|
||||
|
||||
#ifndef PICNIC2_TREE_H
|
||||
#define PICNIC2_TREE_H
|
||||
|
||||
#include "picnic_instances.h"
|
||||
|
||||
/*
|
||||
* Represents a (nearly) complete binary tree, stored in memory as an array.
|
||||
* The root is at nodes[0], and the left child of node k is 2k + 1, the right
|
||||
|
||||
35
src/sig/picnic/external/picnic2_types.c
vendored
35
src/sig/picnic/external/picnic2_types.c
vendored
@ -10,13 +10,18 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "picnic2_types.h"
|
||||
#include "compat.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "picnic2_types.h"
|
||||
#include "compat.h"
|
||||
|
||||
shares_t* allocateShares(size_t count) {
|
||||
shares_t* shares = malloc(sizeof(shares_t));
|
||||
|
||||
@ -110,32 +115,6 @@ void freeSignature2(signature2_t* sig, const picnic_instance_t* params) {
|
||||
free(sig->proofs);
|
||||
}
|
||||
|
||||
commitments_t* allocateCommitments(const picnic_instance_t* params, size_t numCommitments) {
|
||||
commitments_t* commitments = malloc(params->num_rounds * sizeof(commitments_t));
|
||||
|
||||
commitments->nCommitments = (numCommitments) ? numCommitments : params->num_MPC_parties;
|
||||
|
||||
uint8_t* slab = malloc(params->num_rounds * (commitments->nCommitments * params->digest_size +
|
||||
commitments->nCommitments * sizeof(uint8_t*)));
|
||||
|
||||
for (uint32_t i = 0; i < params->num_rounds; i++) {
|
||||
commitments[i].hashes = (uint8_t**)slab;
|
||||
slab += commitments->nCommitments * sizeof(uint8_t*);
|
||||
|
||||
for (uint32_t j = 0; j < commitments->nCommitments; j++) {
|
||||
commitments[i].hashes[j] = slab;
|
||||
slab += params->digest_size;
|
||||
}
|
||||
}
|
||||
|
||||
return commitments;
|
||||
}
|
||||
|
||||
void freeCommitments(commitments_t* commitments) {
|
||||
free(commitments[0].hashes);
|
||||
free(commitments);
|
||||
}
|
||||
|
||||
/* Allocate one commitments_t object with capacity for numCommitments values */
|
||||
void allocateCommitments2(commitments_t* commitments, const picnic_instance_t* params,
|
||||
size_t numCommitments) {
|
||||
|
||||
3
src/sig/picnic/external/picnic2_types.h
vendored
3
src/sig/picnic/external/picnic2_types.h
vendored
@ -53,9 +53,6 @@ void finalFreeRandomTape(randomTape_t* tape);
|
||||
void allocateProof2(proof2_t* proof, const picnic_instance_t* params);
|
||||
void freeProof2(proof2_t* proof);
|
||||
|
||||
commitments_t* allocateCommitments(const picnic_instance_t* params, size_t nCommitments);
|
||||
void freeCommitments(commitments_t* commitments);
|
||||
|
||||
void allocateCommitments2(commitments_t* commitments, const picnic_instance_t* params,
|
||||
size_t nCommitments);
|
||||
void freeCommitments2(commitments_t* commitments);
|
||||
|
||||
274
src/sig/picnic/external/picnic_impl.c
vendored
274
src/sig/picnic/external/picnic_impl.c
vendored
@ -16,7 +16,6 @@
|
||||
#include "io.h"
|
||||
#include "kdf_shake.h"
|
||||
#include "lowmc.h"
|
||||
#include "lowmc_pars.h"
|
||||
#include "mpc_lowmc.h"
|
||||
#include "picnic_impl.h"
|
||||
#include <oqs/rand.h>
|
||||
@ -45,14 +44,6 @@ typedef struct {
|
||||
unsigned int round_number;
|
||||
} sorting_helper_t;
|
||||
|
||||
// Prefix values for domain separation
|
||||
const uint8_t HASH_PREFIX_0 = 0;
|
||||
const uint8_t HASH_PREFIX_1 = 1;
|
||||
const uint8_t HASH_PREFIX_2 = 2;
|
||||
const uint8_t HASH_PREFIX_3 = 3;
|
||||
const uint8_t HASH_PREFIX_4 = 4;
|
||||
const uint8_t HASH_PREFIX_5 = 5;
|
||||
|
||||
/**
|
||||
* Collapse challenge from one char per challenge to bit array.
|
||||
*/
|
||||
@ -243,73 +234,54 @@ static void proof_free(sig_proof_t* prf) {
|
||||
free(prf);
|
||||
}
|
||||
|
||||
static void kdf_shake_update_key_intLE(kdf_shake_t* kdf, uint16_t x) {
|
||||
const uint16_t x_le = htole16(x);
|
||||
kdf_shake_update_key(kdf, (const uint8_t*)&x_le, sizeof(x_le));
|
||||
}
|
||||
|
||||
static void kdf_shake_x4_update_key_intLE(kdf_shake_x4_t* kdf, uint16_t x) {
|
||||
const uint16_t x_le = htole16(x);
|
||||
const uint8_t* ptr[4] = {(const uint8_t*)&x_le, (const uint8_t*)&x_le, (const uint8_t*)&x_le,
|
||||
(const uint8_t*)&x_le};
|
||||
kdf_shake_x4_update_key(kdf, ptr, sizeof(x_le));
|
||||
}
|
||||
|
||||
static void kdf_shake_x4_update_key_intLE_round(kdf_shake_x4_t* kdf, const uint16_t x[4]) {
|
||||
|
||||
const uint16_t x0_le = htole16(x[0]);
|
||||
const uint16_t x1_le = htole16(x[1]);
|
||||
const uint16_t x2_le = htole16(x[2]);
|
||||
const uint16_t x3_le = htole16(x[3]);
|
||||
const uint8_t* ptr[4] = {(const uint8_t*)&x0_le, (const uint8_t*)&x1_le, (const uint8_t*)&x2_le,
|
||||
(const uint8_t*)&x3_le};
|
||||
kdf_shake_x4_update_key(kdf, ptr, sizeof(x0_le));
|
||||
}
|
||||
|
||||
static void kdf_init_from_seed(kdf_shake_t* kdf, const uint8_t* seed, const uint8_t* salt,
|
||||
uint16_t round_number, uint16_t player_number,
|
||||
bool include_input_size, const picnic_instance_t* pp) {
|
||||
const size_t digest_size = pp->digest_size;
|
||||
|
||||
// Hash the seed with H_2.
|
||||
kdf_shake_init_prefix(kdf, pp, HASH_PREFIX_2);
|
||||
kdf_shake_init_prefix(kdf, digest_size, HASH_PREFIX_2);
|
||||
kdf_shake_update_key(kdf, seed, pp->seed_size);
|
||||
kdf_shake_finalize_key(kdf);
|
||||
|
||||
uint8_t tmp[MAX_DIGEST_SIZE];
|
||||
kdf_shake_get_randomness(kdf, tmp, pp->digest_size);
|
||||
kdf_shake_get_randomness(kdf, tmp, digest_size);
|
||||
kdf_shake_clear(kdf);
|
||||
|
||||
// Initialize KDF with H_2(seed) || salt || round_number || player_number || output_size.
|
||||
kdf_shake_init(kdf, pp);
|
||||
kdf_shake_update_key(kdf, tmp, pp->digest_size);
|
||||
kdf_shake_init(kdf, digest_size);
|
||||
kdf_shake_update_key(kdf, tmp, digest_size);
|
||||
kdf_shake_update_key(kdf, salt, SALT_SIZE);
|
||||
kdf_shake_update_key_intLE(kdf, round_number);
|
||||
kdf_shake_update_key_intLE(kdf, player_number);
|
||||
kdf_shake_update_key_intLE(kdf, pp->view_size + (include_input_size ? pp->input_size : 0));
|
||||
kdf_shake_update_key_uint16_le(kdf, round_number);
|
||||
kdf_shake_update_key_uint16_le(kdf, player_number);
|
||||
kdf_shake_update_key_uint16_le(kdf, pp->view_size + (include_input_size ? pp->input_size : 0));
|
||||
kdf_shake_finalize_key(kdf);
|
||||
}
|
||||
|
||||
static void kdf_init_x4_from_seed(kdf_shake_x4_t* kdf, const uint8_t** seed, const uint8_t* salt,
|
||||
const uint16_t round_number[4], const uint16_t player_number,
|
||||
bool include_input_size, const picnic_instance_t* pp) {
|
||||
const size_t digest_size = pp->digest_size;
|
||||
|
||||
// Hash the seed with H_2.
|
||||
kdf_shake_x4_init_prefix(kdf, pp, HASH_PREFIX_2);
|
||||
kdf_shake_x4_init_prefix(kdf, digest_size, HASH_PREFIX_2);
|
||||
kdf_shake_x4_update_key(kdf, seed, pp->seed_size);
|
||||
kdf_shake_x4_finalize_key(kdf);
|
||||
|
||||
uint8_t tmp[4][MAX_DIGEST_SIZE];
|
||||
uint8_t* tmpptr[4] = {tmp[0], tmp[1], tmp[2], tmp[3]};
|
||||
const uint8_t* tmpptr_const[4] = {tmp[0], tmp[1], tmp[2], tmp[3]};
|
||||
kdf_shake_x4_get_randomness(kdf, tmpptr, pp->digest_size);
|
||||
kdf_shake_x4_get_randomness(kdf, tmpptr, digest_size);
|
||||
kdf_shake_x4_clear(kdf);
|
||||
|
||||
// Initialize KDF with H_2(seed) || salt || round_number || player_number || output_size.
|
||||
kdf_shake_x4_init(kdf, pp);
|
||||
kdf_shake_x4_update_key(kdf, tmpptr_const, pp->digest_size);
|
||||
kdf_shake_x4_init(kdf, digest_size);
|
||||
kdf_shake_x4_update_key(kdf, tmpptr_const, digest_size);
|
||||
const uint8_t* saltptr[4] = {salt, salt, salt, salt};
|
||||
kdf_shake_x4_update_key(kdf, saltptr, SALT_SIZE);
|
||||
kdf_shake_x4_update_key_intLE_round(kdf, round_number);
|
||||
kdf_shake_x4_update_key_intLE(kdf, player_number);
|
||||
kdf_shake_x4_update_key_intLE(kdf, pp->view_size + (include_input_size ? pp->input_size : 0));
|
||||
kdf_shake_x4_update_key_uint16s_le(kdf, round_number);
|
||||
kdf_shake_x4_update_key_uint16_le(kdf, player_number);
|
||||
kdf_shake_x4_update_key_uint16_le(kdf, pp->view_size + (include_input_size ? pp->input_size : 0));
|
||||
kdf_shake_x4_finalize_key(kdf);
|
||||
}
|
||||
|
||||
@ -399,14 +371,14 @@ static void hash_commitment(const picnic_instance_t* pp, proof_round_t* prf_roun
|
||||
|
||||
hash_context ctx;
|
||||
// hash the seed
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_4);
|
||||
hash_init_prefix(&ctx, hashlen, HASH_PREFIX_4);
|
||||
hash_update(&ctx, prf_round->seeds[vidx], pp->seed_size);
|
||||
hash_final(&ctx);
|
||||
uint8_t tmp[MAX_DIGEST_SIZE];
|
||||
hash_squeeze(&ctx, tmp, hashlen);
|
||||
|
||||
// compute H_0(H_4(seed), view)
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_0);
|
||||
hash_init_prefix(&ctx, hashlen, HASH_PREFIX_0);
|
||||
hash_update(&ctx, tmp, hashlen);
|
||||
// hash input share
|
||||
hash_update(&ctx, prf_round->input_shares[vidx], pp->input_size);
|
||||
@ -427,7 +399,7 @@ static void hash_commitment_x4(const picnic_instance_t* pp, proof_round_t* prf_r
|
||||
|
||||
hash_context_x4 ctx;
|
||||
// hash the seed
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_4);
|
||||
hash_init_prefix_x4(&ctx, hashlen, HASH_PREFIX_4);
|
||||
const uint8_t* seeds[4] = {prf_round[0].seeds[vidx], prf_round[1].seeds[vidx],
|
||||
prf_round[2].seeds[vidx], prf_round[3].seeds[vidx]};
|
||||
hash_update_x4(&ctx, seeds, pp->seed_size);
|
||||
@ -438,7 +410,7 @@ static void hash_commitment_x4(const picnic_instance_t* pp, proof_round_t* prf_r
|
||||
hash_squeeze_x4(&ctx, tmpptr, hashlen);
|
||||
|
||||
// compute H_0(H_4(seed), view)
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_0);
|
||||
hash_init_prefix_x4(&ctx, hashlen, HASH_PREFIX_0);
|
||||
hash_update_x4(&ctx, tmpptr_const, hashlen);
|
||||
// hash input share
|
||||
const uint8_t* input_shares[4] = {
|
||||
@ -469,7 +441,7 @@ static void hash_commitment_x4_verify(const picnic_instance_t* pp, const sorting
|
||||
|
||||
hash_context_x4 ctx;
|
||||
// hash the seed
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_4);
|
||||
hash_init_prefix_x4(&ctx, hashlen, HASH_PREFIX_4);
|
||||
const uint8_t* seeds[4] = {helper[0].round->seeds[vidx], helper[1].round->seeds[vidx],
|
||||
helper[2].round->seeds[vidx], helper[3].round->seeds[vidx]};
|
||||
hash_update_x4(&ctx, seeds, pp->seed_size);
|
||||
@ -480,7 +452,7 @@ static void hash_commitment_x4_verify(const picnic_instance_t* pp, const sorting
|
||||
hash_squeeze_x4(&ctx, tmpptr, hashlen);
|
||||
|
||||
// compute H_0(H_4(seed), view)
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_0);
|
||||
hash_init_prefix_x4(&ctx, hashlen, HASH_PREFIX_0);
|
||||
hash_update_x4(&ctx, tmpptr_const, hashlen);
|
||||
// hash input share
|
||||
const uint8_t* input_shares[4] = {
|
||||
@ -517,7 +489,7 @@ static void H3_compute(const picnic_instance_t* pp, uint8_t* hash, uint8_t* ch)
|
||||
while (ch < eof) {
|
||||
if (bit_idx >= digest_size_bits) {
|
||||
hash_context ctx;
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_1);
|
||||
hash_init_prefix(&ctx, digest_size, HASH_PREFIX_1);
|
||||
hash_update(&ctx, hash, digest_size);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, hash, digest_size);
|
||||
@ -557,7 +529,7 @@ static void H3_verify(const picnic_instance_t* pp, sig_proof_t* prf, const uint8
|
||||
const size_t output_size = pp->output_size;
|
||||
|
||||
hash_context ctx;
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_1);
|
||||
hash_init_prefix(&ctx, digest_size, HASH_PREFIX_1);
|
||||
|
||||
// hash output shares
|
||||
proof_round_t* round = prf->round;
|
||||
@ -655,7 +627,7 @@ static void H3(const picnic_instance_t* pp, sig_proof_t* prf, const uint8_t* cir
|
||||
const size_t num_rounds = pp->num_rounds;
|
||||
|
||||
hash_context ctx;
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_1);
|
||||
hash_init_prefix(&ctx, pp->digest_size, HASH_PREFIX_1);
|
||||
|
||||
// hash output shares
|
||||
hash_update(&ctx, prf->round[0].output_shares[0], pp->output_size * num_rounds * SC_PROOF);
|
||||
@ -681,16 +653,14 @@ static void H3(const picnic_instance_t* pp, sig_proof_t* prf, const uint8_t* cir
|
||||
*/
|
||||
static void unruh_G(const picnic_instance_t* pp, proof_round_t* prf_round, unsigned int vidx,
|
||||
bool include_is) {
|
||||
hash_context ctx;
|
||||
|
||||
const size_t outputlen =
|
||||
include_is ? pp->unruh_with_input_bytes_size : pp->unruh_without_input_bytes_size;
|
||||
const uint16_t size_le = htole16(outputlen);
|
||||
const size_t digest_size = pp->digest_size;
|
||||
const size_t seedlen = pp->seed_size;
|
||||
|
||||
// Hash the seed with H_5, store digest in output
|
||||
hash_init_prefix(&ctx, pp, HASH_PREFIX_5);
|
||||
hash_context ctx;
|
||||
hash_init_prefix(&ctx, digest_size, HASH_PREFIX_5);
|
||||
hash_update(&ctx, prf_round->seeds[vidx], seedlen);
|
||||
hash_final(&ctx);
|
||||
|
||||
@ -698,13 +668,13 @@ static void unruh_G(const picnic_instance_t* pp, proof_round_t* prf_round, unsig
|
||||
hash_squeeze(&ctx, tmp, digest_size);
|
||||
|
||||
// Hash H_5(seed), the view, and the length
|
||||
hash_init(&ctx, pp);
|
||||
hash_init(&ctx, digest_size);
|
||||
hash_update(&ctx, tmp, digest_size);
|
||||
if (include_is) {
|
||||
hash_update(&ctx, prf_round->input_shares[vidx], pp->input_size);
|
||||
}
|
||||
hash_update(&ctx, prf_round->communicated_bits[vidx], pp->view_size);
|
||||
hash_update(&ctx, (const uint8_t*)&size_le, sizeof(uint16_t));
|
||||
hash_update_uint16_le(&ctx, outputlen);
|
||||
hash_final(&ctx);
|
||||
hash_squeeze(&ctx, prf_round->gs[vidx], outputlen);
|
||||
}
|
||||
@ -714,16 +684,14 @@ static void unruh_G(const picnic_instance_t* pp, proof_round_t* prf_round, unsig
|
||||
*/
|
||||
static void unruh_G_x4(const picnic_instance_t* pp, proof_round_t* prf_round, unsigned int vidx,
|
||||
bool include_is) {
|
||||
hash_context_x4 ctx;
|
||||
|
||||
const size_t outputlen =
|
||||
include_is ? pp->unruh_with_input_bytes_size : pp->unruh_without_input_bytes_size;
|
||||
const uint16_t size_le = htole16(outputlen);
|
||||
const size_t digest_size = pp->digest_size;
|
||||
const size_t seedlen = pp->seed_size;
|
||||
|
||||
// Hash the seed with H_5, store digest in output
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_5);
|
||||
hash_context_x4 ctx;
|
||||
hash_init_prefix_x4(&ctx, digest_size, HASH_PREFIX_5);
|
||||
const uint8_t* seeds[4] = {prf_round[0].seeds[vidx], prf_round[1].seeds[vidx],
|
||||
prf_round[2].seeds[vidx], prf_round[3].seeds[vidx]};
|
||||
hash_update_x4(&ctx, seeds, seedlen);
|
||||
@ -735,7 +703,7 @@ static void unruh_G_x4(const picnic_instance_t* pp, proof_round_t* prf_round, un
|
||||
hash_squeeze_x4(&ctx, tmpptr, digest_size);
|
||||
|
||||
// Hash H_5(seed), the view, and the length
|
||||
hash_init_x4(&ctx, pp);
|
||||
hash_init_x4(&ctx, digest_size);
|
||||
hash_update_x4(&ctx, tmpptr_const, digest_size);
|
||||
if (include_is) {
|
||||
const uint8_t* input_shares[4] = {
|
||||
@ -750,9 +718,7 @@ static void unruh_G_x4(const picnic_instance_t* pp, proof_round_t* prf_round, un
|
||||
prf_round[3].communicated_bits[vidx],
|
||||
};
|
||||
hash_update_x4(&ctx, communicated_bits, pp->view_size);
|
||||
const uint8_t* sizes[4] = {(const uint8_t*)&size_le, (const uint8_t*)&size_le,
|
||||
(const uint8_t*)&size_le, (const uint8_t*)&size_le};
|
||||
hash_update_x4(&ctx, sizes, sizeof(uint16_t));
|
||||
hash_update_x4_uint16_le(&ctx, outputlen);
|
||||
hash_final_x4(&ctx);
|
||||
uint8_t* gs[4] = {prf_round[0].gs[vidx], prf_round[1].gs[vidx], prf_round[2].gs[vidx],
|
||||
prf_round[3].gs[vidx]};
|
||||
@ -764,16 +730,14 @@ static void unruh_G_x4(const picnic_instance_t* pp, proof_round_t* prf_round, un
|
||||
*/
|
||||
static void unruh_G_x4_verify(const picnic_instance_t* pp, const sorting_helper_t* helper,
|
||||
unsigned int vidx, bool include_is) {
|
||||
hash_context_x4 ctx;
|
||||
|
||||
const size_t outputlen =
|
||||
include_is ? pp->unruh_with_input_bytes_size : pp->unruh_without_input_bytes_size;
|
||||
const uint16_t size_le = htole16(outputlen);
|
||||
const size_t digest_size = pp->digest_size;
|
||||
const size_t seedlen = pp->seed_size;
|
||||
|
||||
// Hash the seed with H_5, store digest in output
|
||||
hash_init_prefix_x4(&ctx, pp, HASH_PREFIX_5);
|
||||
hash_context_x4 ctx;
|
||||
hash_init_prefix_x4(&ctx, digest_size, HASH_PREFIX_5);
|
||||
const uint8_t* seeds[4] = {helper[0].round->seeds[vidx], helper[1].round->seeds[vidx],
|
||||
helper[2].round->seeds[vidx], helper[3].round->seeds[vidx]};
|
||||
hash_update_x4(&ctx, seeds, seedlen);
|
||||
@ -785,7 +749,7 @@ static void unruh_G_x4_verify(const picnic_instance_t* pp, const sorting_helper_
|
||||
hash_squeeze_x4(&ctx, tmpptr, digest_size);
|
||||
|
||||
// Hash H_5(seed), the view, and the length
|
||||
hash_init_x4(&ctx, pp);
|
||||
hash_init_x4(&ctx, digest_size);
|
||||
hash_update_x4(&ctx, tmpptr_const, digest_size);
|
||||
if (include_is) {
|
||||
const uint8_t* input_shares[4] = {
|
||||
@ -800,9 +764,7 @@ static void unruh_G_x4_verify(const picnic_instance_t* pp, const sorting_helper_
|
||||
helper[3].round->communicated_bits[vidx],
|
||||
};
|
||||
hash_update_x4(&ctx, communicated_bits, pp->view_size);
|
||||
const uint8_t* sizes[4] = {(const uint8_t*)&size_le, (const uint8_t*)&size_le,
|
||||
(const uint8_t*)&size_le, (const uint8_t*)&size_le};
|
||||
hash_update_x4(&ctx, sizes, sizeof(uint16_t));
|
||||
hash_update_x4_uint16_le(&ctx, outputlen);
|
||||
hash_final_x4(&ctx);
|
||||
uint8_t* gs[4] = {helper[0].round->gs[vidx], helper[1].round->gs[vidx], helper[2].round->gs[vidx],
|
||||
helper[3].round->gs[vidx]};
|
||||
@ -982,17 +944,16 @@ static void generate_seeds(const picnic_instance_t* pp, const uint8_t* private_k
|
||||
const size_t lowmc_n = lowmc->n;
|
||||
|
||||
kdf_shake_t ctx;
|
||||
kdf_shake_init(&ctx, pp);
|
||||
kdf_shake_init(&ctx, pp->digest_size);
|
||||
// sk || m || C || p
|
||||
kdf_shake_update_key(&ctx, private_key, input_size);
|
||||
kdf_shake_update_key(&ctx, m, m_len);
|
||||
kdf_shake_update_key(&ctx, public_key, output_size);
|
||||
kdf_shake_update_key(&ctx, plaintext, output_size);
|
||||
// N as 16 bit LE integer
|
||||
const uint16_t size_le = htole16(lowmc_n);
|
||||
kdf_shake_update_key(&ctx, (const uint8_t*)&size_le, sizeof(size_le));
|
||||
kdf_shake_update_key_uint16_le(&ctx, lowmc_n);
|
||||
#if defined(WITH_EXTRA_RANDOMNESS)
|
||||
// Add extra randomn bytes for fault attack mitigation
|
||||
// Add extra random bytes for fault attack mitigation
|
||||
unsigned char buffer[2 * MAX_DIGEST_SIZE];
|
||||
OQS_randombytes(buffer, 2 * seed_size);
|
||||
kdf_shake_update_key(&ctx, buffer, 2 * seed_size);
|
||||
@ -1036,17 +997,14 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key,
|
||||
in_out_shares_t in_out_shares[2];
|
||||
mzd_local_init_multiple_ex(in_out_shares[0].s, SC_PROOF, 1, lowmc_k, false);
|
||||
mzd_local_init_multiple_ex(in_out_shares[1].s, SC_PROOF, 1, lowmc_n, false);
|
||||
mpc_lowmc_key_t const* shared_key = &in_out_shares->s[0];
|
||||
|
||||
// Generate seeds
|
||||
generate_seeds(pp, private_key, plaintext, public_key, m, m_len, prf->round[0].seeds[0],
|
||||
prf->salt);
|
||||
|
||||
mzd_local_t* shared_key[SC_PROOF];
|
||||
mzd_local_init_multiple(shared_key, SC_PROOF, 1, lowmc_k);
|
||||
|
||||
rvec_t* rvec = calloc(sizeof(rvec_t), lowmc_r); // random tapes for AND-gates
|
||||
|
||||
uint8_t* tape_bytes = malloc(view_size);
|
||||
proof_round_t* round = prf->round;
|
||||
// use 4 parallel instances of keccak for speedup
|
||||
uint8_t* tape_bytes_x4[SC_PROOF][4];
|
||||
@ -1091,7 +1049,7 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key,
|
||||
}
|
||||
|
||||
// perform ZKB++ LowMC evaluation
|
||||
lowmc_impl(shared_key, p, views, in_out_shares, rvec, &recorded_state);
|
||||
lowmc_impl(p, views, in_out_shares, rvec, &recorded_state);
|
||||
|
||||
for (unsigned int j = 0; j < SC_PROOF; ++j) {
|
||||
mzd_to_char_array(round[round_offset].output_shares[j], in_out_shares[1].s[j], output_size);
|
||||
@ -1128,6 +1086,7 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key,
|
||||
|
||||
// compute random tapes
|
||||
for (unsigned int j = 0; j < SC_PROOF; ++j) {
|
||||
uint8_t tape_bytes[MAX_VIEW_SIZE];
|
||||
kdf_shake_get_randomness(&kdfs[j], tape_bytes, view_size);
|
||||
decompress_random_tape(rvec, pp, tape_bytes, j);
|
||||
}
|
||||
@ -1137,7 +1096,7 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key,
|
||||
}
|
||||
|
||||
// perform ZKB++ LowMC evaluation
|
||||
lowmc_impl(shared_key, p, views, in_out_shares, rvec, &recorded_state);
|
||||
lowmc_impl(p, views, in_out_shares, rvec, &recorded_state);
|
||||
|
||||
// commitments
|
||||
for (unsigned int j = 0; j < SC_PROOF; ++j) {
|
||||
@ -1163,10 +1122,8 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key,
|
||||
free(tape_bytes_x4[k][j]);
|
||||
}
|
||||
}
|
||||
free(tape_bytes);
|
||||
free(rvec);
|
||||
free(views);
|
||||
mzd_local_free_multiple(shared_key);
|
||||
mzd_local_free_multiple(in_out_shares[1].s);
|
||||
mzd_local_free_multiple(in_out_shares[0].s);
|
||||
proof_free(prf);
|
||||
@ -1204,7 +1161,6 @@ static int verify_impl(const picnic_instance_t* pp, const uint8_t* plaintext, mz
|
||||
mzd_local_init_multiple_ex(in_out_shares[1].s, SC_PROOF, 1, lowmc_n, false);
|
||||
view_t* views = calloc(sizeof(view_t), view_count);
|
||||
rvec_t* rvec = calloc(sizeof(rvec_t), lowmc_r); // random tapes for and-gates
|
||||
uint8_t* tape_bytes = malloc(view_size);
|
||||
|
||||
// sort the different challenge rounds based on their H3 index, so we can use the 4x Keccak when
|
||||
// verifying since all of this is public information, there is no leakage
|
||||
@ -1321,6 +1277,7 @@ static int verify_impl(const picnic_instance_t* pp, const uint8_t* plaintext, mz
|
||||
|
||||
// compute random tapes
|
||||
for (unsigned int j = 0; j < SC_VERIFY; ++j) {
|
||||
uint8_t tape_bytes[MAX_VIEW_SIZE];
|
||||
kdf_shake_get_randomness(&kdfs[j], tape_bytes, view_size);
|
||||
decompress_random_tape(rvec, pp, tape_bytes, j);
|
||||
}
|
||||
@ -1362,7 +1319,6 @@ static int verify_impl(const picnic_instance_t* pp, const uint8_t* plaintext, mz
|
||||
free(tape_bytes_x4[i][j]);
|
||||
}
|
||||
}
|
||||
free(tape_bytes);
|
||||
free(rvec);
|
||||
free(views);
|
||||
mzd_local_free_multiple(in_out_shares[1].s);
|
||||
@ -1376,8 +1332,8 @@ static int verify_impl(const picnic_instance_t* pp, const uint8_t* plaintext, mz
|
||||
int impl_sign(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8_t* private_key,
|
||||
const uint8_t* public_key, const uint8_t* msg, size_t msglen, uint8_t* sig,
|
||||
size_t* siglen) {
|
||||
mzd_local_t* m_plaintext = mzd_local_init_ex(1, pp->lowmc->n, false);
|
||||
mzd_local_t* m_privatekey = mzd_local_init_ex(1, pp->lowmc->k, false);
|
||||
mzd_local_t m_plaintext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256];
|
||||
mzd_local_t m_privatekey[(MAX_LOWMC_KEY_SIZE_BITS + 255) / 256];
|
||||
|
||||
mzd_from_char_array(m_plaintext, plaintext, pp->output_size);
|
||||
mzd_from_char_array(m_privatekey, private_key, pp->input_size);
|
||||
@ -1385,16 +1341,13 @@ int impl_sign(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8
|
||||
const int result = sign_impl(pp, private_key, m_privatekey, plaintext, m_plaintext, public_key,
|
||||
msg, msglen, sig, siglen);
|
||||
|
||||
mzd_local_free(m_privatekey);
|
||||
mzd_local_free(m_plaintext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int impl_verify(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8_t* public_key,
|
||||
const uint8_t* msg, size_t msglen, const uint8_t* sig, size_t siglen) {
|
||||
mzd_local_t* m_plaintext = mzd_local_init_ex(1, pp->lowmc->n, false);
|
||||
mzd_local_t* m_publickey = mzd_local_init_ex(1, pp->lowmc->n, false);
|
||||
mzd_local_t m_plaintext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256];
|
||||
mzd_local_t m_publickey[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256];
|
||||
|
||||
mzd_from_char_array(m_plaintext, plaintext, pp->output_size);
|
||||
mzd_from_char_array(m_publickey, public_key, pp->output_size);
|
||||
@ -1402,130 +1355,7 @@ int impl_verify(const picnic_instance_t* pp, const uint8_t* plaintext, const uin
|
||||
const int result =
|
||||
verify_impl(pp, plaintext, m_plaintext, public_key, m_publickey, msg, msglen, sig, siglen);
|
||||
|
||||
mzd_local_free(m_publickey);
|
||||
mzd_local_free(m_plaintext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* cropped unused visualize_signature */
|
||||
|
||||
// instance handling
|
||||
|
||||
// L1, L3, and L5 LowMC instances
|
||||
#if defined(WITH_LOWMC_128_128_20)
|
||||
#include "lowmc_128_128_20.h"
|
||||
#define LOWMC_L1_OR_NULL &lowmc_128_128_20
|
||||
#else
|
||||
#define LOWMC_L1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_192_192_30)
|
||||
#include "lowmc_192_192_30.h"
|
||||
#define LOWMC_L3_OR_NULL &lowmc_192_192_30
|
||||
#else
|
||||
#define LOWMC_L3_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_256_256_38)
|
||||
#include "lowmc_256_256_38.h"
|
||||
#define LOWMC_L5_OR_NULL &lowmc_256_256_38
|
||||
#else
|
||||
#define LOWMC_L5_OR_NULL NULL
|
||||
#endif
|
||||
|
||||
// L1, L3, and L5 lowmc instances with 1 SBOX
|
||||
#if defined(WITH_LOWMC_128_128_182)
|
||||
#include "lowmc_128_128_182.h"
|
||||
#define LOWMC_L1_1_OR_NULL &lowmc_128_128_182
|
||||
#else
|
||||
#define LOWMC_L1_1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_192_192_284)
|
||||
#include "lowmc_192_192_284.h"
|
||||
#define LOWMC_L3_1_OR_NULL &lowmc_192_192_284
|
||||
#else
|
||||
#define LOWMC_L3_1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_256_256_363)
|
||||
#include "lowmc_256_256_363.h"
|
||||
#define LOWMC_L5_1_OR_NULL &lowmc_256_256_363
|
||||
#else
|
||||
#define LOWMC_L5_1_OR_NULL NULL
|
||||
#endif
|
||||
|
||||
#define NULL_FNS \
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
|
||||
static picnic_instance_t instances[PARAMETER_SET_MAX_INDEX] = {
|
||||
{NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PARAMETER_SET_INVALID, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L1_OR_NULL, 32, 16, 219, 219, 3, 16, 16, 75, 30, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_FS, Picnic_L1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L1_OR_NULL, 32, 16, 219, 219, 3, 16, 16, 75, 30, 55, 91, 107,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_UR, Picnic_L1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{LOWMC_L3_OR_NULL, 48, 24, 329, 329, 3, 24, 24, 113, 30, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_FS, Picnic_L3_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L3_OR_NULL, 48, 24, 329, 329, 3, 24, 24, 113, 30, 83, 137, 161,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_UR, Picnic_L3_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{LOWMC_L5_OR_NULL, 64, 32, 438, 438, 3, 32, 32, 143, 30, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_FS, Picnic_L5_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L5_OR_NULL, 64, 32, 438, 438, 3, 32, 32, 143, 30, 110, 175, 207,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_UR, Picnic_L5_UR, TRANSFORM_UR, NULL_FNS},
|
||||
// Picnic2 params
|
||||
{LOWMC_L1_OR_NULL, 32, 16, 343, 27, 64, 16, 16, 75, 30, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L1_FS, Picnic2_L1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L3_OR_NULL, 48, 24, 570, 39, 64, 24, 24, 113, 30, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L3_FS, Picnic2_L3_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L5_OR_NULL, 64, 32, 803, 50, 64, 32, 32, 143, 30, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L5_FS, Picnic2_L5_FS, TRANSFORM_FS, NULL_FNS},
|
||||
// Picnic with LowMC with m=1
|
||||
{LOWMC_L1_1_OR_NULL, 32, 16, 219, 219, 3, 16, 16, 69, 3, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_1_FS, Picnic_L1_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L1_1_OR_NULL, 32, 16, 219, 219, 3, 16, 16, 69, 3, 55, 87, 103,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_1_UR, Picnic_L1_1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{LOWMC_L3_1_OR_NULL, 48, 24, 329, 329, 3, 24, 24, 107, 3, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_1_FS, Picnic_L3_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L3_1_OR_NULL, 48, 24, 329, 329, 3, 24, 24, 107, 3, 83, 131, 155,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_1_UR, Picnic_L3_1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{LOWMC_L5_1_OR_NULL, 64, 32, 438, 438, 3, 32, 32, 137, 3, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_1_FS, Picnic_L5_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{LOWMC_L5_1_OR_NULL, 64, 32, 438, 438, 3, 32, 32, 137, 3, 110, 169, 201,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_1_UR, Picnic_L5_1_UR, TRANSFORM_UR, NULL_FNS}};
|
||||
static bool instance_initialized[PARAMETER_SET_MAX_INDEX];
|
||||
|
||||
static bool create_instance(picnic_instance_t* pp) {
|
||||
if (!pp->lowmc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pp->impls.lowmc = lowmc_get_implementation(pp->lowmc);
|
||||
pp->impls.lowmc_store = lowmc_store_get_implementation(pp->lowmc);
|
||||
pp->impls.zkbpp_lowmc = get_zkbpp_lowmc_implementation(pp->lowmc);
|
||||
pp->impls.zkbpp_lowmc_verify = get_zkbpp_lowmc_verify_implementation(pp->lowmc);
|
||||
pp->impls.mzd_share = get_zkbpp_share_implentation(pp->lowmc);
|
||||
pp->impls.lowmc_aux = lowmc_compute_aux_get_implementation(pp->lowmc);
|
||||
pp->impls.lowmc_simulate_online = lowmc_simulate_online_get_implementation(pp->lowmc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const picnic_instance_t* picnic_instance_get(picnic_params_t param) {
|
||||
if (param <= PARAMETER_SET_INVALID || param >= PARAMETER_SET_MAX_INDEX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!instance_initialized[param]) {
|
||||
if (!create_instance(&instances[param])) {
|
||||
return NULL;
|
||||
}
|
||||
instance_initialized[param] = true;
|
||||
}
|
||||
|
||||
return &instances[param];
|
||||
}
|
||||
|
||||
ATTR_DTOR static void clear_instances(void) {
|
||||
for (unsigned int p = PARAMETER_SET_INVALID + 1; p < PARAMETER_SET_MAX_INDEX; ++p) {
|
||||
if (instance_initialized[p]) {
|
||||
instance_initialized[p] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* OQS note: cropped unused visualization functions */
|
||||
|
||||
74
src/sig/picnic/external/picnic_impl.h
vendored
74
src/sig/picnic/external/picnic_impl.h
vendored
@ -11,51 +11,9 @@
|
||||
#define PICNIC_IMPL_H
|
||||
|
||||
#include "lowmc.h"
|
||||
#include "mpc_lowmc.h"
|
||||
#include "picnic2_simulate.h"
|
||||
#include "picnic_instances.h"
|
||||
#include "picnic.h"
|
||||
|
||||
#define MAX_DIGEST_SIZE 64
|
||||
#define MAX_NUM_ROUNDS 438
|
||||
#define MAX_LOWMC_BLOCK_SIZE_BITS (MAX_LOWMC_BLOCK_SIZE * 8)
|
||||
|
||||
typedef enum { TRANSFORM_FS, TRANSFORM_UR } transform_t;
|
||||
|
||||
typedef struct picnic_instance_t {
|
||||
const lowmc_t* lowmc;
|
||||
|
||||
uint32_t digest_size; /* bytes */
|
||||
uint32_t seed_size; /* bytes */
|
||||
uint32_t num_rounds; // T
|
||||
uint32_t num_opened_rounds; // u
|
||||
uint32_t num_MPC_parties; // N
|
||||
|
||||
uint32_t input_size; /* bytes */
|
||||
uint32_t output_size; /* bytes */
|
||||
uint32_t view_size; /* bytes */
|
||||
uint32_t view_round_size; /* bits */
|
||||
|
||||
uint32_t collapsed_challenge_size; /* bytes */
|
||||
uint32_t unruh_without_input_bytes_size; /* bytes */
|
||||
uint32_t unruh_with_input_bytes_size; /* bytes */
|
||||
uint32_t max_signature_size; /* bytes */
|
||||
|
||||
picnic_params_t params;
|
||||
transform_t transform;
|
||||
|
||||
struct {
|
||||
lowmc_implementation_f lowmc;
|
||||
lowmc_store_implementation_f lowmc_store;
|
||||
zkbpp_lowmc_implementation_f zkbpp_lowmc;
|
||||
zkbpp_lowmc_verify_implementation_f zkbpp_lowmc_verify;
|
||||
zkbpp_share_implementation_f mzd_share;
|
||||
lowmc_compute_aux_implementation_f lowmc_aux;
|
||||
lowmc_simulate_online_f lowmc_simulate_online;
|
||||
} impls;
|
||||
} picnic_instance_t;
|
||||
|
||||
const picnic_instance_t* picnic_instance_get(picnic_params_t param);
|
||||
|
||||
int impl_sign(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8_t* private_key,
|
||||
const uint8_t* public_key, const uint8_t* msg, size_t msglen, uint8_t* sig,
|
||||
size_t* siglen);
|
||||
@ -63,34 +21,6 @@ int impl_sign(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8
|
||||
int impl_verify(const picnic_instance_t* pp, const uint8_t* plaintext, const uint8_t* public_key,
|
||||
const uint8_t* msg, size_t msglen, const uint8_t* sig, size_t siglen);
|
||||
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_lowmc_block_size(picnic_params_t param);
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_private_key_size(picnic_params_t param);
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_public_key_size(picnic_params_t param);
|
||||
/**
|
||||
* Compute public key from secret key.
|
||||
*
|
||||
* @param[in] sk The secret key
|
||||
* @param[out] pk The public key to be populated
|
||||
* @return Returns 0 on success, or a nonzero value indicating an error.
|
||||
**/
|
||||
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_sk_to_pk(const picnic_privatekey_t* sk,
|
||||
picnic_publickey_t* pk);
|
||||
|
||||
// Prefix values for domain separation
|
||||
extern const uint8_t HASH_PREFIX_0; // = 0
|
||||
extern const uint8_t HASH_PREFIX_1; // = 1
|
||||
extern const uint8_t HASH_PREFIX_2; // = 2
|
||||
extern const uint8_t HASH_PREFIX_3; // = 3
|
||||
extern const uint8_t HASH_PREFIX_4; // = 4
|
||||
extern const uint8_t HASH_PREFIX_5; // = 5
|
||||
|
||||
#if defined(PICNIC_STATIC)
|
||||
void visualize_signature(FILE* out, const picnic_instance_t* pp, const uint8_t* msg, size_t msglen,
|
||||
const uint8_t* sig, size_t siglen);
|
||||
void picnic_visualize_keys(FILE* out, const picnic_privatekey_t* private_key,
|
||||
const picnic_publickey_t* public_key);
|
||||
void picnic_visualize(FILE* out, const picnic_publickey_t* public_key, const uint8_t* msg,
|
||||
size_t msglen, const uint8_t* sig, size_t siglen);
|
||||
#endif
|
||||
/* OQS note: cropped unused visualization functions */
|
||||
|
||||
#endif
|
||||
|
||||
158
src/sig/picnic/external/picnic_instances.c
vendored
Normal file
158
src/sig/picnic/external/picnic_instances.c
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* This file is part of the optimized 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
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "picnic_instances.h"
|
||||
|
||||
// Prefix values for domain separation
|
||||
const uint8_t HASH_PREFIX_0 = 0;
|
||||
const uint8_t HASH_PREFIX_1 = 1;
|
||||
const uint8_t HASH_PREFIX_2 = 2;
|
||||
const uint8_t HASH_PREFIX_3 = 3;
|
||||
const uint8_t HASH_PREFIX_4 = 4;
|
||||
const uint8_t HASH_PREFIX_5 = 5;
|
||||
|
||||
// instance handling
|
||||
|
||||
// L1, L3, and L5 LowMC instances
|
||||
#if defined(WITH_LOWMC_128_128_20)
|
||||
#include "lowmc_128_128_20.h"
|
||||
#define LOWMC_L1_OR_NULL &lowmc_128_128_20
|
||||
#else
|
||||
#define LOWMC_L1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_192_192_30)
|
||||
#include "lowmc_192_192_30.h"
|
||||
#define LOWMC_L3_OR_NULL &lowmc_192_192_30
|
||||
#else
|
||||
#define LOWMC_L3_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_256_256_38)
|
||||
#include "lowmc_256_256_38.h"
|
||||
#define LOWMC_L5_OR_NULL &lowmc_256_256_38
|
||||
#else
|
||||
#define LOWMC_L5_OR_NULL NULL
|
||||
#endif
|
||||
|
||||
// L1, L3, and L5 lowmc instances with 1 SBOX
|
||||
#if defined(WITH_LOWMC_128_128_182)
|
||||
#include "lowmc_128_128_182.h"
|
||||
#define LOWMC_L1_1_OR_NULL &lowmc_128_128_182
|
||||
#else
|
||||
#define LOWMC_L1_1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_192_192_284)
|
||||
#include "lowmc_192_192_284.h"
|
||||
#define LOWMC_L3_1_OR_NULL &lowmc_192_192_284
|
||||
#else
|
||||
#define LOWMC_L3_1_OR_NULL NULL
|
||||
#endif
|
||||
#if defined(WITH_LOWMC_256_256_363)
|
||||
#include "lowmc_256_256_363.h"
|
||||
#define LOWMC_L5_1_OR_NULL &lowmc_256_256_363
|
||||
#else
|
||||
#define LOWMC_L5_1_OR_NULL NULL
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ZKBPP)
|
||||
#define ENABLE_ZKBPP(x) x
|
||||
#else
|
||||
#define ENABLE_ZKBPP(x) NULL
|
||||
#endif
|
||||
|
||||
#if defined(WITH_KKW)
|
||||
#define ENABLE_KKW(x) x
|
||||
#else
|
||||
#define ENABLE_KKW(x) NULL
|
||||
#endif
|
||||
|
||||
#if defined(WITH_ZKBPP) && defined(WITH_KKW)
|
||||
#define NULL_FNS \
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL }
|
||||
#elif defined(WITH_ZKBPP)
|
||||
#define NULL_FNS \
|
||||
{ NULL, NULL, NULL, NULL, NULL }
|
||||
#else
|
||||
#define NULL_FNS \
|
||||
{ NULL }
|
||||
#endif
|
||||
|
||||
static picnic_instance_t instances[PARAMETER_SET_MAX_INDEX] = {
|
||||
{NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PARAMETER_SET_INVALID, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L1_OR_NULL), 32, 16, 219, 219, 3, 16, 16, 75, 30, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_FS, Picnic_L1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L1_OR_NULL), 32, 16, 219, 219, 3, 16, 16, 75, 30, 55, 91, 107,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_UR, Picnic_L1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L3_OR_NULL), 48, 24, 329, 329, 3, 24, 24, 113, 30, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_FS, Picnic_L3_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L3_OR_NULL), 48, 24, 329, 329, 3, 24, 24, 113, 30, 83, 137, 161,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_UR, Picnic_L3_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L5_OR_NULL), 64, 32, 438, 438, 3, 32, 32, 143, 30, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_FS, Picnic_L5_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L5_OR_NULL), 64, 32, 438, 438, 3, 32, 32, 143, 30, 110, 175, 207,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_UR, Picnic_L5_UR, TRANSFORM_UR, NULL_FNS},
|
||||
// Picnic2 params
|
||||
{ENABLE_KKW(LOWMC_L1_OR_NULL), 32, 16, 343, 27, 64, 16, 16, 75, 30, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L1_FS, Picnic2_L1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_KKW(LOWMC_L3_OR_NULL), 48, 24, 570, 39, 64, 24, 24, 113, 30, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L3_FS, Picnic2_L3_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_KKW(LOWMC_L5_OR_NULL), 64, 32, 803, 50, 64, 32, 32, 143, 30, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic2_L5_FS, Picnic2_L5_FS, TRANSFORM_FS, NULL_FNS},
|
||||
// Picnic with LowMC with m=1
|
||||
{ENABLE_ZKBPP(LOWMC_L1_1_OR_NULL), 32, 16, 219, 219, 3, 16, 16, 69, 3, 55, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_1_FS, Picnic_L1_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L1_1_OR_NULL), 32, 16, 219, 219, 3, 16, 16, 69, 3, 55, 87, 103,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L1_1_UR, Picnic_L1_1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L3_1_OR_NULL), 48, 24, 329, 329, 3, 24, 24, 107, 3, 83, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_1_FS, Picnic_L3_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L3_1_OR_NULL), 48, 24, 329, 329, 3, 24, 24, 107, 3, 83, 131, 155,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L3_1_UR, Picnic_L3_1_UR, TRANSFORM_UR, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L5_1_OR_NULL), 64, 32, 438, 438, 3, 32, 32, 137, 3, 110, 0, 0,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_1_FS, Picnic_L5_1_FS, TRANSFORM_FS, NULL_FNS},
|
||||
{ENABLE_ZKBPP(LOWMC_L5_1_OR_NULL), 64, 32, 438, 438, 3, 32, 32, 137, 3, 110, 169, 201,
|
||||
PICNIC_SIGNATURE_SIZE_Picnic_L5_1_UR, Picnic_L5_1_UR, TRANSFORM_UR, NULL_FNS}};
|
||||
static bool instance_initialized[PARAMETER_SET_MAX_INDEX];
|
||||
|
||||
static bool create_instance(picnic_instance_t* pp) {
|
||||
if (!pp->lowmc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pp->impls.lowmc = lowmc_get_implementation(pp->lowmc);
|
||||
#if defined(WITH_ZKBPP)
|
||||
pp->impls.lowmc_store = lowmc_store_get_implementation(pp->lowmc);
|
||||
pp->impls.zkbpp_lowmc = get_zkbpp_lowmc_implementation(pp->lowmc);
|
||||
pp->impls.zkbpp_lowmc_verify = get_zkbpp_lowmc_verify_implementation(pp->lowmc);
|
||||
pp->impls.mzd_share = get_zkbpp_share_implentation(pp->lowmc);
|
||||
#endif
|
||||
#if defined(WITH_KKW)
|
||||
pp->impls.lowmc_aux = lowmc_compute_aux_get_implementation(pp->lowmc);
|
||||
pp->impls.lowmc_simulate_online = lowmc_simulate_online_get_implementation(pp->lowmc);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const picnic_instance_t* picnic_instance_get(picnic_params_t param) {
|
||||
if (param <= PARAMETER_SET_INVALID || param >= PARAMETER_SET_MAX_INDEX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!instance_initialized[param]) {
|
||||
if (!create_instance(&instances[param])) {
|
||||
return NULL;
|
||||
}
|
||||
instance_initialized[param] = true;
|
||||
}
|
||||
|
||||
return &instances[param];
|
||||
}
|
||||
91
src/sig/picnic/external/picnic_instances.h
vendored
Normal file
91
src/sig/picnic/external/picnic_instances.h
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* This file is part of the optimized 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
|
||||
*/
|
||||
|
||||
#ifndef PICNIC_INSTANCES_H
|
||||
#define PICNIC_INSTANCES_H
|
||||
|
||||
#include "lowmc.h"
|
||||
#if defined(WITH_ZKBPP)
|
||||
#include "mpc_lowmc.h"
|
||||
#endif
|
||||
#if defined(WITH_KKW)
|
||||
#include "picnic2_simulate.h"
|
||||
#endif
|
||||
#include "picnic.h"
|
||||
|
||||
#define SALT_SIZE 32
|
||||
#define MAX_LOWMC_ROUNDS 38
|
||||
#define MAX_LOWMC_SBOXES 10
|
||||
#define MAX_DIGEST_SIZE 64
|
||||
#define MAX_NUM_ROUNDS 438
|
||||
#define MAX_VIEW_SIZE 143
|
||||
|
||||
typedef enum { TRANSFORM_FS, TRANSFORM_UR } transform_t;
|
||||
|
||||
typedef struct picnic_instance_t {
|
||||
const lowmc_t* lowmc;
|
||||
|
||||
uint32_t digest_size; /* bytes */
|
||||
uint32_t seed_size; /* bytes */
|
||||
uint32_t num_rounds; // T
|
||||
uint32_t num_opened_rounds; // u
|
||||
uint32_t num_MPC_parties; // N
|
||||
|
||||
uint32_t input_size; /* bytes */
|
||||
uint32_t output_size; /* bytes */
|
||||
uint32_t view_size; /* bytes */
|
||||
uint32_t view_round_size; /* bits */
|
||||
|
||||
uint32_t collapsed_challenge_size; /* bytes */
|
||||
uint32_t unruh_without_input_bytes_size; /* bytes */
|
||||
uint32_t unruh_with_input_bytes_size; /* bytes */
|
||||
uint32_t max_signature_size; /* bytes */
|
||||
|
||||
picnic_params_t params;
|
||||
transform_t transform;
|
||||
|
||||
struct {
|
||||
lowmc_implementation_f lowmc;
|
||||
#if defined(WITH_ZKBPP)
|
||||
lowmc_store_implementation_f lowmc_store;
|
||||
zkbpp_lowmc_implementation_f zkbpp_lowmc;
|
||||
zkbpp_lowmc_verify_implementation_f zkbpp_lowmc_verify;
|
||||
zkbpp_share_implementation_f mzd_share;
|
||||
#endif
|
||||
#if defined(WITH_KKW)
|
||||
lowmc_compute_aux_implementation_f lowmc_aux;
|
||||
lowmc_simulate_online_f lowmc_simulate_online;
|
||||
#endif
|
||||
} impls;
|
||||
} picnic_instance_t;
|
||||
|
||||
const picnic_instance_t* picnic_instance_get(picnic_params_t param);
|
||||
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_lowmc_block_size(picnic_params_t param);
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_private_key_size(picnic_params_t param);
|
||||
PICNIC_EXPORT size_t PICNIC_CALLING_CONVENTION picnic_get_public_key_size(picnic_params_t param);
|
||||
/**
|
||||
* Compute public key from secret key.
|
||||
*
|
||||
* @param[in] sk The secret key
|
||||
* @param[out] pk The public key to be populated
|
||||
* @return Returns 0 on success, or a nonzero value indicating an error.
|
||||
**/
|
||||
PICNIC_EXPORT int PICNIC_CALLING_CONVENTION picnic_sk_to_pk(const picnic_privatekey_t* sk,
|
||||
picnic_publickey_t* pk);
|
||||
|
||||
// Prefix values for domain separation
|
||||
extern const uint8_t HASH_PREFIX_0; // = 0
|
||||
extern const uint8_t HASH_PREFIX_1; // = 1
|
||||
extern const uint8_t HASH_PREFIX_2; // = 2
|
||||
extern const uint8_t HASH_PREFIX_3; // = 3
|
||||
extern const uint8_t HASH_PREFIX_4; // = 4
|
||||
extern const uint8_t HASH_PREFIX_5; // = 5
|
||||
|
||||
#endif
|
||||
@ -34,21 +34,3 @@ http://creativecommons.org/publicdomain/zero/1.0/
|
||||
#undef SnP_Permute
|
||||
#undef SnP_FastLoop_Absorb
|
||||
#endif
|
||||
|
||||
#ifndef KeccakP1600_excluded
|
||||
#include "KeccakP-1600-SnP.h"
|
||||
|
||||
#define prefix KeccakWidth1600_12rounds
|
||||
#define SnP KeccakP1600
|
||||
#define SnP_width 1600
|
||||
#define SnP_Permute KeccakP1600_Permute_12rounds
|
||||
#if defined(KeccakP1600_12rounds_FastLoop_supported)
|
||||
#define SnP_FastLoop_Absorb KeccakP1600_12rounds_FastLoop_Absorb
|
||||
#endif
|
||||
#include "KeccakSponge.inc"
|
||||
#undef prefix
|
||||
#undef SnP
|
||||
#undef SnP_width
|
||||
#undef SnP_Permute
|
||||
#undef SnP_FastLoop_Absorb
|
||||
#endif
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
# void KeccakP1600_Initialize(void *state);
|
||||
#
|
||||
.globl KeccakP1600_Initialize
|
||||
.hidden KeccakP1600_Initialize
|
||||
.type KeccakP1600_Initialize,@function
|
||||
.align 32
|
||||
KeccakP1600_Initialize:
|
||||
@ -38,6 +39,7 @@ KeccakP1600_Initialize:
|
||||
# %rdi %rsi %rdx
|
||||
#
|
||||
.globl KeccakP1600_AddByte
|
||||
.hidden KeccakP1600_AddByte
|
||||
.type KeccakP1600_AddByte,@function
|
||||
.align 32
|
||||
KeccakP1600_AddByte:
|
||||
@ -58,6 +60,7 @@ KeccakP1600_AddByte:
|
||||
# %rdi %rsi %rdx %rcx
|
||||
#
|
||||
.globl KeccakP1600_AddBytes
|
||||
.hidden KeccakP1600_AddBytes
|
||||
.type KeccakP1600_AddBytes,@function
|
||||
.align 32
|
||||
KeccakP1600_AddBytes:
|
||||
@ -117,6 +120,7 @@ KeccakP1600_AddBytes_Exit:
|
||||
# %rdi %rsi %rdx %rcx
|
||||
#
|
||||
.globl KeccakP1600_OverwriteBytes
|
||||
.hidden KeccakP1600_OverwriteBytes
|
||||
.type KeccakP1600_OverwriteBytes,@function
|
||||
.align 32
|
||||
KeccakP1600_OverwriteBytes:
|
||||
@ -176,6 +180,7 @@ KeccakP1600_OverwriteBytes_Exit:
|
||||
# %rdi %rsi
|
||||
#
|
||||
.globl KeccakP1600_OverwriteWithZeroes
|
||||
.hidden KeccakP1600_OverwriteWithZeroes
|
||||
.type KeccakP1600_OverwriteWithZeroes,@function
|
||||
.align 32
|
||||
KeccakP1600_OverwriteWithZeroes:
|
||||
@ -211,6 +216,7 @@ KeccakP1600_OverwriteWithZeroes_Exit:
|
||||
# %rdi %rsi %rdx %rcx
|
||||
#
|
||||
.globl KeccakP1600_ExtractBytes
|
||||
.hidden KeccakP1600_ExtractBytes
|
||||
.type KeccakP1600_ExtractBytes,@function
|
||||
.align 32
|
||||
KeccakP1600_ExtractBytes:
|
||||
@ -273,6 +279,7 @@ KeccakP1600_ExtractBytes_Exit:
|
||||
# %rdi %rsi %rdx %rcx %r8
|
||||
#
|
||||
.globl KeccakP1600_ExtractAndAddBytes
|
||||
.hidden KeccakP1600_ExtractAndAddBytes
|
||||
.type KeccakP1600_ExtractAndAddBytes,@function
|
||||
.align 32
|
||||
KeccakP1600_ExtractAndAddBytes:
|
||||
@ -486,6 +493,7 @@ __KeccakF1600:
|
||||
|
||||
|
||||
.globl KeccakP1600_Permute_24rounds
|
||||
.hidden KeccakP1600_Permute_24rounds
|
||||
.type KeccakP1600_Permute_24rounds,@function
|
||||
.align 32
|
||||
KeccakP1600_Permute_24rounds:
|
||||
@ -514,36 +522,8 @@ KeccakP1600_Permute_24rounds:
|
||||
ret
|
||||
.size KeccakP1600_Permute_24rounds,.-KeccakP1600_Permute_24rounds
|
||||
|
||||
.globl KeccakP1600_Permute_12rounds
|
||||
.type KeccakP1600_Permute_12rounds,@function
|
||||
.align 32
|
||||
KeccakP1600_Permute_12rounds:
|
||||
lea rhotates_left+96(%rip),%r8
|
||||
lea rhotates_right+96(%rip),%r9
|
||||
lea iotas+12*4*8(%rip),%r10
|
||||
mov $12,%eax
|
||||
lea 96(%rdi),%rdi
|
||||
vzeroupper
|
||||
vpbroadcastq -96(%rdi),%ymm0 # load A[5][5]
|
||||
vmovdqu 8+32*0-96(%rdi),%ymm1
|
||||
vmovdqu 8+32*1-96(%rdi),%ymm2
|
||||
vmovdqu 8+32*2-96(%rdi),%ymm3
|
||||
vmovdqu 8+32*3-96(%rdi),%ymm4
|
||||
vmovdqu 8+32*4-96(%rdi),%ymm5
|
||||
vmovdqu 8+32*5-96(%rdi),%ymm6
|
||||
call __KeccakF1600
|
||||
vmovq %xmm0,-96(%rdi)
|
||||
vmovdqu %ymm1,8+32*0-96(%rdi)
|
||||
vmovdqu %ymm2,8+32*1-96(%rdi)
|
||||
vmovdqu %ymm3,8+32*2-96(%rdi)
|
||||
vmovdqu %ymm4,8+32*3-96(%rdi)
|
||||
vmovdqu %ymm5,8+32*4-96(%rdi)
|
||||
vmovdqu %ymm6,8+32*5-96(%rdi)
|
||||
vzeroupper
|
||||
ret
|
||||
.size KeccakP1600_Permute_12rounds,.-KeccakP1600_Permute_12rounds
|
||||
|
||||
.globl KeccakP1600_Permute_Nrounds
|
||||
.hidden KeccakP1600_Permute_Nrounds
|
||||
.type KeccakP1600_Permute_Nrounds,@function
|
||||
.align 32
|
||||
KeccakP1600_Permute_Nrounds:
|
||||
@ -580,6 +560,7 @@ KeccakP1600_Permute_Nrounds:
|
||||
# %rdi %rsi %rdx %rcx
|
||||
#
|
||||
.globl KeccakF1600_FastLoop_Absorb
|
||||
.hidden KeccakF1600_FastLoop_Absorb
|
||||
.type KeccakF1600_FastLoop_Absorb,@function
|
||||
.align 32
|
||||
KeccakF1600_FastLoop_Absorb:
|
||||
@ -743,175 +724,6 @@ KeccakF1600_FastLoop_Absorb_LanesAddLoop:
|
||||
jmp KeccakF1600_FastLoop_Absorb_Exit
|
||||
.size KeccakF1600_FastLoop_Absorb,.-KeccakF1600_FastLoop_Absorb
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
#
|
||||
# size_t KeccakP1600_12rounds_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen);
|
||||
# %rdi %rsi %rdx %rcx
|
||||
#
|
||||
.globl KeccakP1600_12rounds_FastLoop_Absorb
|
||||
.type KeccakP1600_12rounds_FastLoop_Absorb,@function
|
||||
.align 32
|
||||
KeccakP1600_12rounds_FastLoop_Absorb:
|
||||
push %rbx
|
||||
push %r10
|
||||
shr $3, %rcx # rcx = data length in lanes
|
||||
mov %rdx, %rbx # rbx = initial data pointer
|
||||
cmp %rsi, %rcx
|
||||
jb KeccakP1600_12rounds_FastLoop_Absorb_Exit
|
||||
vzeroupper
|
||||
cmp $21, %rsi
|
||||
jnz KeccakP1600_12rounds_FastLoop_Absorb_Not21Lanes
|
||||
sub $21, %rcx
|
||||
lea rhotates_left+96(%rip),%r8
|
||||
lea rhotates_right+96(%rip),%r9
|
||||
lea 96(%rdi),%rdi
|
||||
vpbroadcastq -96(%rdi),%ymm0 # load A[5][5]
|
||||
vmovdqu 8+32*0-96(%rdi),%ymm1
|
||||
vmovdqu 8+32*1-96(%rdi),%ymm2
|
||||
vmovdqu 8+32*2-96(%rdi),%ymm3
|
||||
vmovdqu 8+32*3-96(%rdi),%ymm4
|
||||
vmovdqu 8+32*4-96(%rdi),%ymm5
|
||||
vmovdqu 8+32*5-96(%rdi),%ymm6
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_Loop21Lanes:
|
||||
vpbroadcastq (%rdx),%ymm7
|
||||
vmovdqu 8(%rdx),%ymm8
|
||||
|
||||
vmovdqa map2(%rip), %xmm15
|
||||
vpcmpeqq %ymm14, %ymm14, %ymm14
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm9
|
||||
|
||||
vmovdqa mask3_21(%rip), %ymm14
|
||||
vpxor %ymm10, %ymm10, %ymm10
|
||||
vmovdqa map3(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm10
|
||||
|
||||
vmovdqa mask4_21(%rip), %ymm14
|
||||
vpxor %ymm11, %ymm11, %ymm11
|
||||
vmovdqa map4(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm11
|
||||
|
||||
vmovdqa mask5_21(%rip), %ymm14
|
||||
vpxor %ymm12, %ymm12, %ymm12
|
||||
vmovdqa map5(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm12
|
||||
|
||||
vmovdqa mask6_21(%rip), %ymm14
|
||||
vpxor %ymm13, %ymm13, %ymm13
|
||||
vmovdqa map6(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm13
|
||||
|
||||
vpxor %ymm7,%ymm0,%ymm0
|
||||
vpxor %ymm8,%ymm1,%ymm1
|
||||
vpxor %ymm9,%ymm2,%ymm2
|
||||
vpxor %ymm10,%ymm3,%ymm3
|
||||
vpxor %ymm11,%ymm4,%ymm4
|
||||
vpxor %ymm12,%ymm5,%ymm5
|
||||
vpxor %ymm13,%ymm6,%ymm6
|
||||
add $21*8, %rdx
|
||||
lea iotas+12*4*8(%rip),%r10
|
||||
mov $12,%eax
|
||||
call __KeccakF1600
|
||||
sub $21, %rcx
|
||||
jnc KeccakP1600_12rounds_FastLoop_Absorb_Loop21Lanes
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_SaveAndExit:
|
||||
vmovq %xmm0,-96(%rdi)
|
||||
vmovdqu %ymm1,8+32*0-96(%rdi)
|
||||
vmovdqu %ymm2,8+32*1-96(%rdi)
|
||||
vmovdqu %ymm3,8+32*2-96(%rdi)
|
||||
vmovdqu %ymm4,8+32*3-96(%rdi)
|
||||
vmovdqu %ymm5,8+32*4-96(%rdi)
|
||||
vmovdqu %ymm6,8+32*5-96(%rdi)
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_Exit:
|
||||
vzeroupper
|
||||
mov %rdx, %rax # return number of bytes processed
|
||||
sub %rbx, %rax
|
||||
pop %r10
|
||||
pop %rbx
|
||||
ret
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_Not21Lanes:
|
||||
cmp $17, %rsi
|
||||
jnz KeccakP1600_12rounds_FastLoop_Absorb_Not17Lanes
|
||||
sub $17, %rcx
|
||||
lea rhotates_left+96(%rip),%r8
|
||||
lea rhotates_right+96(%rip),%r9
|
||||
lea 96(%rdi),%rdi
|
||||
vpbroadcastq -96(%rdi),%ymm0 # load A[5][5]
|
||||
vmovdqu 8+32*0-96(%rdi),%ymm1
|
||||
vmovdqu 8+32*1-96(%rdi),%ymm2
|
||||
vmovdqu 8+32*2-96(%rdi),%ymm3
|
||||
vmovdqu 8+32*3-96(%rdi),%ymm4
|
||||
vmovdqu 8+32*4-96(%rdi),%ymm5
|
||||
vmovdqu 8+32*5-96(%rdi),%ymm6
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_Loop17Lanes:
|
||||
vpbroadcastq (%rdx),%ymm7
|
||||
vmovdqu 8(%rdx),%ymm8
|
||||
|
||||
vmovdqa mask2_17(%rip), %ymm14
|
||||
vpxor %ymm9, %ymm9, %ymm9
|
||||
vmovdqa map2(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm9
|
||||
|
||||
vmovdqa mask3_17(%rip), %ymm14
|
||||
vpxor %ymm10, %ymm10, %ymm10
|
||||
vmovdqa map3(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm10
|
||||
|
||||
vmovdqa mask4_17(%rip), %ymm14
|
||||
vpxor %ymm11, %ymm11, %ymm11
|
||||
vmovdqa map4(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm11
|
||||
|
||||
vmovdqa mask5_17(%rip), %ymm14
|
||||
vpxor %ymm12, %ymm12, %ymm12
|
||||
vmovdqa map5(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm12
|
||||
|
||||
vmovdqa mask6_17(%rip), %ymm14
|
||||
vpxor %ymm13, %ymm13, %ymm13
|
||||
vmovdqa map6(%rip), %xmm15
|
||||
vpgatherdq %ymm14, (%rdx, %xmm15, 1), %ymm13
|
||||
|
||||
vpxor %ymm7,%ymm0,%ymm0
|
||||
vpxor %ymm8,%ymm1,%ymm1
|
||||
vpxor %ymm9,%ymm2,%ymm2
|
||||
vpxor %ymm10,%ymm3,%ymm3
|
||||
vpxor %ymm11,%ymm4,%ymm4
|
||||
vpxor %ymm12,%ymm5,%ymm5
|
||||
vpxor %ymm13,%ymm6,%ymm6
|
||||
add $17*8, %rdx
|
||||
lea iotas+12*4*8(%rip),%r10
|
||||
mov $12,%eax
|
||||
call __KeccakF1600
|
||||
sub $17, %rcx
|
||||
jnc KeccakP1600_12rounds_FastLoop_Absorb_Loop17Lanes
|
||||
jmp KeccakP1600_12rounds_FastLoop_Absorb_SaveAndExit
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_Not17Lanes:
|
||||
lea mapState(%rip), %r9
|
||||
mov %rsi, %rax
|
||||
KeccakP1600_12rounds_FastLoop_Absorb_LanesAddLoop:
|
||||
mov (%rdx), %r8
|
||||
add $8, %rdx
|
||||
mov (%r9), %r10
|
||||
add $8, %r9
|
||||
add %rdi, %r10
|
||||
xor %r8, (%r10)
|
||||
sub $1, %rax
|
||||
jnz KeccakP1600_12rounds_FastLoop_Absorb_LanesAddLoop
|
||||
sub %rsi, %rcx
|
||||
push %rdi
|
||||
push %rsi
|
||||
push %rdx
|
||||
push %rcx
|
||||
call KeccakP1600_Permute_12rounds@PLT
|
||||
pop %rcx
|
||||
pop %rdx
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
cmp %rsi, %rcx
|
||||
jae KeccakP1600_12rounds_FastLoop_Absorb_Not17Lanes
|
||||
jmp KeccakP1600_12rounds_FastLoop_Absorb_Exit
|
||||
.size KeccakP1600_12rounds_FastLoop_Absorb,.-KeccakP1600_12rounds_FastLoop_Absorb
|
||||
|
||||
.equ ALLON, 0xFFFFFFFFFFFFFFFF
|
||||
|
||||
.align 64
|
||||
|
||||
@ -45,7 +45,7 @@ typedef __m256i V256;
|
||||
#if defined(KeccakP1600times4_useAVX2)
|
||||
#define ANDnu256(a, b) _mm256_andnot_si256(a, b)
|
||||
#define CONST256(a) _mm256_load_si256((const V256 *)&(a))
|
||||
#define CONST256_64(a) (V256)_mm256_broadcast_sd((const double*)(&a))
|
||||
#define CONST256_64(a) _mm256_set1_epi64x(a)
|
||||
#define LOAD256(a) _mm256_load_si256((const V256 *)&(a))
|
||||
#define LOAD256u(a) _mm256_loadu_si256((const V256 *)&(a))
|
||||
#define LOAD4_64(a, b, c, d) _mm256_set_epi64x((UINT64)(a), (UINT64)(b), (UINT64)(c), (UINT64)(d))
|
||||
@ -56,13 +56,13 @@ static const UINT64 rho8[4] = {0x0605040302010007, 0x0E0D0C0B0A09080F, 0x1615141
|
||||
static const UINT64 rho56[4] = {0x0007060504030201, 0x080F0E0D0C0B0A09, 0x1017161514131211, 0x181F1E1D1C1B1A19};
|
||||
#define STORE256(a, b) _mm256_store_si256((V256 *)&(a), b)
|
||||
#define STORE256u(a, b) _mm256_storeu_si256((V256 *)&(a), b)
|
||||
#define STORE2_128(ah, al, v) _mm256_storeu2_m128d((V128*)&(ah), (V128*)&(al), v)
|
||||
#define STORE2_128(ah, al, v) _mm256_storeu2_m128i(&(ah), &(al), v)
|
||||
#define XOR256(a, b) _mm256_xor_si256(a, b)
|
||||
#define XOReq256(a, b) a = _mm256_xor_si256(a, b)
|
||||
#define UNPACKL( a, b ) _mm256_unpacklo_epi64((a), (b))
|
||||
#define UNPACKH( a, b ) _mm256_unpackhi_epi64((a), (b))
|
||||
#define PERM128( a, b, c ) (V256)_mm256_permute2f128_ps((__m256)(a), (__m256)(b), c)
|
||||
#define SHUFFLE64( a, b, c ) (V256)_mm256_shuffle_pd((__m256d)(a), (__m256d)(b), c)
|
||||
#define PERM128( a, b, c ) _mm256_permute2f128_si256((a), (b), c)
|
||||
#define SHUFFLE64( a, b, c ) _mm256_castpd_si256(_mm256_shuffle_pd(_mm256_castsi256_pd(a), _mm256_castsi256_pd(b), c))
|
||||
|
||||
#define UNINTLEAVE() lanesL01 = UNPACKL( lanes0, lanes1 ), \
|
||||
lanesH01 = UNPACKH( lanes0, lanes1 ), \
|
||||
|
||||
@ -353,21 +353,6 @@ void KeccakP1600_Permute_24rounds(void *state)
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP1600_Permute_12rounds(void *state)
|
||||
{
|
||||
declareABCDE
|
||||
#ifndef KeccakP1600_fullUnrolling
|
||||
unsigned int i;
|
||||
#endif
|
||||
UINT64 *stateAsLanes = (UINT64*)state;
|
||||
|
||||
copyFromState(A, stateAsLanes)
|
||||
rounds12
|
||||
copyToState(stateAsLanes, A)
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP1600_ExtractBytesInLane(const void *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
UINT64 lane = ((UINT64*)state)[lanePosition];
|
||||
@ -539,26 +524,3 @@ size_t KeccakF1600_FastLoop_Absorb(void *state, unsigned int laneCount, const un
|
||||
copyToState(stateAsLanes, A)
|
||||
return originalDataByteLen - dataByteLen;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
size_t KeccakP1600_12rounds_FastLoop_Absorb(void *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen)
|
||||
{
|
||||
size_t originalDataByteLen = dataByteLen;
|
||||
declareABCDE
|
||||
#ifndef KeccakP1600_fullUnrolling
|
||||
unsigned int i;
|
||||
#endif
|
||||
UINT64 *stateAsLanes = (UINT64*)state;
|
||||
UINT64 *inDataAsLanes = (UINT64*)data;
|
||||
|
||||
copyFromState(A, stateAsLanes)
|
||||
while(dataByteLen >= laneCount*8) {
|
||||
addInput(A, inDataAsLanes, laneCount)
|
||||
rounds12
|
||||
inDataAsLanes += laneCount;
|
||||
dataByteLen -= laneCount*8;
|
||||
}
|
||||
copyToState(stateAsLanes, A)
|
||||
return originalDataByteLen - dataByteLen;
|
||||
}
|
||||
|
||||
39
src/sig/picnic/external/simd.h
vendored
39
src/sig/picnic/external/simd.h
vendored
@ -24,11 +24,6 @@
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && !(defined(__APPLE__) && (__clang_major__ <= 8)) && \
|
||||
!defined(__MINGW32__) && !defined(__MINGW64__)
|
||||
#define BUILTIN_CPU_SUPPORTED
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
|
||||
@ -107,8 +102,10 @@ typedef __m256i word256;
|
||||
#endif
|
||||
|
||||
#define mm256_zero _mm256_setzero_si256()
|
||||
#define mm256_xor(l, r) _mm256_xor_si256(l, r)
|
||||
#define mm256_and(l, r) _mm256_and_si256(l, r)
|
||||
#define mm256_xor(l, r) _mm256_xor_si256((l), (r))
|
||||
#define mm256_and(l, r) _mm256_and_si256((l), (r))
|
||||
/* !l & r */
|
||||
#define mm256_nand(l, r) _mm256_andnot_si256((l), (r))
|
||||
|
||||
apply_region(mm256_xor_region, word256, mm256_xor, FN_ATTRIBUTES_AVX2)
|
||||
apply_mask_region(mm256_xor_mask_region, word256, mm256_xor, mm256_and, FN_ATTRIBUTES_AVX2)
|
||||
@ -119,8 +116,13 @@ apply_mask(mm256_xor_mask, word256, mm256_xor, mm256_and, FN_ATTRIBUTES_AVX2_CON
|
||||
typedef __m128i word128;
|
||||
|
||||
#define mm128_zero _mm_setzero_si128()
|
||||
#define mm128_xor(l, r) _mm_xor_si128(l, r)
|
||||
#define mm128_and(l, r) _mm_and_si128(l, r)
|
||||
#define mm128_xor(l, r) _mm_xor_si128((l), (r))
|
||||
#define mm128_and(l, r) _mm_and_si128((l), (r))
|
||||
/* !l & r */
|
||||
#define mm128_nand(l, r) _mm_andnot_si128((l), (r))
|
||||
#define mm128_broadcast_u64(x) _mm_set1_epi64x((x))
|
||||
#define mm128_sl_u64(x, s) _mm_slli_epi64((x), (s))
|
||||
#define mm128_sr_u64(x, s) _mm_srli_epi64((x), (s))
|
||||
|
||||
apply_region(mm128_xor_region, word128, mm128_xor, FN_ATTRIBUTES_SSE2)
|
||||
apply_mask_region(mm128_xor_mask_region, word128, mm128_xor, mm128_and, FN_ATTRIBUTES_SSE2)
|
||||
@ -133,14 +135,19 @@ apply_array(mm256_and_sse, word128, mm128_and, 2, FN_ATTRIBUTES_SSE2)
|
||||
typedef uint64x2_t word128;
|
||||
|
||||
#define mm128_zero vmovq_n_u64(0)
|
||||
#define mm128_xor(l, r) veorq_u64(l, r)
|
||||
#define mm128_and(l, r) vandq_u64(l, r)
|
||||
#define mm128_xor(l, r) veorq_u64((l), (r))
|
||||
#define mm128_and(l, r) vandq_u64((l), (r))
|
||||
/* !l & r, requires l to be an immediate */
|
||||
#define mm128_nand(l, r) vbicq_u64((r), (l))
|
||||
#define mm128_broadcast_u64(x) vdupq_n_u64((x))
|
||||
#define mm128_sl_u64(x, s) vshlq_n_u64((x), (s))
|
||||
#define mm128_sr_u64(x, s) vshrq_n_u64((x), (s))
|
||||
|
||||
apply_region(mm128_xor_region, word128, mm128_xor, FN_ATTRIBUTES_NEON);
|
||||
apply_mask_region(mm128_xor_mask_region, word128, mm128_xor, mm128_and, FN_ATTRIBUTES_NEON);
|
||||
apply_mask(mm128_xor_mask, word128, mm128_xor, mm128_and, FN_ATTRIBUTES_NEON_CONST);
|
||||
apply_array(mm256_xor, word128, mm128_xor, 2, FN_ATTRIBUTES_NEON);
|
||||
apply_array(mm256_and, word128, mm128_and, 2, FN_ATTRIBUTES_NEON);
|
||||
apply_region(mm128_xor_region, word128, mm128_xor, FN_ATTRIBUTES_NEON)
|
||||
apply_mask_region(mm128_xor_mask_region, word128, mm128_xor, mm128_and, FN_ATTRIBUTES_NEON)
|
||||
apply_mask(mm128_xor_mask, word128, mm128_xor, mm128_and, FN_ATTRIBUTES_NEON_CONST)
|
||||
apply_array(mm256_xor, word128, mm128_xor, 2, FN_ATTRIBUTES_NEON)
|
||||
apply_array(mm256_and, word128, mm128_and, 2, FN_ATTRIBUTES_NEON)
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@ -113,7 +113,7 @@ OQS_SIG *OQS_SIG_picnic_L1_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic_L1_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 1;
|
||||
sig->euf_cma = true;
|
||||
@ -152,7 +152,7 @@ OQS_SIG *OQS_SIG_picnic_L1_UR_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic_L1_UR;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 1;
|
||||
sig->euf_cma = true;
|
||||
@ -191,7 +191,7 @@ OQS_SIG *OQS_SIG_picnic_L3_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic_L3_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 3;
|
||||
sig->euf_cma = true;
|
||||
@ -230,7 +230,7 @@ OQS_SIG *OQS_SIG_picnic_L3_UR_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic_L3_UR;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 3;
|
||||
sig->euf_cma = true;
|
||||
@ -269,7 +269,7 @@ OQS_SIG *OQS_SIG_picnic_L5_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic_L5_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 5;
|
||||
sig->euf_cma = true;
|
||||
@ -309,7 +309,7 @@ OQS_SIG *OQS_SIG_picnic_L5_UR_new() {
|
||||
}
|
||||
|
||||
sig->method_name = OQS_SIG_alg_picnic_L5_UR;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 5;
|
||||
sig->euf_cma = true;
|
||||
@ -346,7 +346,7 @@ OQS_SIG *OQS_SIG_picnic2_L1_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic2_L1_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 1;
|
||||
sig->euf_cma = true;
|
||||
@ -384,7 +384,7 @@ OQS_SIG *OQS_SIG_picnic2_L3_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic2_L3_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 3;
|
||||
sig->euf_cma = true;
|
||||
@ -422,7 +422,7 @@ OQS_SIG *OQS_SIG_picnic2_L5_FS_new() {
|
||||
return NULL;
|
||||
}
|
||||
sig->method_name = OQS_SIG_alg_picnic2_L5_FS;
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1";
|
||||
sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.2";
|
||||
|
||||
sig->claimed_nist_level = 5;
|
||||
sig->euf_cma = true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user