mirror of
https://github.com/henrydcase/pqc.git
synced 2024-11-22 15:39:07 +00:00
add rainbowIa-cyclic
This commit is contained in:
parent
d42e96368a
commit
bf9af978d9
@ -148,10 +148,7 @@ int PQCLEAN_RAINBOWIACLASSIC_CLEAN_rainbow_sign( uint8_t *signature, const sk_t
|
||||
gf256v_add( signature + _PUB_N_BYTE, salt, _SALT_BYTE );
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _RAINBOW_CLASSIC
|
||||
int PQCLEAN_RAINBOWIACLASSIC_CLEAN_rainbow_verify( const uint8_t *digest, const uint8_t *signature, const pk_t *pk ) {
|
||||
unsigned char digest_ck[_PUB_M_BYTE];
|
||||
// public_map( digest_ck , pk , signature ); Evaluating the quadratic public polynomials.
|
||||
|
@ -19,9 +19,7 @@
|
||||
/// @param[in] digest - the digest.
|
||||
///
|
||||
int PQCLEAN_RAINBOWIACLASSIC_CLEAN_rainbow_sign( uint8_t *signature, const sk_t *sk, const uint8_t *digest );
|
||||
#endif
|
||||
|
||||
#ifdef _RAINBOW_CLASSIC
|
||||
///
|
||||
/// @brief Verifying function.
|
||||
///
|
||||
|
@ -97,6 +97,7 @@ void obsfucate_l1_polys( unsigned char *l1_polys, const unsigned char *l2_polys,
|
||||
|
||||
/////////////////// Classic //////////////////////////////////
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
static
|
||||
void _generate_secretkey( sk_t *sk, const unsigned char *sk_seed ) {
|
||||
memcpy( sk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
@ -113,7 +114,6 @@ void _generate_secretkey( sk_t *sk, const unsigned char *sk_seed ) {
|
||||
memset( &prng0, 0, sizeof(prng_t) );
|
||||
}
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair( pk_t *rpk, sk_t *sk, const unsigned char *sk_seed ) {
|
||||
_generate_secretkey( sk, sk_seed );
|
||||
|
||||
@ -140,6 +140,7 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair( pk_t *rpk, sk_t *sk, const
|
||||
///////////////////// Cyclic //////////////////////////////////
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair_cyclic( cpk_t *pk, sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed ) {
|
||||
memcpy( pk->pk_seed, pk_seed, LEN_PKSEED );
|
||||
memcpy( sk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
|
||||
// prng for sk
|
||||
prng_t prng;
|
||||
@ -163,8 +164,12 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair_cyclic( cpk_t *pk, sk_t *sk
|
||||
|
||||
PQCLEAN_RAINBOWIACLASSIC_CLEAN_calculate_F_from_Q( sk, Qs, sk ); // calcuate the rest parts of secret key from Qs and S,T
|
||||
|
||||
|
||||
unsigned char t4[sizeof(sk->t4)];
|
||||
memcpy( t4, sk->t4, _V1_BYTE * _O2 ); // temporarily store t4
|
||||
memcpy( sk->t4, t2, _V1_BYTE * _O2 ); // restore t2
|
||||
PQCLEAN_RAINBOWIACLASSIC_CLEAN_calculate_Q_from_F_cyclic( pk, sk, sk ); // calculate the rest parts of public key: l1_Q3, l1_Q5, l1_Q6, l1_Q9, l2_Q9
|
||||
memcpy( sk->t4, t4, _V1_BYTE * _O2 ); // restore t4
|
||||
|
||||
obsfucate_l1_polys( pk->l1_Q3, Qs->l2_F3, _V1 * _O2, sk->s1 );
|
||||
obsfucate_l1_polys( pk->l1_Q5, Qs->l2_F5, N_TRIANGLE_TERMS(_O1), sk->s1 );
|
||||
@ -213,7 +218,8 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_secretkey_cyclic( sk_t *sk, const u
|
||||
// clean prng for sk
|
||||
memset( &prng0, 0, sizeof(prng_t) );
|
||||
}
|
||||
|
||||
#endif
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_cpk_to_pk( pk_t *rpk, const cpk_t *cpk ) {
|
||||
// procedure: cpk_t --> extcpk_t --> pk_t
|
||||
|
||||
|
@ -94,8 +94,9 @@ struct rainbow_secretkey_cyclic {
|
||||
/// @param[in] sk_seed - seed for generating the secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair( pk_t *pk, sk_t *sk, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
#if defined _RAINBOW_CYCLIC
|
||||
///
|
||||
/// @brief Generate key pairs for cyclic rainbow.
|
||||
///
|
||||
@ -105,8 +106,9 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair( pk_t *pk, sk_t *sk, const
|
||||
/// @param[in] sk_seed - seed for generating secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair_cyclic( cpk_t *pk, sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
#if defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
///
|
||||
/// @brief Generate compressed key pairs for cyclic rainbow.
|
||||
///
|
||||
@ -127,7 +129,9 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_compact_keypair_cyclic( cpk_t *pk,
|
||||
/// @param[in] sk_seed - seed for generating the secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_secretkey_cyclic( sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
////////////////////////////////////
|
||||
|
||||
///
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
#if defined _RAINBOW_CYCLIC || defined _RAINBOW_CLASSIC
|
||||
void PQCLEAN_RAINBOWIACLASSIC_CLEAN_extcpk_to_pk( pk_t *pk, const ext_cpk_t *cpk ) {
|
||||
const unsigned char *idx_l1 = cpk->l1_Q1;
|
||||
const unsigned char *idx_l2 = cpk->l2_Q1;
|
||||
@ -82,7 +82,9 @@ void PQCLEAN_RAINBOWIACLASSIC_CLEAN_extcpk_to_pk( pk_t *pk, const ext_cpk_t *cpk
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
static
|
||||
void calculate_Q_from_F_ref( ext_cpk_t *Qs, const sk_t *Fs, const sk_t *Ts ) {
|
||||
/*
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "rainbow_keypair.h"
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
#if defined _RAINBOW_CYCLIC || defined _RAINBOW_CLASSIC
|
||||
/// @brief The (internal use) public key for rainbow
|
||||
///
|
||||
/// The (internal use) public key for rainbow. The public
|
||||
|
@ -27,13 +27,13 @@ PQCLEAN_RAINBOWIACLASSIC_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned c
|
||||
|
||||
unsigned char pk_seed[LEN_PKSEED] = {0};
|
||||
randombytes( pk_seed, LEN_PKSEED );
|
||||
generate_keypair_cyclic( (cpk_t *) pk, (sk_t *) sk, pk_seed, sk_seed );
|
||||
PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_keypair_cyclic( (cpk_t *) pk, (sk_t *) sk, pk_seed, sk_seed );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
unsigned char pk_seed[LEN_PKSEED] = {0};
|
||||
randombytes( pk_seed, LEN_PKSEED );
|
||||
generate_compact_keypair_cyclic( (cpk_t *) pk, (csk_t *) sk, pk_seed, sk_seed );
|
||||
PQCLEAN_RAINBOWIACLASSIC_CLEAN_generate_compact_keypair_cyclic( (cpk_t *) pk, (csk_t *) sk, pk_seed, sk_seed );
|
||||
|
||||
#else
|
||||
error here
|
||||
@ -60,11 +60,11 @@ PQCLEAN_RAINBOWIACLASSIC_CLEAN_crypto_sign(unsigned char *sm, size_t *smlen, con
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
|
||||
return rainbow_sign( sm + mlen, (const sk_t *)sk, digest );
|
||||
return PQCLEAN_RAINBOWIACLASSIC_CLEAN_rainbow_sign( sm + mlen, (const sk_t *)sk, digest );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
return rainbow_sign_cyclic( sm + mlen, (const csk_t *)sk, digest );
|
||||
return PQCLEAN_RAINBOWIACLASSIC_CLEAN_rainbow_sign_cyclic( sm + mlen, (const csk_t *)sk, digest );
|
||||
|
||||
#else
|
||||
error here
|
||||
|
17
crypto_sign/rainbowIa-cyclic/META.yml
Normal file
17
crypto_sign/rainbowIa-cyclic/META.yml
Normal file
@ -0,0 +1,17 @@
|
||||
name: Rainbow-Ia-cyclic
|
||||
type: signature
|
||||
claimed-nist-level: 1
|
||||
length-public-key: 58144
|
||||
length-secret-key: 92960
|
||||
length-signature: 64
|
||||
nistkat-sha256: 16f53bf0966b433451ae26e47f09f2dc8ea42db6a5c58fff1a2e7954f94dac0a
|
||||
testvectors-sha256: b7341bd862a8f683339e03cf236b885804854d9e0479cb53955761864ecc18bf
|
||||
principal-submitter: Jintai Ding
|
||||
auxiliary-submitters:
|
||||
- Ming-Shing Chen
|
||||
- Albrecht Petzoldt
|
||||
- Dieter Schmidt
|
||||
- Bo-Yin Yang
|
||||
implementations:
|
||||
- name: clean
|
||||
version: https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents/round-2/submissions/Rainbow-Round2.zip
|
1
crypto_sign/rainbowIa-cyclic/clean/LICENSE
Normal file
1
crypto_sign/rainbowIa-cyclic/clean/LICENSE
Normal file
@ -0,0 +1 @@
|
||||
XXX
|
20
crypto_sign/rainbowIa-cyclic/clean/Makefile
Normal file
20
crypto_sign/rainbowIa-cyclic/clean/Makefile
Normal file
@ -0,0 +1,20 @@
|
||||
# This Makefile can be used with GNU Make or BSD Make
|
||||
|
||||
LIB=librainbowIa-cyclic_clean.a
|
||||
|
||||
HEADERS = api.h blas_comm.h blas.h blas_u32.h gf.h parallel_matrix_op.h rainbow_blas.h rainbow_config.h rainbow.h rainbow_keypair_computation.h rainbow_keypair.h utils_hash.h utils_prng.h
|
||||
OBJECTS = blas_comm.o parallel_matrix_op.o rainbow.o rainbow_keypair.o rainbow_keypair_computation.o sign.o utils_hash.o utils_prng.o blas_u32.o gf.o
|
||||
|
||||
CFLAGS=-O3 -Wall -Wconversion -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -Wredundant-decls -std=c99 -I../../../common $(EXTRAFLAGS)
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
$(LIB): $(OBJECTS)
|
||||
$(AR) -r $@ $(OBJECTS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS)
|
||||
$(RM) $(LIB)
|
19
crypto_sign/rainbowIa-cyclic/clean/Makefile.Microsoft_nmake
Normal file
19
crypto_sign/rainbowIa-cyclic/clean/Makefile.Microsoft_nmake
Normal file
@ -0,0 +1,19 @@
|
||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
||||
# nmake /f Makefile.Microsoft_nmake
|
||||
|
||||
LIBRARY=librainbowIa-cyclic_clean.lib
|
||||
OBJECTS = blas_comm.obj parallel_matrix_op.obj rainbow.obj rainbow_keypair.obj rainbow_keypair_computation.obj sign.obj utils_hash.obj utils_prng.obj blas_u32.obj gf.obj
|
||||
|
||||
CFLAGS=/nologo /I ..\..\..\common /W4 /WX
|
||||
|
||||
all: $(LIBRARY)
|
||||
|
||||
# Make sure objects are recompiled if headers change.
|
||||
$(OBJECTS): *.h
|
||||
|
||||
$(LIBRARY): $(OBJECTS)
|
||||
LIB.EXE /NOLOGO /WX /OUT:$@ $**
|
||||
|
||||
clean:
|
||||
-DEL $(OBJECTS)
|
||||
-DEL $(LIBRARY)
|
32
crypto_sign/rainbowIa-cyclic/clean/api.h
Normal file
32
crypto_sign/rainbowIa-cyclic/clean/api.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef PQCLEAN_RAINBOWIACYCLIC_CLEAN_API_H
|
||||
#define PQCLEAN_RAINBOWIACYCLIC_CLEAN_API_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define PQCLEAN_RAINBOWIACYCLIC_CLEAN_CRYPTO_SECRETKEYBYTES 92960
|
||||
#define PQCLEAN_RAINBOWIACYCLIC_CLEAN_CRYPTO_PUBLICKEYBYTES 58144
|
||||
#define PQCLEAN_RAINBOWIACYCLIC_CLEAN_CRYPTO_BYTES 64
|
||||
#define PQCLEAN_RAINBOWIACYCLIC_CLEAN_CRYPTO_ALGNAME "RAINBOW(16,32,32,32) - cyclic"
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk);
|
||||
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_signature(
|
||||
uint8_t *sig, size_t *siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *sk);
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_verify(
|
||||
const uint8_t *sig, size_t siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *pk);
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign(uint8_t *sm, size_t *smlen,
|
||||
const uint8_t *m, size_t mlen,
|
||||
const uint8_t *sk);
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_open(uint8_t *m, size_t *mlen,
|
||||
const uint8_t *sm, size_t smlen,
|
||||
const uint8_t *pk);
|
||||
|
||||
|
||||
#endif
|
28
crypto_sign/rainbowIa-cyclic/clean/blas.h
Normal file
28
crypto_sign/rainbowIa-cyclic/clean/blas.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _BLAS_H_
|
||||
#define _BLAS_H_
|
||||
/// @file blas.h
|
||||
/// @brief Defining the implementations for linear algebra functions depending on the machine architecture.
|
||||
///
|
||||
|
||||
#include "blas_comm.h"
|
||||
#include "blas_u32.h"
|
||||
#include "rainbow_config.h"
|
||||
|
||||
#define gf256v_predicated_add PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_predicated_add_u32
|
||||
#define gf256v_add PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_add_u32
|
||||
|
||||
#ifdef _USE_GF16
|
||||
|
||||
#define gf16v_mul_scalar PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_scalar_u32
|
||||
#define gf16v_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_madd_u32
|
||||
#define gf16v_dot PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_dot_u32
|
||||
|
||||
#else
|
||||
|
||||
#define gf256v_mul_scalar PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_scalar_u32
|
||||
#define gf256v_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_madd_u32
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _BLAS_H_
|
||||
|
297
crypto_sign/rainbowIa-cyclic/clean/blas_comm.c
Normal file
297
crypto_sign/rainbowIa-cyclic/clean/blas_comm.c
Normal file
@ -0,0 +1,297 @@
|
||||
/// @file blas_comm.c
|
||||
/// @brief The standard implementations for blas_comm.h
|
||||
///
|
||||
|
||||
#include "blas.h"
|
||||
#include "blas_comm.h"
|
||||
#include "gf.h"
|
||||
#include "rainbow_config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(uint8_t *b, unsigned _num_byte) {
|
||||
gf256v_add(b, b, _num_byte);
|
||||
}
|
||||
#ifdef _USE_GF16
|
||||
|
||||
/// @brief get an element from GF(16) vector .
|
||||
///
|
||||
/// @param[in] a - the input vector a.
|
||||
/// @param[in] i - the index in the vector a.
|
||||
/// @return the value of the element.
|
||||
///
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(const uint8_t *a, unsigned i) {
|
||||
uint8_t r = a[i >> 1];
|
||||
uint8_t r0 = r & 0xf;
|
||||
uint8_t r1 = r >> 4;
|
||||
uint8_t m = (uint8_t)(-((int8_t)i & 1));
|
||||
return (uint8_t)((r1 & m) | ((~m)&r0));
|
||||
}
|
||||
|
||||
/// @brief set an element for a GF(16) vector .
|
||||
///
|
||||
/// @param[in,out] a - the vector a.
|
||||
/// @param[in] i - the index in the vector a.
|
||||
/// @param[in] v - the value for the i-th element in vector a.
|
||||
/// @return the value of the element.
|
||||
///
|
||||
static uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_set_ele(uint8_t *a, unsigned i, uint8_t v) {
|
||||
uint8_t m = (uint8_t) (0xf ^ (-((int8_t)i & 1))); /// 1--> 0xf0 , 0--> 0x0f
|
||||
uint8_t ai_remaining = (uint8_t) (a[i >> 1] & (~m)); /// erase
|
||||
a[i >> 1] = (uint8_t) (ai_remaining | (m & (v << 4)) | (m & v & 0xf)); /// set
|
||||
return v;
|
||||
}
|
||||
|
||||
static void gf16mat_prod_ref(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(c, n_A_vec_byte);
|
||||
for (unsigned i = 0; i < n_A_width; i++) {
|
||||
uint8_t bb = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(b, i);
|
||||
gf16v_madd(c, matA, bb, n_A_vec_byte);
|
||||
matA += n_A_vec_byte;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_mul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned len_vec) {
|
||||
unsigned n_vec_byte = (len_vec + 1) / 2;
|
||||
for (unsigned k = 0; k < len_vec; k++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(c, n_vec_byte);
|
||||
const uint8_t *bk = b + n_vec_byte * k;
|
||||
for (unsigned i = 0; i < len_vec; i++) {
|
||||
uint8_t bb = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(bk, i);
|
||||
gf16v_madd(c, a + n_vec_byte * i, bb, n_vec_byte);
|
||||
}
|
||||
c += n_vec_byte;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
unsigned gf16mat_gauss_elim_ref(uint8_t *mat, unsigned h, unsigned w) {
|
||||
unsigned n_w_byte = (w + 1) / 2;
|
||||
unsigned r8 = 1;
|
||||
for (unsigned i = 0; i < h; i++) {
|
||||
unsigned offset_byte = i >> 1;
|
||||
uint8_t *ai = mat + n_w_byte * i;
|
||||
for (unsigned j = i + 1; j < h; j++) {
|
||||
uint8_t *aj = mat + n_w_byte * j;
|
||||
gf256v_predicated_add(ai + offset_byte, !PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_is_nonzero(PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(ai, i)), aj + offset_byte, n_w_byte - offset_byte);
|
||||
}
|
||||
uint8_t pivot = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(ai, i);
|
||||
r8 &= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_is_nonzero(pivot);
|
||||
pivot = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_inv(pivot);
|
||||
offset_byte = (i + 1) >> 1;
|
||||
gf16v_mul_scalar(ai + offset_byte, pivot, n_w_byte - offset_byte);
|
||||
for (unsigned j = 0; j < h; j++) {
|
||||
if (i == j) {
|
||||
continue;
|
||||
}
|
||||
uint8_t *aj = mat + n_w_byte * j;
|
||||
gf16v_madd(aj + offset_byte, ai + offset_byte, PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(aj, i), n_w_byte - offset_byte);
|
||||
}
|
||||
}
|
||||
return r8;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned gf16mat_solve_linear_eq_ref(uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n) {
|
||||
uint8_t mat[64 * 33];
|
||||
unsigned n_byte = (n + 1) >> 1;
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
memcpy(mat + i * (n_byte + 1), inp_mat + i * n_byte, n_byte);
|
||||
mat[i * (n_byte + 1) + n_byte] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(c_terms, i);
|
||||
}
|
||||
unsigned r8 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_gauss_elim(mat, n, n + 2); /// XXX: this function is ``defined'' in blas.h
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_set_ele(sol, i, mat[i * (n_byte + 1) + n_byte]);
|
||||
}
|
||||
return r8;
|
||||
}
|
||||
|
||||
static inline void gf16mat_submat(uint8_t *mat2, unsigned w2, unsigned st, const uint8_t *mat, unsigned w, unsigned h) {
|
||||
unsigned n_byte_w1 = (w + 1) / 2;
|
||||
unsigned n_byte_w2 = (w2 + 1) / 2;
|
||||
unsigned st_2 = st / 2;
|
||||
for (unsigned i = 0; i < h; i++) {
|
||||
for (unsigned j = 0; j < n_byte_w2; j++) {
|
||||
mat2[i * n_byte_w2 + j] = mat[i * n_byte_w1 + st_2 + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_inv(uint8_t *inv_a, const uint8_t *a, unsigned H, uint8_t *buffer) {
|
||||
unsigned n_w_byte = (H + 1) / 2;
|
||||
|
||||
uint8_t *aa = buffer;
|
||||
for (unsigned i = 0; i < H; i++) {
|
||||
uint8_t *ai = aa + i * 2 * n_w_byte;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(ai, 2 * n_w_byte);
|
||||
gf256v_add(ai, a + i * n_w_byte, n_w_byte);
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_set_ele(ai + n_w_byte, i, 1);
|
||||
}
|
||||
unsigned r8 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_gauss_elim(aa, H, 2 * H); /// XXX: would 2*H fail if H is odd ???
|
||||
gf16mat_submat(inv_a, H, H, aa, 2 * H, H);
|
||||
return r8;
|
||||
}
|
||||
#else
|
||||
/// @brief get an element from GF(256) vector .
|
||||
///
|
||||
/// @param[in] a - the input vector a.
|
||||
/// @param[in] i - the index in the vector a.
|
||||
/// @return the value of the element.
|
||||
///
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele(const uint8_t *a, unsigned i) {
|
||||
return a[i];
|
||||
}
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_is_zero(const uint8_t *a, unsigned _num_byte) {
|
||||
uint8_t r = 0;
|
||||
while ( _num_byte-- ) {
|
||||
r |= a[0];
|
||||
a++;
|
||||
}
|
||||
return (0 == r);
|
||||
}
|
||||
|
||||
/// polynomial multplication
|
||||
/// School boook
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_polymul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned _num) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(c, _num * 2 - 1);
|
||||
for (unsigned i = 0; i < _num; i++) {
|
||||
gf256v_madd(c + i, a, b[i], _num);
|
||||
}
|
||||
}
|
||||
|
||||
static void gf256mat_prod_ref(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(c, n_A_vec_byte);
|
||||
for (unsigned i = 0; i < n_A_width; i++) {
|
||||
gf256v_madd(c, matA, b[i], n_A_vec_byte);
|
||||
matA += n_A_vec_byte;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_mul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned len_vec) {
|
||||
unsigned n_vec_byte = len_vec;
|
||||
for (unsigned k = 0; k < len_vec; k++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(c, n_vec_byte);
|
||||
const uint8_t *bk = b + n_vec_byte * k;
|
||||
for (unsigned i = 0; i < len_vec; i++) {
|
||||
gf256v_madd(c, a + n_vec_byte * i, bk[i], n_vec_byte);
|
||||
}
|
||||
c += n_vec_byte;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
unsigned gf256mat_gauss_elim_ref( uint8_t *mat, unsigned h, unsigned w ) {
|
||||
unsigned r8 = 1;
|
||||
|
||||
for (unsigned i = 0; i < h; i++) {
|
||||
uint8_t *ai = mat + w * i;
|
||||
unsigned skip_len_align4 = i & ((unsigned)~0x3);
|
||||
|
||||
for (unsigned j = i + 1; j < h; j++) {
|
||||
uint8_t *aj = mat + w * j;
|
||||
gf256v_predicated_add( ai + skip_len_align4, !PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_is_nonzero(ai[i]), aj + skip_len_align4, w - skip_len_align4 );
|
||||
}
|
||||
r8 &= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_is_nonzero(ai[i]);
|
||||
uint8_t pivot = ai[i];
|
||||
pivot = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_inv( pivot );
|
||||
gf256v_mul_scalar( ai + skip_len_align4, pivot, w - skip_len_align4 );
|
||||
for (unsigned j = 0; j < h; j++) {
|
||||
if (i == j) {
|
||||
continue;
|
||||
}
|
||||
uint8_t *aj = mat + w * j;
|
||||
gf256v_madd( aj + skip_len_align4, ai + skip_len_align4, aj[i], w - skip_len_align4 );
|
||||
}
|
||||
}
|
||||
|
||||
return r8;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned gf256mat_solve_linear_eq_ref( uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n ) {
|
||||
uint8_t mat[ 64 * 64 ];
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
memcpy( mat + i * (n + 1), inp_mat + i * n, n );
|
||||
mat[i * (n + 1) + n] = c_terms[i];
|
||||
}
|
||||
unsigned r8 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_gauss_elim( mat, n, n + 1 );
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
sol[i] = mat[i * (n + 1) + n];
|
||||
}
|
||||
return r8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline
|
||||
void gf256mat_submat( uint8_t *mat2, unsigned w2, unsigned st, const uint8_t *mat, unsigned w, unsigned h ) {
|
||||
for (unsigned i = 0; i < h; i++) {
|
||||
for (unsigned j = 0; j < w2; j++) {
|
||||
mat2[i * w2 + j] = mat[i * w + st + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_inv( uint8_t *inv_a, const uint8_t *a, unsigned H, uint8_t *buffer ) {
|
||||
uint8_t *aa = buffer;
|
||||
for (unsigned i = 0; i < H; i++) {
|
||||
uint8_t *ai = aa + i * 2 * H;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( ai, 2 * H );
|
||||
gf256v_add( ai, a + i * H, H );
|
||||
ai[H + i] = 1;
|
||||
}
|
||||
unsigned r8 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_gauss_elim( aa, H, 2 * H );
|
||||
gf256mat_submat( inv_a, H, H, aa, 2 * H, H );
|
||||
return r8;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// choosing the implementations depends on the macros _BLAS_AVX2_ and _BLAS_SSE
|
||||
|
||||
#ifdef _USE_GF16
|
||||
#define gf16mat_prod_impl gf16mat_prod_ref
|
||||
#define gf16mat_gauss_elim_impl gf16mat_gauss_elim_ref
|
||||
#define gf16mat_solve_linear_eq_impl gf16mat_solve_linear_eq_ref
|
||||
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_prod(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b) {
|
||||
gf16mat_prod_impl( c, matA, n_A_vec_byte, n_A_width, b);
|
||||
}
|
||||
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_gauss_elim(uint8_t *mat, unsigned h, unsigned w) {
|
||||
return gf16mat_gauss_elim_impl( mat, h, w);
|
||||
}
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_solve_linear_eq( uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n ) {
|
||||
return gf16mat_solve_linear_eq_impl( sol, inp_mat, c_terms, n );
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
#define gf256mat_prod_impl gf256mat_prod_ref
|
||||
#define gf256mat_gauss_elim_impl gf256mat_gauss_elim_ref
|
||||
#define gf256mat_solve_linear_eq_impl gf256mat_solve_linear_eq_ref
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_prod(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b) {
|
||||
gf256mat_prod_impl( c, matA, n_A_vec_byte, n_A_width, b);
|
||||
}
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_gauss_elim( uint8_t *mat, unsigned h, unsigned w ) {
|
||||
return gf256mat_gauss_elim_impl( mat, h, w );
|
||||
}
|
||||
|
||||
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_solve_linear_eq( uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n ) {
|
||||
return gf256mat_solve_linear_eq_impl( sol, inp_mat, c_terms, n );
|
||||
}
|
||||
|
||||
#endif
|
155
crypto_sign/rainbowIa-cyclic/clean/blas_comm.h
Normal file
155
crypto_sign/rainbowIa-cyclic/clean/blas_comm.h
Normal file
@ -0,0 +1,155 @@
|
||||
#ifndef _BLAS_COMM_H_
|
||||
#define _BLAS_COMM_H_
|
||||
/// @file blas_comm.h
|
||||
/// @brief Common functions for linear algebra.
|
||||
///
|
||||
|
||||
#include "rainbow_config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/// @brief set a vector to 0.
|
||||
///
|
||||
/// @param[in,out] b - the vector b.
|
||||
/// @param[in] _num_byte - number of bytes for the vector b.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero(uint8_t *b, unsigned _num_byte);
|
||||
|
||||
#ifdef _USE_GF16
|
||||
/// @brief get an element from GF(16) vector .
|
||||
///
|
||||
/// @param[in] a - the input vector a.
|
||||
/// @param[in] i - the index in the vector a.
|
||||
/// @return the value of the element.
|
||||
///
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele(const uint8_t *a, unsigned i);
|
||||
|
||||
/// @brief matrix-matrix multiplication: c = a * b , in GF(16)
|
||||
///
|
||||
/// @param[out] c - the output matrix c
|
||||
/// @param[in] c - a matrix a.
|
||||
/// @param[in] b - a matrix b.
|
||||
/// @param[in] len_vec - the length of column vectors.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_mul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned len_vec);
|
||||
|
||||
/// @brief Gauss elimination for a matrix, in GF(16)
|
||||
///
|
||||
/// @param[in,out] mat - the matrix.
|
||||
/// @param[in] h - the height of the matrix.
|
||||
/// @param[in] w - the width of the matrix.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_gauss_elim(uint8_t *mat, unsigned h, unsigned w);
|
||||
|
||||
/// @brief Solving linear equations, in GF(16)
|
||||
///
|
||||
/// @param[out] sol - the solutions.
|
||||
/// @param[in] inp_mat - the matrix parts of input equations.
|
||||
/// @param[in] c_terms - the constant terms of the input equations.
|
||||
/// @param[in] n - the number of equations.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_solve_linear_eq(uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n);
|
||||
|
||||
/// @brief Computing the inverse matrix, in GF(16)
|
||||
///
|
||||
/// @param[out] inv_a - the output of matrix a.
|
||||
/// @param[in] a - a matrix a.
|
||||
/// @param[in] H - height of matrix a, i.e., matrix a is an HxH matrix.
|
||||
/// @param[in] buffer - The buffer for computations. it has to be as large as 2 input matrixes.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_inv(uint8_t *inv_a, const uint8_t *a, unsigned H, uint8_t *buffer);
|
||||
|
||||
/// @brief matrix-vector multiplication: c = matA * b , in GF(16)
|
||||
///
|
||||
/// @param[out] c - the output vector c
|
||||
/// @param[in] matA - a column-major matrix A.
|
||||
/// @param[in] n_A_vec_byte - the size of column vectors in bytes.
|
||||
/// @param[in] n_A_width - the width of matrix A.
|
||||
/// @param[in] b - the vector b.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_prod(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b);
|
||||
|
||||
#else
|
||||
/// @brief get an element from GF(256) vector .
|
||||
///
|
||||
/// @param[in] a - the input vector a.
|
||||
/// @param[in] i - the index in the vector a.
|
||||
/// @return the value of the element.
|
||||
///
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele(const uint8_t *a, unsigned i);
|
||||
|
||||
|
||||
|
||||
/// @brief check if a vector is 0.
|
||||
///
|
||||
/// @param[in] a - the vector a.
|
||||
/// @param[in] _num_byte - number of bytes for the vector a.
|
||||
/// @return 1(true) if a is 0. 0(false) else.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_is_zero(const uint8_t *a, unsigned _num_byte);
|
||||
|
||||
|
||||
/// @brief polynomial multiplication: c = a*b
|
||||
///
|
||||
/// @param[out] c - the output polynomial c
|
||||
/// @param[in] a - the vector a.
|
||||
/// @param[in] b - the vector b.
|
||||
/// @param[in] _num - number of elements for the polynomials a and b.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_polymul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned _num);
|
||||
|
||||
|
||||
/// @brief matrix-vector multiplication: c = matA * b , in GF(256)
|
||||
///
|
||||
/// @param[out] c - the output vector c
|
||||
/// @param[in] matA - a column-major matrix A.
|
||||
/// @param[in] n_A_vec_byte - the size of column vectors in bytes.
|
||||
/// @param[in] n_A_width - the width of matrix A.
|
||||
/// @param[in] b - the vector b.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_prod(uint8_t *c, const uint8_t *matA, unsigned n_A_vec_byte, unsigned n_A_width, const uint8_t *b);
|
||||
|
||||
/// @brief matrix-matrix multiplication: c = a * b , in GF(256)
|
||||
///
|
||||
/// @param[out] c - the output matrix c
|
||||
/// @param[in] c - a matrix a.
|
||||
/// @param[in] b - a matrix b.
|
||||
/// @param[in] len_vec - the length of column vectors.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_mul(uint8_t *c, const uint8_t *a, const uint8_t *b, unsigned len_vec);
|
||||
|
||||
/// @brief Gauss elimination for a matrix, in GF(256)
|
||||
///
|
||||
/// @param[in,out] mat - the matrix.
|
||||
/// @param[in] h - the height of the matrix.
|
||||
/// @param[in] w - the width of the matrix.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_gauss_elim(uint8_t *mat, unsigned h, unsigned w);
|
||||
|
||||
/// @brief Solving linear equations, in GF(256)
|
||||
///
|
||||
/// @param[out] sol - the solutions.
|
||||
/// @param[in] inp_mat - the matrix parts of input equations.
|
||||
/// @param[in] c_terms - the constant terms of the input equations.
|
||||
/// @param[in] n - the number of equations.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_solve_linear_eq(uint8_t *sol, const uint8_t *inp_mat, const uint8_t *c_terms, unsigned n);
|
||||
|
||||
/// @brief Computing the inverse matrix, in GF(256)
|
||||
///
|
||||
/// @param[out] inv_a - the output of matrix a.
|
||||
/// @param[in] a - a matrix a.
|
||||
/// @param[in] H - height of matrix a, i.e., matrix a is an HxH matrix.
|
||||
/// @param[in] buffer - The buffer for computations. it has to be as large as 2 input matrixes.
|
||||
/// @return 1(true) if success. 0(false) if the matrix is singular.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256mat_inv(uint8_t *inv_a, const uint8_t *a, unsigned H, uint8_t *buffer);
|
||||
#endif
|
||||
|
||||
#endif // _BLAS_COMM_H_
|
||||
|
170
crypto_sign/rainbowIa-cyclic/clean/blas_u32.c
Normal file
170
crypto_sign/rainbowIa-cyclic/clean/blas_u32.c
Normal file
@ -0,0 +1,170 @@
|
||||
#include "blas_u32.h"
|
||||
#include "gf.h"
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_predicated_add_u32(uint8_t *accu_b, uint8_t predicate, const uint8_t *a, unsigned _num_byte) {
|
||||
uint32_t pr_u32 = ((uint32_t) 0) - ((uint32_t) predicate);
|
||||
uint8_t pr_u8 = pr_u32 & 0xff;
|
||||
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *b_u32 = (uint32_t *) accu_b;
|
||||
const uint32_t *a_u32 = (const uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
b_u32[i] ^= (a_u32[i] & pr_u32);
|
||||
}
|
||||
|
||||
a += (n_u32 << 2);
|
||||
accu_b += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
accu_b[i] ^= (a[i] & pr_u8);
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_add_u32(uint8_t *accu_b, const uint8_t *a, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *b_u32 = (uint32_t *) accu_b;
|
||||
const uint32_t *a_u32 = (const uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
b_u32[i] ^= a_u32[i];
|
||||
}
|
||||
|
||||
a += (n_u32 << 2);
|
||||
accu_b += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
accu_b[i] ^= a[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _USE_GF16
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_scalar_u32(uint8_t *a, uint8_t gf16_b, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *a_u32 = (uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
a_u32[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(a_u32[i], gf16_b);
|
||||
}
|
||||
|
||||
union tmp_32 {
|
||||
uint8_t u8[4];
|
||||
uint32_t u32;
|
||||
} t;
|
||||
t.u32 = 0;
|
||||
a += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
t.u8[i] = a[i];
|
||||
}
|
||||
t.u32 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(t.u32, gf16_b);
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
a[i] = t.u8[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_madd_u32(uint8_t *accu_c, const uint8_t *a, uint8_t gf16_b, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *c_u32 = (uint32_t *) accu_c;
|
||||
const uint32_t *a_u32 = (const uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
c_u32[i] ^= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(a_u32[i], gf16_b);
|
||||
}
|
||||
|
||||
union tmp_32 {
|
||||
uint8_t u8[4];
|
||||
uint32_t u32;
|
||||
} t;
|
||||
t.u32 = 0;
|
||||
accu_c += (n_u32 << 2);
|
||||
a += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
t.u8[i] = a[i];
|
||||
}
|
||||
t.u32 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(t.u32, gf16_b);
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
accu_c[i] ^= t.u8[i];
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_dot_u32(const uint8_t *a, const uint8_t *b, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
const uint32_t *a_u32 = (const uint32_t *) a;
|
||||
const uint32_t *b_u32 = (const uint32_t *) b;
|
||||
uint32_t r = 0;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
r ^= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32_u32(a_u32[i], b_u32[i]);
|
||||
}
|
||||
|
||||
unsigned rem = _num_byte & 3;
|
||||
if (rem) {
|
||||
union tmp_32 {
|
||||
uint8_t u8[4];
|
||||
uint32_t u32;
|
||||
} ta, tb;
|
||||
ta.u32 = 0;
|
||||
tb.u32 = 0;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
ta.u8[i] = a[(n_u32 << 2) + i];
|
||||
}
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
tb.u8[i] = b[(n_u32 << 2) + i];
|
||||
}
|
||||
r ^= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32_u32(ta.u32, tb.u32);
|
||||
}
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_reduce_u32(r);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_scalar_u32(uint8_t *a, uint8_t b, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *a_u32 = (uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
a_u32[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(a_u32[i], b);
|
||||
}
|
||||
|
||||
union tmp_32 {
|
||||
uint8_t u8[4];
|
||||
uint32_t u32;
|
||||
} t;
|
||||
t.u32 = 0;
|
||||
a += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
t.u8[i] = a[i];
|
||||
}
|
||||
t.u32 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(t.u32, b);
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
a[i] = t.u8[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_madd_u32(uint8_t *accu_c, const uint8_t *a, uint8_t gf256_b, unsigned _num_byte) {
|
||||
unsigned n_u32 = _num_byte >> 2;
|
||||
uint32_t *c_u32 = (uint32_t *) accu_c;
|
||||
const uint32_t *a_u32 = (const uint32_t *) a;
|
||||
for (unsigned i = 0; i < n_u32; i++) {
|
||||
c_u32[i] ^= PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(a_u32[i], gf256_b);
|
||||
}
|
||||
|
||||
union tmp_32 {
|
||||
uint8_t u8[4];
|
||||
uint32_t u32;
|
||||
} t;
|
||||
t.u32 = 0;
|
||||
accu_c += (n_u32 << 2);
|
||||
a += (n_u32 << 2);
|
||||
unsigned rem = _num_byte & 3;
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
t.u8[i] = a[i];
|
||||
}
|
||||
t.u32 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(t.u32, gf256_b);
|
||||
for (unsigned i = 0; i < rem; i++) {
|
||||
accu_c[i] ^= t.u8[i];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
27
crypto_sign/rainbowIa-cyclic/clean/blas_u32.h
Normal file
27
crypto_sign/rainbowIa-cyclic/clean/blas_u32.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef _BLAS_U32_H_
|
||||
#define _BLAS_U32_H_
|
||||
/// @file blas_u32.h
|
||||
/// @brief Inlined functions for implementing basic linear algebra functions for uint32 arch.
|
||||
///
|
||||
|
||||
#include "rainbow_config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_predicated_add_u32(uint8_t *accu_b, uint8_t predicate, const uint8_t *a, unsigned _num_byte);
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_add_u32(uint8_t *accu_b, const uint8_t *a, unsigned _num_byte);
|
||||
|
||||
#ifdef _USE_GF16
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_madd_u32(uint8_t *accu_c, const uint8_t *a, uint8_t gf16_b, unsigned _num_byte);
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_scalar_u32(uint8_t *a, uint8_t gf16_b, unsigned _num_byte);
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_dot_u32(const uint8_t *a, const uint8_t *b, unsigned _num_byte);
|
||||
|
||||
#else
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_scalar_u32(uint8_t *a, uint8_t b, unsigned _num_byte);
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_madd_u32(uint8_t *accu_c, const uint8_t *a, uint8_t gf256_b, unsigned _num_byte);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _BLAS_U32_H_
|
||||
|
202
crypto_sign/rainbowIa-cyclic/clean/gf.c
Normal file
202
crypto_sign/rainbowIa-cyclic/clean/gf.c
Normal file
@ -0,0 +1,202 @@
|
||||
#include "gf.h"
|
||||
|
||||
static inline uint8_t gf256v_reduce_u32(uint32_t a) {
|
||||
// https://godbolt.org/z/7hirMb
|
||||
uint16_t *aa = (uint16_t *) (&a);
|
||||
uint16_t r = aa[0] ^ aa[1];
|
||||
uint8_t *rr = (uint8_t *) (&r);
|
||||
return rr[0] ^ rr[1];
|
||||
}
|
||||
|
||||
#ifdef _USE_GF16
|
||||
//// gf4 := gf2[x]/x^2+x+1
|
||||
static inline uint8_t gf4_mul_2(uint8_t a) {
|
||||
uint8_t r = (uint8_t) (a << 1);
|
||||
r ^= (uint8_t) ((a >> 1) * 7);
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline uint8_t gf4_mul_3(uint8_t a) {
|
||||
uint8_t msk = (uint8_t) (a - 2) >> 1;
|
||||
return (uint8_t)((msk & (a * 3)) | ((~msk) & (a - 1)));
|
||||
}
|
||||
|
||||
static inline uint8_t gf4_mul(uint8_t a, uint8_t b) {
|
||||
uint8_t r = (uint8_t) (a * (b & 1));
|
||||
return r ^ (uint8_t)(gf4_mul_2(a) * (b >> 1));
|
||||
}
|
||||
|
||||
static inline uint8_t gf4_squ(uint8_t a) {
|
||||
return a ^ (a >> 1);
|
||||
}
|
||||
|
||||
static inline uint32_t gf4v_mul_2_u32(uint32_t a) {
|
||||
uint32_t bit0 = a & 0x55555555;
|
||||
uint32_t bit1 = a & 0xaaaaaaaa;
|
||||
return (bit0 << 1) ^ bit1 ^ (bit1 >> 1);
|
||||
}
|
||||
|
||||
static inline uint32_t gf4v_mul_3_u32(uint32_t a) {
|
||||
uint32_t bit0 = a & 0x55555555;
|
||||
uint32_t bit1 = a & 0xaaaaaaaa;
|
||||
return (bit0 << 1) ^ bit0 ^ (bit1 >> 1);
|
||||
}
|
||||
|
||||
static inline uint32_t gf4v_mul_u32(uint32_t a, uint8_t b) {
|
||||
uint32_t bit0_b = ((uint32_t) 0) - ((uint32_t)(b & 1));
|
||||
uint32_t bit1_b = ((uint32_t) 0) - ((uint32_t)((b >> 1) & 1));
|
||||
return (a & bit0_b) ^ (bit1_b & gf4v_mul_2_u32(a));
|
||||
}
|
||||
|
||||
static inline uint32_t _gf4v_mul_u32_u32(uint32_t a0, uint32_t a1, uint32_t b0, uint32_t b1) {
|
||||
uint32_t c0 = a0 & b0;
|
||||
uint32_t c2 = a1 & b1;
|
||||
uint32_t c1_ = (a0 ^ a1) & (b0 ^ b1);
|
||||
return ((c1_ ^ c0) << 1) ^ c0 ^ c2;
|
||||
}
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_is_nonzero(uint8_t a) {
|
||||
unsigned a4 = a & 0xf;
|
||||
unsigned r = ((unsigned) 0) - a4;
|
||||
r >>= 4;
|
||||
return r & 1;
|
||||
}
|
||||
|
||||
//// gf16 := gf4[y]/y^2+y+x
|
||||
static inline uint8_t gf16_mul(uint8_t a, uint8_t b) {
|
||||
uint8_t a0 = a & 3;
|
||||
uint8_t a1 = (a >> 2);
|
||||
uint8_t b0 = b & 3;
|
||||
uint8_t b1 = (b >> 2);
|
||||
uint8_t a0b0 = gf4_mul(a0, b0);
|
||||
uint8_t a1b1 = gf4_mul(a1, b1);
|
||||
uint8_t a0b1_a1b0 = gf4_mul(a0 ^ a1, b0 ^ b1) ^ a0b0 ^ a1b1;
|
||||
uint8_t a1b1_x2 = gf4_mul_2(a1b1);
|
||||
return (uint8_t) ((a0b1_a1b0 ^ a1b1) << 2 ^ a0b0 ^ a1b1_x2);
|
||||
}
|
||||
|
||||
static inline uint8_t gf16_squ(uint8_t a) {
|
||||
uint8_t a0 = a & 3;
|
||||
uint8_t a1 = (a >> 2);
|
||||
a1 = gf4_squ(a1);
|
||||
uint8_t a1squ_x2 = gf4_mul_2(a1);
|
||||
return (uint8_t)((a1 << 2) ^ a1squ_x2 ^ gf4_squ(a0));
|
||||
}
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_inv(uint8_t a) {
|
||||
uint8_t a2 = gf16_squ(a);
|
||||
uint8_t a4 = gf16_squ(a2);
|
||||
uint8_t a8 = gf16_squ(a4);
|
||||
uint8_t a6 = gf16_mul(a4, a2);
|
||||
return gf16_mul(a8, a6);
|
||||
}
|
||||
|
||||
static inline uint8_t gf16_mul_8(uint8_t a) {
|
||||
uint8_t a0 = a & 3;
|
||||
uint8_t a1 = a >> 2;
|
||||
return (uint8_t)(gf4_mul_2(a0 ^ a1) << 2 | gf4_mul_3(a1));
|
||||
}
|
||||
|
||||
// gf16 := gf4[y]/y^2+y+x
|
||||
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(uint32_t a, uint8_t b) {
|
||||
uint32_t axb0 = gf4v_mul_u32(a, b);
|
||||
uint32_t axb1 = gf4v_mul_u32(a, b >> 2);
|
||||
uint32_t a0b1 = (axb1 << 2) & 0xcccccccc;
|
||||
uint32_t a1b1 = axb1 & 0xcccccccc;
|
||||
uint32_t a1b1_2 = a1b1 >> 2;
|
||||
|
||||
return axb0 ^ a0b1 ^ a1b1 ^ gf4v_mul_2_u32(a1b1_2);
|
||||
}
|
||||
|
||||
static inline uint32_t _gf16v_mul_u32_u32(uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t b0, uint32_t b1, uint32_t b2, uint32_t b3) {
|
||||
uint32_t c0 = _gf4v_mul_u32_u32(a0, a1, b0, b1);
|
||||
uint32_t c1_ = _gf4v_mul_u32_u32(a0 ^ a2, a1 ^ a3, b0 ^ b2, b1 ^ b3);
|
||||
|
||||
uint32_t c2_0 = a2 & b2;
|
||||
uint32_t c2_2 = a3 & b3;
|
||||
uint32_t c2_1_ = (a2 ^ a3) & (b2 ^ b3);
|
||||
uint32_t c2_r0 = c2_0 ^ c2_2;
|
||||
uint32_t c2_r1 = c2_0 ^ c2_1_;
|
||||
// GF(4) x2: (bit0<<1)^bit1^(bit1>>1);
|
||||
return ((c1_ ^ c0) << 2) ^ c0 ^ (c2_r0 << 1) ^ c2_r1 ^ (c2_r1 << 1);
|
||||
}
|
||||
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32_u32(uint32_t a, uint32_t b) {
|
||||
uint32_t a0 = a & 0x11111111;
|
||||
uint32_t a1 = (a >> 1) & 0x11111111;
|
||||
uint32_t a2 = (a >> 2) & 0x11111111;
|
||||
uint32_t a3 = (a >> 3) & 0x11111111;
|
||||
uint32_t b0 = b & 0x11111111;
|
||||
uint32_t b1 = (b >> 1) & 0x11111111;
|
||||
uint32_t b2 = (b >> 2) & 0x11111111;
|
||||
uint32_t b3 = (b >> 3) & 0x11111111;
|
||||
|
||||
return _gf16v_mul_u32_u32(a0, a1, a2, a3, b0, b1, b2, b3);
|
||||
}
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_reduce_u32(uint32_t a) {
|
||||
uint8_t r256 = gf256v_reduce_u32(a);
|
||||
return (uint8_t)((r256 & 0xf) ^ (r256 >> 4));
|
||||
}
|
||||
|
||||
static inline uint32_t gf16v_mul_8_u32(uint32_t a) {
|
||||
uint32_t a1 = a & 0xcccccccc;
|
||||
uint32_t a0 = (a << 2) & 0xcccccccc;
|
||||
return gf4v_mul_2_u32(a0 ^ a1) | gf4v_mul_3_u32(a1 >> 2);
|
||||
}
|
||||
|
||||
#else
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_is_nonzero(uint8_t a) {
|
||||
unsigned a8 = a;
|
||||
unsigned r = ((unsigned) 0) - a8;
|
||||
r >>= 8;
|
||||
return r & 1;
|
||||
}
|
||||
|
||||
// gf256 := gf16[X]/X^2+X+xy
|
||||
static inline uint8_t gf256_mul(uint8_t a, uint8_t b) {
|
||||
uint8_t a0 = a & 15;
|
||||
uint8_t a1 = (a >> 4);
|
||||
uint8_t b0 = b & 15;
|
||||
uint8_t b1 = (b >> 4);
|
||||
uint8_t a0b0 = gf16_mul(a0, b0);
|
||||
uint8_t a1b1 = gf16_mul(a1, b1);
|
||||
uint8_t a0b1_a1b0 = gf16_mul(a0 ^ a1, b0 ^ b1) ^ a0b0 ^ a1b1;
|
||||
uint8_t a1b1_x8 = gf16_mul_8(a1b1);
|
||||
return (uint8_t)((a0b1_a1b0 ^ a1b1) << 4 ^ a0b0 ^ a1b1_x8);
|
||||
}
|
||||
|
||||
static inline uint8_t gf256_squ(uint8_t a) {
|
||||
uint8_t a0 = a & 15;
|
||||
uint8_t a1 = (a >> 4);
|
||||
a1 = gf16_squ(a1);
|
||||
uint8_t a1squ_x8 = gf16_mul_8(a1);
|
||||
return (uint8_t)((a1 << 4) ^ a1squ_x8 ^ gf16_squ(a0));
|
||||
}
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_inv(uint8_t a) {
|
||||
// 128+64+32+16+8+4+2 = 254
|
||||
uint8_t a2 = gf256_squ(a);
|
||||
uint8_t a4 = gf256_squ(a2);
|
||||
uint8_t a8 = gf256_squ(a4);
|
||||
uint8_t a4_2 = gf256_mul(a4, a2);
|
||||
uint8_t a8_4_2 = gf256_mul(a4_2, a8);
|
||||
uint8_t a64_ = gf256_squ(a8_4_2);
|
||||
a64_ = gf256_squ(a64_);
|
||||
a64_ = gf256_squ(a64_);
|
||||
uint8_t a64_2 = gf256_mul(a64_, a8_4_2);
|
||||
uint8_t a128_ = gf256_squ(a64_2);
|
||||
return gf256_mul(a2, a128_);
|
||||
}
|
||||
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(uint32_t a, uint8_t b) {
|
||||
uint32_t axb0 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(a, b);
|
||||
uint32_t axb1 = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(a, b >> 4);
|
||||
uint32_t a0b1 = (axb1 << 4) & 0xf0f0f0f0;
|
||||
uint32_t a1b1 = axb1 & 0xf0f0f0f0;
|
||||
uint32_t a1b1_4 = a1b1 >> 4;
|
||||
|
||||
return axb0 ^ a0b1 ^ a1b1 ^ gf16v_mul_8_u32(a1b1_4);
|
||||
}
|
||||
#endif
|
28
crypto_sign/rainbowIa-cyclic/clean/gf.h
Normal file
28
crypto_sign/rainbowIa-cyclic/clean/gf.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _GF16_H_
|
||||
#define _GF16_H_
|
||||
|
||||
#include "rainbow_config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/// @file gf16.h
|
||||
/// @brief Library for arithmetics in GF(16) and GF(256)
|
||||
///
|
||||
|
||||
|
||||
#ifdef _USE_GF16
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_is_nonzero(uint8_t a);
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16_inv(uint8_t a);
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32(uint32_t a, uint8_t b);
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_u32_u32(uint32_t a, uint32_t b);
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_reduce_u32(uint32_t a);
|
||||
|
||||
#else
|
||||
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_is_nonzero(uint8_t a);
|
||||
uint8_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256_inv(uint8_t a);
|
||||
uint32_t PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_mul_u32(uint32_t a, uint8_t b);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _GF16_H_
|
321
crypto_sign/rainbowIa-cyclic/clean/parallel_matrix_op.c
Normal file
321
crypto_sign/rainbowIa-cyclic/clean/parallel_matrix_op.c
Normal file
@ -0,0 +1,321 @@
|
||||
/// @file parallel_matrix_op.c
|
||||
/// @brief the standard implementations for functions in parallel_matrix_op.h
|
||||
///
|
||||
/// the standard implementations for functions in parallel_matrix_op.h
|
||||
///
|
||||
|
||||
#include "blas.h"
|
||||
#include "blas_comm.h"
|
||||
#include "parallel_matrix_op.h"
|
||||
|
||||
///
|
||||
/// @brief Calculate the corresponding index in an array for an upper-triangle(UT) matrix.
|
||||
///
|
||||
/// @param[in] i_row - the i-th row in an upper-triangle matrix.
|
||||
/// @param[in] j_col - the j-th column in an upper-triangle matrix.
|
||||
/// @param[in] dim - the dimension of the upper-triangle matrix, i.e., an dim x dim matrix.
|
||||
/// @return the corresponding index in an array storage.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat( unsigned i_row, unsigned j_col, unsigned dim ) {
|
||||
return (dim + dim - i_row + 1 ) * i_row / 2 + j_col - i_row;
|
||||
}
|
||||
|
||||
///
|
||||
/// @brief Calculate the corresponding index in an array for an upper-triangle or lower-triangle matrix.
|
||||
///
|
||||
/// @param[in] i_row - the i-th row in a triangle matrix.
|
||||
/// @param[in] j_col - the j-th column in a triangle matrix.
|
||||
/// @param[in] dim - the dimension of the triangle matrix, i.e., an dim x dim matrix.
|
||||
/// @return the corresponding index in an array storage.
|
||||
///
|
||||
static inline
|
||||
unsigned idx_of_2trimat( unsigned i_row, unsigned j_col, unsigned n_var ) {
|
||||
if ( i_row > j_col ) {
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(j_col, i_row, n_var);
|
||||
}
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i_row, j_col, n_var);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( unsigned char *btriC, const unsigned char *bA, unsigned Awidth, unsigned size_batch ) {
|
||||
unsigned char *runningC = btriC;
|
||||
unsigned Aheight = Awidth;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < i; j++) {
|
||||
unsigned idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(j, i, Aheight);
|
||||
gf256v_add( btriC + idx * size_batch, bA + size_batch * (i * Awidth + j), size_batch );
|
||||
}
|
||||
gf256v_add( runningC, bA + size_batch * (i * Awidth + i), size_batch * (Aheight - i) );
|
||||
runningC += size_batch * (Aheight - i);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _USE_GF16
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimat_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Awidth = Bheight;
|
||||
unsigned Aheight = Awidth;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (k < i) {
|
||||
continue;
|
||||
}
|
||||
gf16v_madd( bC, & btriA[ (k - i)*size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
btriA += (Aheight - i) * size_batch;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimatTr_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Aheight = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (i < k) {
|
||||
continue;
|
||||
}
|
||||
gf16v_madd( bC, & btriA[ size_batch * (PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(k, i, Aheight)) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_2trimat_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Aheight = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (i == k) {
|
||||
continue;
|
||||
}
|
||||
gf16v_madd( bC, & btriA[ size_batch * (idx_of_2trimat(i, k, Aheight)) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_matTr_madd_gf16( unsigned char *bC, const unsigned char *A_to_tr, unsigned Aheight, unsigned size_Acolvec, unsigned Awidth,
|
||||
const unsigned char *bB, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Atr_height = Awidth;
|
||||
unsigned Atr_width = Aheight;
|
||||
for (unsigned i = 0; i < Atr_height; i++) {
|
||||
for (unsigned j = 0; j < Atr_width; j++) {
|
||||
gf16v_madd( bC, & bB[ j * Bwidth * size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &A_to_tr[size_Acolvec * i], j ), size_batch * Bwidth );
|
||||
}
|
||||
bC += size_batch * Bwidth;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_bmatTr_madd_gf16( unsigned char *bC, const unsigned char *bA_to_tr, unsigned Awidth_before_tr,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
const unsigned char *bA = bA_to_tr;
|
||||
unsigned Aheight = Awidth_before_tr;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
gf16v_madd( bC, & bA[ size_batch * (i + k * Aheight) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_mat_madd_gf16( unsigned char *bC, const unsigned char *bA, unsigned Aheight,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Awidth = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
gf16v_madd( bC, & bA[ k * size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
bA += (Awidth) * size_batch;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_recmat_eval_gf16( unsigned char *z, const unsigned char *y, unsigned dim_y, const unsigned char *mat,
|
||||
const unsigned char *x, unsigned dim_x, unsigned size_batch ) {
|
||||
unsigned char tmp[128];
|
||||
|
||||
unsigned char _x[128];
|
||||
for (unsigned i = 0; i < dim_x; i++) {
|
||||
_x[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( x, i );
|
||||
}
|
||||
unsigned char _y[128];
|
||||
for (unsigned i = 0; i < dim_y; i++) {
|
||||
_y[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( y, i );
|
||||
}
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( z, size_batch );
|
||||
for (unsigned i = 0; i < dim_y; i++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( tmp, size_batch );
|
||||
for (unsigned j = 0; j < dim_x; j++) {
|
||||
gf16v_madd( tmp, mat, _x[j], size_batch );
|
||||
mat += size_batch;
|
||||
}
|
||||
gf16v_madd( z, tmp, _y[i], size_batch );
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_trimat_eval_gf16( unsigned char *y, const unsigned char *trimat, const unsigned char *x, unsigned dim, unsigned size_batch ) {
|
||||
unsigned char tmp[256];
|
||||
|
||||
unsigned char _x[256];
|
||||
for (unsigned i = 0; i < dim; i++) {
|
||||
_x[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele( x, i );
|
||||
}
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( y, size_batch );
|
||||
for (unsigned i = 0; i < dim; i++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( tmp, size_batch );
|
||||
for (unsigned j = i; j < dim; j++) {
|
||||
gf16v_madd( tmp, trimat, _x[j], size_batch );
|
||||
trimat += size_batch;
|
||||
}
|
||||
gf16v_madd( y, tmp, _x[i], size_batch );
|
||||
}
|
||||
}
|
||||
#else
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimat_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Awidth = Bheight;
|
||||
unsigned Aheight = Awidth;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (k < i) {
|
||||
continue;
|
||||
}
|
||||
gf256v_madd( bC, & btriA[ (k - i)*size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
btriA += (Aheight - i) * size_batch;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimatTr_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Aheight = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (i < k) {
|
||||
continue;
|
||||
}
|
||||
gf256v_madd( bC, & btriA[ size_batch * (PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(k, i, Aheight)) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_2trimat_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Aheight = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
if (i == k) {
|
||||
continue;
|
||||
}
|
||||
gf256v_madd( bC, & btriA[ size_batch * (idx_of_2trimat(i, k, Aheight)) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_matTr_madd_gf256( unsigned char *bC, const unsigned char *A_to_tr, unsigned Aheight, unsigned size_Acolvec, unsigned Awidth,
|
||||
const unsigned char *bB, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Atr_height = Awidth;
|
||||
unsigned Atr_width = Aheight;
|
||||
for (unsigned i = 0; i < Atr_height; i++) {
|
||||
for (unsigned j = 0; j < Atr_width; j++) {
|
||||
gf256v_madd( bC, & bB[ j * Bwidth * size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &A_to_tr[size_Acolvec * i], j ), size_batch * Bwidth );
|
||||
}
|
||||
bC += size_batch * Bwidth;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_bmatTr_madd_gf256( unsigned char *bC, const unsigned char *bA_to_tr, unsigned Awidth_before_tr,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
const unsigned char *bA = bA_to_tr;
|
||||
unsigned Aheight = Awidth_before_tr;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
gf256v_madd( bC, & bA[ size_batch * (i + k * Aheight) ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_mat_madd_gf256( unsigned char *bC, const unsigned char *bA, unsigned Aheight,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch ) {
|
||||
unsigned Awidth = Bheight;
|
||||
for (unsigned i = 0; i < Aheight; i++) {
|
||||
for (unsigned j = 0; j < Bwidth; j++) {
|
||||
for (unsigned k = 0; k < Bheight; k++) {
|
||||
gf256v_madd( bC, & bA[ k * size_batch ], PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( &B[j * size_Bcolvec], k ), size_batch );
|
||||
}
|
||||
bC += size_batch;
|
||||
}
|
||||
bA += (Awidth) * size_batch;
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_trimat_eval_gf256( unsigned char *y, const unsigned char *trimat, const unsigned char *x, unsigned dim, unsigned size_batch ) {
|
||||
unsigned char tmp[256];
|
||||
|
||||
unsigned char _x[256];
|
||||
for (unsigned i = 0; i < dim; i++) {
|
||||
_x[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( x, i );
|
||||
}
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( y, size_batch );
|
||||
for (unsigned i = 0; i < dim; i++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( tmp, size_batch );
|
||||
for (unsigned j = i; j < dim; j++) {
|
||||
gf256v_madd( tmp, trimat, _x[j], size_batch );
|
||||
trimat += size_batch;
|
||||
}
|
||||
gf256v_madd( y, tmp, _x[i], size_batch );
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_recmat_eval_gf256( unsigned char *z, const unsigned char *y, unsigned dim_y, const unsigned char *mat,
|
||||
const unsigned char *x, unsigned dim_x, unsigned size_batch ) {
|
||||
unsigned char tmp[128];
|
||||
|
||||
unsigned char _x[128];
|
||||
for (unsigned i = 0; i < dim_x; i++) {
|
||||
_x[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( x, i );
|
||||
}
|
||||
unsigned char _y[128];
|
||||
for (unsigned i = 0; i < dim_y; i++) {
|
||||
_y[i] = PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_get_ele( y, i );
|
||||
}
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( z, size_batch );
|
||||
for (unsigned i = 0; i < dim_y; i++) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( tmp, size_batch );
|
||||
for (unsigned j = 0; j < dim_x; j++) {
|
||||
gf256v_madd( tmp, mat, _x[j], size_batch );
|
||||
mat += size_batch;
|
||||
}
|
||||
gf256v_madd( z, tmp, _y[i], size_batch );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
282
crypto_sign/rainbowIa-cyclic/clean/parallel_matrix_op.h
Normal file
282
crypto_sign/rainbowIa-cyclic/clean/parallel_matrix_op.h
Normal file
@ -0,0 +1,282 @@
|
||||
#ifndef _P_MATRIX_OP_H_
|
||||
#define _P_MATRIX_OP_H_
|
||||
/// @file parallel_matrix_op.h
|
||||
/// @brief Librarys for operations of batched matrixes.
|
||||
///
|
||||
///
|
||||
|
||||
//////////////// Section: triangle matrix <-> rectangle matrix ///////////////////////////////////
|
||||
|
||||
|
||||
///
|
||||
/// @brief Calculate the corresponding index in an array for an upper-triangle(UT) matrix.
|
||||
///
|
||||
/// @param[in] i_row - the i-th row in an upper-triangle matrix.
|
||||
/// @param[in] j_col - the j-th column in an upper-triangle matrix.
|
||||
/// @param[in] dim - the dimension of the upper-triangle matrix, i.e., an dim x dim matrix.
|
||||
/// @return the corresponding index in an array storage.
|
||||
///
|
||||
unsigned PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat( unsigned i_row, unsigned j_col, unsigned dim );
|
||||
|
||||
///
|
||||
/// @brief Upper trianglize a rectangle matrix to the corresponding upper-trangle matrix.
|
||||
///
|
||||
/// @param[out] btriC - the batched upper-trianglized matrix C.
|
||||
/// @param[in] bA - a batched retangle matrix A.
|
||||
/// @param[in] bwidth - the width of the batched matrix A, i.e., A is a Awidth x Awidth matrix.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( unsigned char *btriC, const unsigned char *bA, unsigned Awidth, unsigned size_batch );
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////// Section: matrix multiplications ///////////////////////////////
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief bC += btriA * B , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimat_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += btriA * B , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimat_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
|
||||
///
|
||||
/// @brief bC += btriA^Tr * B , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A. A will be transposed while multiplying.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimatTr_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += btriA^Tr * B , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A, which will be transposed while multiplying.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimatTr_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief bC += (btriA + btriA^Tr) *B , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A. The operand for multiplication is (btriA + btriA^Tr).
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_2trimat_madd_gf16( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += (btriA + btriA^Tr) *B , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] btriA - a batched UT matrix A. The operand for multiplication is (btriA + btriA^Tr).
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_2trimat_madd_gf256( unsigned char *bC, const unsigned char *btriA,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief bC += A^Tr * bB , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] A_to_tr - a column-major matrix A. The operand for multiplication is A^Tr.
|
||||
/// @param[in] Aheight - the height of A.
|
||||
/// @param[in] size_Acolvec - the size of a column vector in A.
|
||||
/// @param[in] Awidth - the width of A.
|
||||
/// @param[in] bB - a batched matrix B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_matTr_madd_gf16( unsigned char *bC,
|
||||
const unsigned char *A_to_tr, unsigned Aheight, unsigned size_Acolvec, unsigned Awidth,
|
||||
const unsigned char *bB, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += A^Tr * bB , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] A_to_tr - a column-major matrix A. The operand for multiplication is A^Tr.
|
||||
/// @param[in] Aheight - the height of A.
|
||||
/// @param[in] size_Acolvec - the size of a column vector in A.
|
||||
/// @param[in] Awidth - the width of A.
|
||||
/// @param[in] bB - a batched matrix B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_matTr_madd_gf256( unsigned char *bC,
|
||||
const unsigned char *A_to_tr, unsigned Aheight, unsigned size_Acolvec, unsigned Awidth,
|
||||
const unsigned char *bB, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
|
||||
///
|
||||
/// @brief bC += bA^Tr * B , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] bA_to_tr - a batched matrix A. The operand for multiplication is (bA^Tr).
|
||||
/// @param[in] Awidth_befor_tr - the width of A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_bmatTr_madd_gf16( unsigned char *bC, const unsigned char *bA_to_tr, unsigned Awidth_before_tr,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += bA^Tr * B , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] bA_to_tr - a batched matrix A. The operand for multiplication is (bA^Tr).
|
||||
/// @param[in] Awidth_befor_tr - the width of A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_bmatTr_madd_gf256( unsigned char *bC, const unsigned char *bA_to_tr, unsigned Awidth_before_tr,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += bA * B , in GF(16)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] bA - a batched matrix A.
|
||||
/// @param[in] Aheigh - the height of A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_mat_madd_gf16( unsigned char *bC, const unsigned char *bA, unsigned Aheight,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief bC += bA * B , in GF(256)
|
||||
///
|
||||
/// @param[out] bC - the batched matrix C.
|
||||
/// @param[in] bA - a batched matrix A.
|
||||
/// @param[in] Aheigh - the height of A.
|
||||
/// @param[in] B - a column-major matrix B.
|
||||
/// @param[in] Bheight - the height of B.
|
||||
/// @param[in] size_Bcolvec - the size of the column vector in B.
|
||||
/// @param[in] Bwidth - the width of B.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_mat_madd_gf256( unsigned char *bC, const unsigned char *bA, unsigned Aheight,
|
||||
const unsigned char *B, unsigned Bheight, unsigned size_Bcolvec, unsigned Bwidth, unsigned size_batch );
|
||||
|
||||
|
||||
|
||||
//////////////////// Section: "quadratric" matrix evaluation ///////////////////////////////
|
||||
|
||||
|
||||
///
|
||||
/// @brief y = x^Tr * trimat * x , in GF(16)
|
||||
///
|
||||
/// @param[out] y - the returned batched element y.
|
||||
/// @param[in] trimat - a batched matrix.
|
||||
/// @param[in] x - an input vector x.
|
||||
/// @param[in] dim - the dimension of matrix trimat (and x).
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_trimat_eval_gf16( unsigned char *y, const unsigned char *trimat, const unsigned char *x, unsigned dim, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief y = x^Tr * trimat * x , in GF(256)
|
||||
///
|
||||
/// @param[out] y - the returned batched element y.
|
||||
/// @param[in] trimat - a batched matrix.
|
||||
/// @param[in] x - an input vector x.
|
||||
/// @param[in] dim - the dimension of matrix trimat (and x).
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_trimat_eval_gf256( unsigned char *y, const unsigned char *trimat, const unsigned char *x, unsigned dim, unsigned size_batch );
|
||||
|
||||
|
||||
///
|
||||
/// @brief z = y^Tr * mat * x , in GF(16)
|
||||
///
|
||||
/// @param[out] z - the returned batched element z.
|
||||
/// @param[in] y - an input vector y.
|
||||
/// @param[in] dim_y - the length of y.
|
||||
/// @param[in] mat - a batched matrix.
|
||||
/// @param[in] x - an input vector x.
|
||||
/// @param[in] dim_x - the length of x.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_recmat_eval_gf16( unsigned char *z, const unsigned char *y, unsigned dim_y,
|
||||
const unsigned char *mat, const unsigned char *x, unsigned dim_x, unsigned size_batch );
|
||||
|
||||
///
|
||||
/// @brief z = y^Tr * mat * x , in GF(256)
|
||||
///
|
||||
/// @param[out] z - the returned batched element z.
|
||||
/// @param[in] y - an input vector y.
|
||||
/// @param[in] dim_y - the length of y.
|
||||
/// @param[in] mat - a batched matrix.
|
||||
/// @param[in] x - an input vector x.
|
||||
/// @param[in] dim_x - the length of x.
|
||||
/// @param[in] size_batch - number of the batched elements in the corresponding position of the matrix.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_recmat_eval_gf256( unsigned char *z, const unsigned char *y, unsigned dim_y,
|
||||
const unsigned char *mat, const unsigned char *x, unsigned dim_x, unsigned size_batch );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _P_MATRIX_OP_H_
|
||||
|
187
crypto_sign/rainbowIa-cyclic/clean/rainbow.c
Normal file
187
crypto_sign/rainbowIa-cyclic/clean/rainbow.c
Normal file
@ -0,0 +1,187 @@
|
||||
/// @file rainbow.c
|
||||
/// @brief The standard implementations for functions in rainbow.h
|
||||
///
|
||||
|
||||
#include "blas.h"
|
||||
#include "rainbow.h"
|
||||
#include "rainbow_blas.h"
|
||||
#include "rainbow_config.h"
|
||||
#include "rainbow_keypair.h"
|
||||
#include "utils_hash.h"
|
||||
#include "utils_prng.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define MAX_ATTEMPT_FRMAT 128
|
||||
#define _MAX_O ((_O1>_O2)?_O1:_O2)
|
||||
#define _MAX_O_BYTE ((_O1_BYTE>_O2_BYTE)?_O1_BYTE:_O2_BYTE)
|
||||
|
||||
#if defined(_RAINBOW_CLASSIC) || defined(_RAINBOW_CYCLIC)
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( uint8_t *signature, const sk_t *sk, const uint8_t *_digest ) {
|
||||
uint8_t mat_l1[_O1 * _O1_BYTE];
|
||||
uint8_t mat_l2[_O2 * _O2_BYTE];
|
||||
uint8_t mat_buffer[2 * _MAX_O * _MAX_O_BYTE];
|
||||
|
||||
// setup PRNG
|
||||
prng_t prng_sign;
|
||||
uint8_t prng_preseed[LEN_SKSEED + _HASH_LEN];
|
||||
memcpy( prng_preseed, sk->sk_seed, LEN_SKSEED );
|
||||
memcpy( prng_preseed + LEN_SKSEED, _digest, _HASH_LEN ); // prng_preseed = sk_seed || digest
|
||||
uint8_t prng_seed[_HASH_LEN];
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( prng_seed, _HASH_LEN, prng_preseed, _HASH_LEN + LEN_SKSEED );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( &prng_sign, prng_seed, _HASH_LEN ); // seed = H( sk_seed || digest )
|
||||
for (unsigned i = 0; i < LEN_SKSEED + _HASH_LEN; i++) {
|
||||
prng_preseed[i] ^= prng_preseed[i]; // clean
|
||||
}
|
||||
for (unsigned i = 0; i < _HASH_LEN; i++) {
|
||||
prng_seed[i] ^= prng_seed[i]; // clean
|
||||
}
|
||||
|
||||
// roll vinegars.
|
||||
uint8_t vinegar[_V1_BYTE];
|
||||
unsigned n_attempt = 0;
|
||||
unsigned l1_succ = 0;
|
||||
while ( !l1_succ ) {
|
||||
if ( MAX_ATTEMPT_FRMAT <= n_attempt ) {
|
||||
break;
|
||||
}
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( &prng_sign, vinegar, _V1_BYTE ); // generating vinegars
|
||||
gfmat_prod( mat_l1, sk->l1_F2, _O1 * _O1_BYTE, _V1, vinegar ); // generating the linear equations for layer 1
|
||||
l1_succ = gfmat_inv( mat_l1, mat_l1, _O1, mat_buffer ); // check if the linear equation solvable
|
||||
n_attempt ++;
|
||||
}
|
||||
|
||||
// Given the vinegars, pre-compute variables needed for layer 2
|
||||
uint8_t r_l1_F1[_O1_BYTE] = {0};
|
||||
uint8_t r_l2_F1[_O2_BYTE] = {0};
|
||||
batch_quad_trimat_eval( r_l1_F1, sk->l1_F1, vinegar, _V1, _O1_BYTE );
|
||||
batch_quad_trimat_eval( r_l2_F1, sk->l2_F1, vinegar, _V1, _O2_BYTE );
|
||||
uint8_t mat_l2_F3[ _O2 * _O2_BYTE];
|
||||
uint8_t mat_l2_F2[_O1 * _O2_BYTE];
|
||||
gfmat_prod( mat_l2_F3, sk->l2_F3, _O2 * _O2_BYTE, _V1, vinegar );
|
||||
gfmat_prod( mat_l2_F2, sk->l2_F2, _O1 * _O2_BYTE, _V1, vinegar );
|
||||
|
||||
// Some local variables.
|
||||
uint8_t _z[_PUB_M_BYTE];
|
||||
uint8_t y[_PUB_M_BYTE];
|
||||
uint8_t *x_v1 = vinegar;
|
||||
uint8_t x_o1[_O1_BYTE];
|
||||
uint8_t x_o2[_O1_BYTE];
|
||||
|
||||
uint8_t digest_salt[_HASH_LEN + _SALT_BYTE];
|
||||
memcpy( digest_salt, _digest, _HASH_LEN );
|
||||
uint8_t *salt = digest_salt + _HASH_LEN;
|
||||
|
||||
uint8_t temp_o[_MAX_O_BYTE + 32] = {0};
|
||||
unsigned succ = 0;
|
||||
while ( !succ ) {
|
||||
if ( MAX_ATTEMPT_FRMAT <= n_attempt ) {
|
||||
break;
|
||||
}
|
||||
// The computation: H(digest||salt) --> z --S--> y --C-map--> x --T--> w
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( &prng_sign, salt, _SALT_BYTE ); // roll the salt
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( _z, _PUB_M_BYTE, digest_salt, _HASH_LEN + _SALT_BYTE ); // H(digest||salt)
|
||||
|
||||
// y = S^-1 * z
|
||||
memcpy(y, _z, _PUB_M_BYTE); // identity part of S
|
||||
gfmat_prod(temp_o, sk->s1, _O1_BYTE, _O2, _z + _O1_BYTE);
|
||||
gf256v_add(y, temp_o, _O1_BYTE);
|
||||
|
||||
// Central Map:
|
||||
// layer 1: calculate x_o1
|
||||
memcpy( temp_o, r_l1_F1, _O1_BYTE );
|
||||
gf256v_add( temp_o, y, _O1_BYTE );
|
||||
gfmat_prod( x_o1, mat_l1, _O1_BYTE, _O1, temp_o );
|
||||
|
||||
// layer 2: calculate x_o2
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf256v_set_zero( temp_o, _O2_BYTE );
|
||||
gfmat_prod( temp_o, mat_l2_F2, _O2_BYTE, _O1, x_o1 ); // F2
|
||||
batch_quad_trimat_eval( mat_l2, sk->l2_F5, x_o1, _O1, _O2_BYTE ); // F5
|
||||
gf256v_add( temp_o, mat_l2, _O2_BYTE );
|
||||
gf256v_add( temp_o, r_l2_F1, _O2_BYTE ); // F1
|
||||
gf256v_add( temp_o, y + _O1_BYTE, _O2_BYTE );
|
||||
|
||||
// generate the linear equations of the 2nd layer
|
||||
gfmat_prod( mat_l2, sk->l2_F6, _O2 * _O2_BYTE, _O1, x_o1 ); // F6
|
||||
gf256v_add( mat_l2, mat_l2_F3, _O2 * _O2_BYTE); // F3
|
||||
succ = gfmat_inv( mat_l2, mat_l2, _O2, mat_buffer );
|
||||
gfmat_prod( x_o2, mat_l2, _O2_BYTE, _O2, temp_o ); // solve l2 eqs
|
||||
|
||||
n_attempt ++;
|
||||
};
|
||||
// w = T^-1 * y
|
||||
uint8_t w[_PUB_N_BYTE];
|
||||
// identity part of T.
|
||||
memcpy( w, x_v1, _V1_BYTE );
|
||||
memcpy( w + _V1_BYTE, x_o1, _O1_BYTE );
|
||||
memcpy( w + _V2_BYTE, x_o2, _O2_BYTE );
|
||||
// Computing the t1 part.
|
||||
gfmat_prod(y, sk->t1, _V1_BYTE, _O1, x_o1 );
|
||||
gf256v_add(w, y, _V1_BYTE );
|
||||
// Computing the t4 part.
|
||||
gfmat_prod(y, sk->t4, _V1_BYTE, _O2, x_o2 );
|
||||
gf256v_add(w, y, _V1_BYTE );
|
||||
// Computing the t3 part.
|
||||
gfmat_prod(y, sk->t3, _O1_BYTE, _O2, x_o2 );
|
||||
gf256v_add(w + _V1_BYTE, y, _O1_BYTE );
|
||||
|
||||
memset( signature, 0, _SIGNATURE_BYTE ); // set the output 0
|
||||
// clean
|
||||
memset( &prng_sign, 0, sizeof(prng_t) );
|
||||
memset( vinegar, 0, _V1_BYTE );
|
||||
memset( r_l1_F1, 0, _O1_BYTE );
|
||||
memset( r_l2_F1, 0, _O2_BYTE );
|
||||
memset( _z, 0, _PUB_M_BYTE );
|
||||
memset( y, 0, _PUB_M_BYTE );
|
||||
memset( x_o1, 0, _O1_BYTE );
|
||||
memset( x_o2, 0, _O2_BYTE );
|
||||
memset( temp_o, 0, sizeof(temp_o) );
|
||||
|
||||
// return: copy w and salt to the signature.
|
||||
if ( MAX_ATTEMPT_FRMAT <= n_attempt ) {
|
||||
return -1;
|
||||
}
|
||||
gf256v_add( signature, w, _PUB_N_BYTE );
|
||||
gf256v_add( signature + _PUB_N_BYTE, salt, _SALT_BYTE );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify( const uint8_t *digest, const uint8_t *signature, const pk_t *pk ) {
|
||||
unsigned char digest_ck[_PUB_M_BYTE];
|
||||
// public_map( digest_ck , pk , signature ); Evaluating the quadratic public polynomials.
|
||||
batch_quad_trimat_eval( digest_ck, pk->pk, signature, _PUB_N, _PUB_M_BYTE );
|
||||
|
||||
unsigned char correct[_PUB_M_BYTE];
|
||||
unsigned char digest_salt[_HASH_LEN + _SALT_BYTE];
|
||||
memcpy( digest_salt, digest, _HASH_LEN );
|
||||
memcpy( digest_salt + _HASH_LEN, signature + _PUB_N_BYTE, _SALT_BYTE );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( correct, _PUB_M_BYTE, digest_salt, _HASH_LEN + _SALT_BYTE ); // H( digest || salt )
|
||||
|
||||
// check consistancy.
|
||||
unsigned char cc = 0;
|
||||
for (unsigned i = 0; i < _PUB_M_BYTE; i++) {
|
||||
cc |= (digest_ck[i] ^ correct[i]);
|
||||
}
|
||||
return (0 == cc) ? 0 : -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _RAINBOW_CYCLIC_COMPRESSED
|
||||
/////////////// cyclic version ///////////////////////////
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign_cyclic( uint8_t *signature, const csk_t *csk, const uint8_t *digest ) {
|
||||
unsigned char sk[sizeof(sk_t) + 32];
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_secretkey_cyclic((sk_t *)sk, csk->pk_seed, csk->sk_seed ); // generating classic secret key.
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( signature, (sk_t *) sk, digest );
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( const uint8_t *digest, const uint8_t *signature, const cpk_t *_pk ) {
|
||||
unsigned char pk[sizeof(pk_t) +32];
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_cpk_to_pk( (pk_t *)pk, _pk ); // generating classic public key.
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify( digest, signature, (pk_t *)pk );
|
||||
}
|
||||
#endif
|
57
crypto_sign/rainbowIa-cyclic/clean/rainbow.h
Normal file
57
crypto_sign/rainbowIa-cyclic/clean/rainbow.h
Normal file
@ -0,0 +1,57 @@
|
||||
#ifndef _RAINBOW_H_
|
||||
#define _RAINBOW_H_
|
||||
/// @file rainbow.h
|
||||
/// @brief APIs for rainbow.
|
||||
///
|
||||
|
||||
|
||||
#include "rainbow_config.h"
|
||||
#include "rainbow_keypair.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(_RAINBOW_CLASSIC) || defined(_RAINBOW_CYCLIC)
|
||||
///
|
||||
/// @brief Signing function for classical secret key.
|
||||
///
|
||||
/// @param[out] signature - the signature.
|
||||
/// @param[in] sk - the secret key.
|
||||
/// @param[in] digest - the digest.
|
||||
///
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( uint8_t *signature, const sk_t *sk, const uint8_t *digest );
|
||||
|
||||
///
|
||||
/// @brief Verifying function.
|
||||
///
|
||||
/// @param[in] digest - the digest.
|
||||
/// @param[in] signature - the signature.
|
||||
/// @param[in] pk - the public key.
|
||||
/// @return 0 for successful verified. -1 for failed verification.
|
||||
///
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify( const uint8_t *digest, const uint8_t *signature, const pk_t *pk );
|
||||
#endif
|
||||
|
||||
#ifdef _RAINBOW_CYCLIC_COMPRESSED
|
||||
///
|
||||
/// @brief Signing function for compressed secret key of the cyclic rainbow.
|
||||
///
|
||||
/// @param[out] signature - the signature.
|
||||
/// @param[in] sk - the compressed secret key.
|
||||
/// @param[in] digest - the digest.
|
||||
///
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign_cyclic( uint8_t *signature, const csk_t *sk, const uint8_t *digest );
|
||||
#endif
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
///
|
||||
/// @brief Verifying function for cyclic public keys.
|
||||
///
|
||||
/// @param[in] digest - the digest.
|
||||
/// @param[in] signature - the signature.
|
||||
/// @param[in] pk - the public key of cyclic rainbow.
|
||||
/// @return 0 for successful verified. -1 for failed verification.
|
||||
///
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( const uint8_t *digest, const uint8_t *signature, const cpk_t *pk );
|
||||
#endif
|
||||
|
||||
#endif // _RAINBOW_H_
|
55
crypto_sign/rainbowIa-cyclic/clean/rainbow_blas.h
Normal file
55
crypto_sign/rainbowIa-cyclic/clean/rainbow_blas.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef _RAINBOW_BLAS_H_
|
||||
#define _RAINBOW_BLAS_H_
|
||||
/// @file rainbow_blas.h
|
||||
/// @brief Defining the functions used in rainbow.c acconding to the definitions in rainbow_config.h
|
||||
///
|
||||
/// Defining the functions used in rainbow.c acconding to the definitions in rainbow_config.h
|
||||
|
||||
|
||||
#include "blas.h"
|
||||
#include "parallel_matrix_op.h"
|
||||
#include "rainbow_config.h"
|
||||
|
||||
#ifdef _USE_GF16
|
||||
|
||||
#define gfv_get_ele PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_get_ele
|
||||
#define gfv_mul_scalar PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_mul_scalar
|
||||
#define gfv_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16v_madd
|
||||
|
||||
#define gfmat_prod PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_prod
|
||||
#define gfmat_inv PQCLEAN_RAINBOWIACYCLIC_CLEAN_gf16mat_inv
|
||||
|
||||
#define batch_trimat_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimat_madd_gf16
|
||||
#define batch_trimatTr_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_trimatTr_madd_gf16
|
||||
#define batch_2trimat_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_2trimat_madd_gf16
|
||||
#define batch_matTr_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_matTr_madd_gf16
|
||||
#define batch_bmatTr_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_bmatTr_madd_gf16
|
||||
#define batch_mat_madd PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_mat_madd_gf16
|
||||
|
||||
#define batch_quad_trimat_eval PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_trimat_eval_gf16
|
||||
#define batch_quad_recmat_eval PQCLEAN_RAINBOWIACYCLIC_CLEAN_batch_quad_recmat_eval_gf16
|
||||
|
||||
#else
|
||||
|
||||
#define gfv_get_ele gf256v_get_ele
|
||||
#define gfv_mul_scalar gf256v_mul_scalar
|
||||
#define gfv_madd gf256v_madd
|
||||
|
||||
#define gfmat_prod gf256mat_prod
|
||||
#define gfmat_inv gf256mat_inv
|
||||
|
||||
#define batch_trimat_madd batch_trimat_madd_gf256
|
||||
#define batch_trimatTr_madd batch_trimatTr_madd_gf256
|
||||
#define batch_2trimat_madd batch_2trimat_madd_gf256
|
||||
#define batch_matTr_madd batch_matTr_madd_gf256
|
||||
#define batch_bmatTr_madd batch_bmatTr_madd_gf256
|
||||
#define batch_mat_madd batch_mat_madd_gf256
|
||||
|
||||
#define batch_quad_trimat_eval batch_quad_trimat_eval_gf256
|
||||
#define batch_quad_recmat_eval batch_quad_recmat_eval_gf256
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _RAINBOW_BLAS_H_
|
||||
|
93
crypto_sign/rainbowIa-cyclic/clean/rainbow_config.h
Normal file
93
crypto_sign/rainbowIa-cyclic/clean/rainbow_config.h
Normal file
@ -0,0 +1,93 @@
|
||||
#ifndef _H_RAINBOW_CONFIG_H_
|
||||
#define _H_RAINBOW_CONFIG_H_
|
||||
|
||||
/// @file rainbow_config.h
|
||||
/// @brief Defining the parameters of the Rainbow and the corresponding constants.
|
||||
///
|
||||
|
||||
|
||||
|
||||
// TODO: refactor this
|
||||
/// the defined parameter
|
||||
#define _RAINBOW16_32_32_32
|
||||
//#define _RAINBOW256_68_36_36
|
||||
//#define _RAINBOW256_92_48_48
|
||||
|
||||
//#define _RAINBOW_CLASSIC
|
||||
#define _RAINBOW_CYCLIC
|
||||
//#define _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
|
||||
#if defined _RAINBOW16_32_32_32
|
||||
#define _USE_GF16
|
||||
#define _GFSIZE 16
|
||||
#define _V1 32
|
||||
#define _O1 32
|
||||
#define _O2 32
|
||||
#define _HASH_LEN 32
|
||||
|
||||
#elif defined _RAINBOW256_68_36_36
|
||||
#define _GFSIZE 256
|
||||
#define _V1 68
|
||||
#define _O1 36
|
||||
#define _O2 36
|
||||
#define _HASH_LEN 48
|
||||
|
||||
#elif defined _RAINBOW256_92_48_48
|
||||
#define _GFSIZE 256
|
||||
#define _V1 92
|
||||
#define _O1 48
|
||||
#define _O2 48
|
||||
#define _HASH_LEN 64
|
||||
|
||||
#else
|
||||
error here.
|
||||
#endif
|
||||
|
||||
|
||||
#define _V2 ((_V1)+(_O1))
|
||||
|
||||
/// size of N, in # of gf elements.
|
||||
#define _PUB_N (_V1+_O1+_O2)
|
||||
|
||||
/// size of M, in # gf elements.
|
||||
#define _PUB_M (_O1+_O2)
|
||||
|
||||
|
||||
/// size of variables, in # bytes.
|
||||
|
||||
|
||||
#ifdef _USE_GF16
|
||||
// GF16
|
||||
#define _V1_BYTE (_V1/2)
|
||||
#define _V2_BYTE (_V2/2)
|
||||
#define _O1_BYTE (_O1/2)
|
||||
#define _O2_BYTE (_O2/2)
|
||||
#define _PUB_N_BYTE (_PUB_N/2)
|
||||
#define _PUB_M_BYTE (_PUB_M/2)
|
||||
|
||||
#else
|
||||
// GF256
|
||||
#define _V1_BYTE (_V1)
|
||||
#define _V2_BYTE (_V2)
|
||||
#define _O1_BYTE (_O1)
|
||||
#define _O2_BYTE (_O2)
|
||||
#define _PUB_N_BYTE (_PUB_N)
|
||||
#define _PUB_M_BYTE (_PUB_M)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/// length of seed for public key, in # bytes
|
||||
#define LEN_PKSEED 32
|
||||
|
||||
/// length of seed for secret key, in # bytes
|
||||
#define LEN_SKSEED 32
|
||||
|
||||
/// length of salt for a signature, in # bytes
|
||||
#define _SALT_BYTE 16
|
||||
|
||||
/// length of a signature
|
||||
#define _SIGNATURE_BYTE (_PUB_N_BYTE + _SALT_BYTE )
|
||||
|
||||
#endif // _H_RAINBOW_CONFIG_H_
|
246
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair.c
Normal file
246
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair.c
Normal file
@ -0,0 +1,246 @@
|
||||
/// @file rainbow_keypair.c
|
||||
/// @brief implementations of functions in rainbow_keypair.h
|
||||
///
|
||||
|
||||
#include "blas.h"
|
||||
#include "blas_comm.h"
|
||||
#include "rainbow_blas.h"
|
||||
#include "rainbow_keypair.h"
|
||||
#include "rainbow_keypair_computation.h"
|
||||
#include "utils_prng.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static
|
||||
void generate_S_T( unsigned char *s_and_t, prng_t *prng0 ) {
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, s_and_t, _O1_BYTE * _O2 ); // S1
|
||||
s_and_t += _O1_BYTE * _O2;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, s_and_t, _V1_BYTE * _O1 ); // T1
|
||||
s_and_t += _V1_BYTE * _O1;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, s_and_t, _V1_BYTE * _O2 ); // T2
|
||||
s_and_t += _V1_BYTE * _O2;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, s_and_t, _O1_BYTE * _O2 ); // T3
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
unsigned generate_l1_F12( unsigned char *sk, prng_t *prng0 ) {
|
||||
unsigned n_byte_generated = 0;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O1_BYTE * N_TRIANGLE_TERMS(_V1) ); // l1_F1
|
||||
sk += _O1_BYTE * N_TRIANGLE_TERMS(_V1);
|
||||
n_byte_generated += _O1_BYTE * N_TRIANGLE_TERMS(_V1);
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O1_BYTE * _V1 * _O1 ); // l1_F2
|
||||
n_byte_generated += _O1_BYTE * _V1 * _O1;
|
||||
return n_byte_generated;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
unsigned generate_l2_F12356( unsigned char *sk, prng_t *prng0 ) {
|
||||
unsigned n_byte_generated = 0;
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O2_BYTE * N_TRIANGLE_TERMS(_V1) ); // l2_F1
|
||||
sk += _O2_BYTE * N_TRIANGLE_TERMS(_V1);
|
||||
n_byte_generated += _O2_BYTE * N_TRIANGLE_TERMS(_V1);
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O2_BYTE * _V1 * _O1 ); // l2_F2
|
||||
sk += _O2_BYTE * _V1 * _O1;
|
||||
n_byte_generated += _O2_BYTE * _V1 * _O1;
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O2_BYTE * _V1 * _O2 ); // l2_F3
|
||||
sk += _O2_BYTE * _V1 * _O1;
|
||||
n_byte_generated += _O2_BYTE * _V1 * _O1;
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O2_BYTE * N_TRIANGLE_TERMS(_O1) ); // l2_F5
|
||||
sk += _O2_BYTE * N_TRIANGLE_TERMS(_O1);
|
||||
n_byte_generated += _O2_BYTE * N_TRIANGLE_TERMS(_O1);
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen( prng0, sk, _O2_BYTE * _O1 * _O2 ); // l2_F6
|
||||
n_byte_generated += _O2_BYTE * _O1 * _O2;
|
||||
|
||||
return n_byte_generated;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void generate_B1_B2( unsigned char *sk, prng_t *prng0 ) {
|
||||
sk += generate_l1_F12( sk, prng0 );
|
||||
generate_l2_F12356( sk, prng0 );
|
||||
}
|
||||
|
||||
static
|
||||
void calculate_t4( unsigned char *t2_to_t4, const unsigned char *t1, const unsigned char *t3 ) {
|
||||
// t4 = T_sk.t1 * T_sk.t3 - T_sk.t2
|
||||
unsigned char temp[_V1_BYTE + 32];
|
||||
unsigned char *t4 = t2_to_t4;
|
||||
for (unsigned i = 0; i < _O2; i++) { /// t3 width
|
||||
gfmat_prod( temp, t1, _V1_BYTE, _O1, t3 );
|
||||
gf256v_add( t4, temp, _V1_BYTE );
|
||||
t4 += _V1_BYTE;
|
||||
t3 += _O1_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void obsfucate_l1_polys( unsigned char *l1_polys, const unsigned char *l2_polys, unsigned n_terms, const unsigned char *s1 ) {
|
||||
unsigned char temp[_O1_BYTE + 32];
|
||||
while ( n_terms-- ) {
|
||||
gfmat_prod( temp, s1, _O1_BYTE, _O2, l2_polys );
|
||||
gf256v_add( l1_polys, temp, _O1_BYTE );
|
||||
l1_polys += _O1_BYTE;
|
||||
l2_polys += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////// Classic //////////////////////////////////
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
static
|
||||
void _generate_secretkey( sk_t *sk, const unsigned char *sk_seed ) {
|
||||
memcpy( sk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
|
||||
// set up prng
|
||||
prng_t prng0;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( &prng0, sk_seed, LEN_SKSEED );
|
||||
|
||||
// generating secret key with prng.
|
||||
generate_S_T( sk->s1, &prng0 );
|
||||
generate_B1_B2( sk->l1_F1, &prng0 );
|
||||
|
||||
// clean prng
|
||||
memset( &prng0, 0, sizeof(prng_t) );
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair( pk_t *rpk, sk_t *sk, const unsigned char *sk_seed ) {
|
||||
_generate_secretkey( sk, sk_seed );
|
||||
|
||||
// set up a temporary structure ext_cpk_t for calculating public key.
|
||||
ext_cpk_t pk;
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F( &pk, sk, sk ); // compute the public key in ext_cpk_t format.
|
||||
calculate_t4( sk->t4, sk->t1, sk->t3 );
|
||||
|
||||
obsfucate_l1_polys( pk.l1_Q1, pk.l2_Q1, N_TRIANGLE_TERMS(_V1), sk->s1 );
|
||||
obsfucate_l1_polys( pk.l1_Q2, pk.l2_Q2, _V1 * _O1, sk->s1 );
|
||||
obsfucate_l1_polys( pk.l1_Q3, pk.l2_Q3, _V1 * _O2, sk->s1 );
|
||||
obsfucate_l1_polys( pk.l1_Q5, pk.l2_Q5, N_TRIANGLE_TERMS(_O1), sk->s1 );
|
||||
obsfucate_l1_polys( pk.l1_Q6, pk.l2_Q6, _O1 * _O2, sk->s1 );
|
||||
obsfucate_l1_polys( pk.l1_Q9, pk.l2_Q9, N_TRIANGLE_TERMS(_O2), sk->s1 );
|
||||
// so far, the pk contains the full pk but in ext_cpk_t format.
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_extcpk_to_pk( rpk, &pk ); // convert the public key from ext_cpk_t to pk_t.
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined _RAINBOW_CYCLIC
|
||||
///////////////////// Cyclic //////////////////////////////////
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair_cyclic( cpk_t *pk, sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed ) {
|
||||
memcpy( pk->pk_seed, pk_seed, LEN_PKSEED );
|
||||
memcpy( sk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
|
||||
// prng for sk
|
||||
prng_t prng;
|
||||
prng_t *prng0 = &prng;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( prng0, sk_seed, LEN_SKSEED );
|
||||
generate_S_T( sk->s1, prng0 ); // S,T: only a part of sk
|
||||
|
||||
unsigned char t2[sizeof(sk->t4)];
|
||||
memcpy( t2, sk->t4, _V1_BYTE * _O2 ); // temporarily store t2
|
||||
calculate_t4( sk->t4, sk->t1, sk->t3 ); // t2 <- t4
|
||||
|
||||
// prng for pk
|
||||
sk_t inst_Qs;
|
||||
sk_t *Qs = &inst_Qs;
|
||||
prng_t *prng1 = &prng;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( prng1, pk_seed, LEN_PKSEED );
|
||||
generate_B1_B2( Qs->l1_F1, prng1 ); // generating l1_Q1, l1_Q2, l2_Q1, l2_Q2, l2_Q3, l2_Q5, l2_Q6
|
||||
obsfucate_l1_polys( Qs->l1_F1, Qs->l2_F1, N_TRIANGLE_TERMS(_V1), sk->s1 );
|
||||
obsfucate_l1_polys( Qs->l1_F2, Qs->l2_F2, _V1 * _O1, sk->s1 );
|
||||
// so far, the Qs contains l1_F1, l1_F2, l2_F1, l2_F2, l2_F3, l2_F5, l2_F6.
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_F_from_Q( sk, Qs, sk ); // calcuate the rest parts of secret key from Qs and S,T
|
||||
|
||||
|
||||
unsigned char t4[sizeof(sk->t4)];
|
||||
memcpy( t4, sk->t4, _V1_BYTE * _O2 ); // temporarily store t4
|
||||
memcpy( sk->t4, t2, _V1_BYTE * _O2 ); // restore t2
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F_cyclic( pk, sk, sk ); // calculate the rest parts of public key: l1_Q3, l1_Q5, l1_Q6, l1_Q9, l2_Q9
|
||||
memcpy( sk->t4, t4, _V1_BYTE * _O2 ); // restore t4
|
||||
|
||||
obsfucate_l1_polys( pk->l1_Q3, Qs->l2_F3, _V1 * _O2, sk->s1 );
|
||||
obsfucate_l1_polys( pk->l1_Q5, Qs->l2_F5, N_TRIANGLE_TERMS(_O1), sk->s1 );
|
||||
obsfucate_l1_polys( pk->l1_Q6, Qs->l2_F6, _O1 * _O2, sk->s1 );
|
||||
obsfucate_l1_polys( pk->l1_Q9, pk->l2_Q9, N_TRIANGLE_TERMS(_O2), sk->s1 );
|
||||
|
||||
// clean
|
||||
memset( &prng, 0, sizeof(prng_t) );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _RAINBOW_CYCLIC_COMPRESSED
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_compact_keypair_cyclic( cpk_t *pk, csk_t *rsk, const unsigned char *pk_seed, const unsigned char *sk_seed ) {
|
||||
memcpy( rsk->pk_seed, pk_seed, LEN_PKSEED );
|
||||
memcpy( rsk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
sk_t sk;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair_cyclic( pk, &sk, pk_seed, sk_seed );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _RAINBOW_CYCLIC_COMPRESSED
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_secretkey_cyclic( sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed ) {
|
||||
memcpy( sk->sk_seed, sk_seed, LEN_SKSEED );
|
||||
|
||||
// prng for sk
|
||||
prng_t prng0;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( &prng0, sk_seed, LEN_SKSEED );
|
||||
generate_S_T( sk->s1, &prng0 );
|
||||
calculate_t4( sk->t4, sk->t1, sk->t3 );
|
||||
|
||||
// prng for pk
|
||||
sk_t inst_Qs;
|
||||
sk_t *Qs = &inst_Qs;
|
||||
prng_t prng1;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( &prng1, pk_seed, LEN_PKSEED );
|
||||
generate_B1_B2( Qs->l1_F1, &prng1 );
|
||||
|
||||
obsfucate_l1_polys( Qs->l1_F1, Qs->l2_F1, N_TRIANGLE_TERMS(_V1), sk->s1 );
|
||||
obsfucate_l1_polys( Qs->l1_F2, Qs->l2_F2, _V1 * _O1, sk->s1 );
|
||||
|
||||
// calcuate the parts of sk according to pk.
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_F_from_Q( sk, Qs, sk );
|
||||
|
||||
// clean prng for sk
|
||||
memset( &prng0, 0, sizeof(prng_t) );
|
||||
}
|
||||
#endif
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_cpk_to_pk( pk_t *rpk, const cpk_t *cpk ) {
|
||||
// procedure: cpk_t --> extcpk_t --> pk_t
|
||||
|
||||
// convert from cpk_t to extcpk_t
|
||||
ext_cpk_t pk;
|
||||
|
||||
// setup prng
|
||||
prng_t prng0;
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set( &prng0, cpk->pk_seed, LEN_SKSEED );
|
||||
|
||||
// generating parts of key with prng
|
||||
generate_l1_F12( pk.l1_Q1, &prng0 );
|
||||
// copying parts of key from input. l1_Q3, l1_Q5, l1_Q6, l1_Q9
|
||||
memcpy( pk.l1_Q3, cpk->l1_Q3, _O1_BYTE * ( _V1 * _O2 + N_TRIANGLE_TERMS(_O1) + _O1 * _O2 + N_TRIANGLE_TERMS(_O2) ) );
|
||||
|
||||
// generating parts of key with prng
|
||||
generate_l2_F12356( pk.l2_Q1, &prng0 );
|
||||
// copying parts of key from input: l2_Q9
|
||||
memcpy( pk.l2_Q9, cpk->l2_Q9, _O2_BYTE * N_TRIANGLE_TERMS(_O2) );
|
||||
|
||||
// convert from extcpk_t to pk_t
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_extcpk_to_pk( rpk, &pk );
|
||||
}
|
||||
#endif
|
146
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair.h
Normal file
146
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair.h
Normal file
@ -0,0 +1,146 @@
|
||||
#ifndef _RAINBOW_KEYPAIR_H_
|
||||
#define _RAINBOW_KEYPAIR_H_
|
||||
/// @file rainbow_keypair.h
|
||||
/// @brief Formats of key pairs and functions for generating key pairs.
|
||||
/// Formats of key pairs and functions for generating key pairs.
|
||||
///
|
||||
|
||||
|
||||
|
||||
#include "rainbow_config.h"
|
||||
|
||||
|
||||
#define N_TRIANGLE_TERMS(n_var) ((n_var)*((n_var)+1)/2)
|
||||
|
||||
|
||||
/// @brief public key for classic rainbow
|
||||
///
|
||||
/// public key for classic rainbow
|
||||
///
|
||||
typedef
|
||||
struct rainbow_publickey {
|
||||
unsigned char pk[(_PUB_M_BYTE) * N_TRIANGLE_TERMS(_PUB_N)];
|
||||
} pk_t;
|
||||
|
||||
|
||||
/// @brief secret key for classic rainbow
|
||||
///
|
||||
/// secret key for classic rainbow
|
||||
///
|
||||
typedef
|
||||
struct rainbow_secretkey {
|
||||
///
|
||||
/// seed for generating secret key.
|
||||
/// Generating S, T, and F for classic rainbow.
|
||||
/// Generating S and T only for cyclic rainbow.
|
||||
unsigned char sk_seed[LEN_SKSEED];
|
||||
|
||||
unsigned char s1[_O1_BYTE * _O2]; ///< part of S map
|
||||
unsigned char t1[_V1_BYTE * _O1]; ///< part of T map
|
||||
unsigned char t4[_V1_BYTE * _O2]; ///< part of T map
|
||||
unsigned char t3[_O1_BYTE * _O2]; ///< part of T map
|
||||
|
||||
unsigned char l1_F1[_O1_BYTE * N_TRIANGLE_TERMS(_V1)]; ///< part of C-map, F1, Layer1
|
||||
unsigned char l1_F2[_O1_BYTE * _V1 * _O1]; ///< part of C-map, F2, Layer1
|
||||
|
||||
unsigned char l2_F1[_O2_BYTE * N_TRIANGLE_TERMS(_V1)]; ///< part of C-map, F1, Layer2
|
||||
unsigned char l2_F2[_O2_BYTE * _V1 * _O1]; ///< part of C-map, F2, Layer2
|
||||
|
||||
unsigned char l2_F3[_O2_BYTE * _V1 * _O2]; ///< part of C-map, F3, Layer2
|
||||
unsigned char l2_F5[_O2_BYTE * N_TRIANGLE_TERMS(_O1)]; ///< part of C-map, F5, Layer2
|
||||
unsigned char l2_F6[_O2_BYTE * _O1 * _O2]; ///< part of C-map, F6, Layer2
|
||||
} sk_t;
|
||||
|
||||
|
||||
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
/// @brief public key for cyclic rainbow
|
||||
///
|
||||
/// public key for cyclic rainbow
|
||||
///
|
||||
typedef
|
||||
struct rainbow_publickey_cyclic {
|
||||
unsigned char pk_seed[LEN_PKSEED]; ///< seed for generating l1_Q1,l1_Q2,l2_Q1,l2_Q2,l2_Q3,l2_Q5,l2_Q6
|
||||
|
||||
unsigned char l1_Q3[_O1_BYTE * _V1 * _O2]; ///< Q3, layer1
|
||||
unsigned char l1_Q5[_O1_BYTE * N_TRIANGLE_TERMS(_O1)]; ///< Q5, layer1
|
||||
unsigned char l1_Q6[_O1_BYTE * _O1 * _O2]; ///< Q6, layer1
|
||||
unsigned char l1_Q9[_O1_BYTE * N_TRIANGLE_TERMS(_O2)]; ///< Q9, layer1
|
||||
|
||||
unsigned char l2_Q9[_O2_BYTE * N_TRIANGLE_TERMS(_O2)]; ///< Q9, layer2
|
||||
} cpk_t;
|
||||
|
||||
|
||||
|
||||
/// @brief compressed secret key for cyclic rainbow
|
||||
///
|
||||
/// compressed secret key for cyclic rainbow
|
||||
///
|
||||
typedef
|
||||
struct rainbow_secretkey_cyclic {
|
||||
unsigned char pk_seed[LEN_PKSEED]; ///< seed for generating a part of public key.
|
||||
unsigned char sk_seed[LEN_SKSEED]; ///< seed for generating a part of secret key.
|
||||
} csk_t;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
///
|
||||
/// @brief Generate key pairs for classic rainbow.
|
||||
///
|
||||
/// @param[out] pk - the public key.
|
||||
/// @param[out] sk - the secret key.
|
||||
/// @param[in] sk_seed - seed for generating the secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair( pk_t *pk, sk_t *sk, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#if defined _RAINBOW_CYCLIC
|
||||
///
|
||||
/// @brief Generate key pairs for cyclic rainbow.
|
||||
///
|
||||
/// @param[out] pk - the public key.
|
||||
/// @param[out] sk - the secret key.
|
||||
/// @param[in] pk_seed - seed for generating parts of public key.
|
||||
/// @param[in] sk_seed - seed for generating secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair_cyclic( cpk_t *pk, sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#if defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
///
|
||||
/// @brief Generate compressed key pairs for cyclic rainbow.
|
||||
///
|
||||
/// @param[out] pk - the public key.
|
||||
/// @param[out] sk - the compressed secret key.
|
||||
/// @param[in] pk_seed - seed for generating parts of the public key.
|
||||
/// @param[in] sk_seed - seed for generating the secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_compact_keypair_cyclic( cpk_t *pk, csk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#ifdef _RAINBOW_CYCLIC_COMPRESSED
|
||||
///
|
||||
/// @brief Generate secret key for cyclic rainbow.
|
||||
///
|
||||
/// @param[out] sk - the secret key.
|
||||
/// @param[in] pk_seed - seed for generating parts of the pbulic key.
|
||||
/// @param[in] sk_seed - seed for generating the secret key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_secretkey_cyclic( sk_t *sk, const unsigned char *pk_seed, const unsigned char *sk_seed );
|
||||
#endif
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
////////////////////////////////////
|
||||
|
||||
///
|
||||
/// @brief converting formats of public keys : from cyclic version to classic key
|
||||
///
|
||||
/// @param[out] pk - the classic public key.
|
||||
/// @param[in] cpk - the cyclic public key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_cpk_to_pk( pk_t *pk, const cpk_t *cpk );
|
||||
#endif
|
||||
|
||||
#endif // _RAINBOW_KEYPAIR_H_
|
349
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair_computation.c
Normal file
349
crypto_sign/rainbowIa-cyclic/clean/rainbow_keypair_computation.c
Normal file
@ -0,0 +1,349 @@
|
||||
/// @file rainbow_keypair_computation.c
|
||||
/// @brief Implementations for functions in rainbow_keypair_computation.h
|
||||
///
|
||||
|
||||
|
||||
#include "blas.h"
|
||||
#include "blas_comm.h"
|
||||
#include "rainbow_blas.h"
|
||||
#include "rainbow_keypair.h"
|
||||
#include "rainbow_keypair_computation.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if defined _RAINBOW_CYCLIC || defined _RAINBOW_CLASSIC
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_extcpk_to_pk( pk_t *pk, const ext_cpk_t *cpk ) {
|
||||
const unsigned char *idx_l1 = cpk->l1_Q1;
|
||||
const unsigned char *idx_l2 = cpk->l2_Q1;
|
||||
for (unsigned i = 0; i < _V1; i++) {
|
||||
for (unsigned j = i; j < _V1; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
idx_l1 = cpk->l1_Q2;
|
||||
idx_l2 = cpk->l2_Q2;
|
||||
for (unsigned i = 0; i < _V1; i++) {
|
||||
for (unsigned j = _V1; j < _V1 + _O1; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
idx_l1 = cpk->l1_Q3;
|
||||
idx_l2 = cpk->l2_Q3;
|
||||
for (unsigned i = 0; i < _V1; i++) {
|
||||
for (unsigned j = _V1 + _O1; j < _PUB_N; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
idx_l1 = cpk->l1_Q5;
|
||||
idx_l2 = cpk->l2_Q5;
|
||||
for (unsigned i = _V1; i < _V1 + _O1; i++) {
|
||||
for (unsigned j = i; j < _V1 + _O1; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
idx_l1 = cpk->l1_Q6;
|
||||
idx_l2 = cpk->l2_Q6;
|
||||
for (unsigned i = _V1; i < _V1 + _O1; i++) {
|
||||
for (unsigned j = _V1 + _O1; j < _PUB_N; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
idx_l1 = cpk->l1_Q9;
|
||||
idx_l2 = cpk->l2_Q9;
|
||||
for (unsigned i = _V1 + _O1; i < _PUB_N; i++) {
|
||||
for (unsigned j = i; j < _PUB_N; j++) {
|
||||
unsigned pub_idx = PQCLEAN_RAINBOWIACYCLIC_CLEAN_idx_of_trimat(i, j, _PUB_N);
|
||||
memcpy( & pk->pk[ _PUB_M_BYTE * pub_idx ], idx_l1, _O1_BYTE );
|
||||
memcpy( (&pk->pk[ _PUB_M_BYTE * pub_idx ]) + _O1_BYTE, idx_l2, _O2_BYTE );
|
||||
idx_l1 += _O1_BYTE;
|
||||
idx_l2 += _O2_BYTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
static
|
||||
void calculate_Q_from_F_ref( ext_cpk_t *Qs, const sk_t *Fs, const sk_t *Ts ) {
|
||||
/*
|
||||
Layer 1
|
||||
Computing :
|
||||
Q_pk.l1_F1s[i] = F_sk.l1_F1s[i]
|
||||
|
||||
Q_pk.l1_F2s[i] = (F1* T1 + F2) + F1tr * t1
|
||||
Q_pk.l1_F5s[i] = UT( T1tr* (F1 * T1 + F2) )
|
||||
*/
|
||||
const unsigned char *t2 = Ts->t4;
|
||||
|
||||
memcpy( Qs->l1_Q1, Fs->l1_F1, _O1_BYTE * N_TRIANGLE_TERMS(_V1) );
|
||||
|
||||
memcpy( Qs->l1_Q2, Fs->l1_F2, _O1_BYTE * _V1 * _O1 );
|
||||
batch_trimat_madd( Qs->l1_Q2, Fs->l1_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O1_BYTE ); // F1*T1 + F2
|
||||
|
||||
memset( Qs->l1_Q3, 0, _O1_BYTE * _V1 * _O2 );
|
||||
memset( Qs->l1_Q5, 0, _O1_BYTE * N_TRIANGLE_TERMS(_O1) );
|
||||
memset( Qs->l1_Q6, 0, _O1_BYTE * _O1 * _O2 );
|
||||
memset( Qs->l1_Q9, 0, _O1_BYTE * N_TRIANGLE_TERMS(_O2) );
|
||||
|
||||
// l1_Q5 : _O1_BYTE * _O1 * _O1
|
||||
// l1_Q9 : _O1_BYTE * _O2 * _O2
|
||||
// l2_Q5 : _O2_BYTE * _V1 * _O1
|
||||
// l2_Q9 : _O2_BYTE * _V1 * _O2
|
||||
|
||||
|
||||
unsigned char tempQ[_O1_BYTE * _O1 * _O1 + 32];
|
||||
|
||||
memset( tempQ, 0, _O1_BYTE * _O1 * _O1 ); // l1_Q5
|
||||
batch_matTr_madd( tempQ, Ts->t1, _V1, _V1_BYTE, _O1, Qs->l1_Q2, _O1, _O1_BYTE ); // t1_tr*(F1*T1 + F2)
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l1_Q5, tempQ, _O1, _O1_BYTE ); // UT( ... ) // Q5
|
||||
|
||||
batch_trimatTr_madd( Qs->l1_Q2, Fs->l1_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O1_BYTE ); // Q2
|
||||
/*
|
||||
Computing:
|
||||
F1_T2 = F1 * t2
|
||||
F2_T3 = F2 * t3
|
||||
F1_F1T_T2 + F2_T3 = F1_T2 + F2_T3 + F1tr * t2
|
||||
Q_pk.l1_F3s[i] = F1_F1T_T2 + F2_T3
|
||||
Q_pk.l1_F6s[i] = T1tr* ( F1_F1T_T2 + F2_T3 ) + F2tr * t2
|
||||
Q_pk.l1_F9s[i] = UT( T2tr* ( F1_T2 + F2_T3 ) )
|
||||
*/
|
||||
batch_trimat_madd( Qs->l1_Q3, Fs->l1_F1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F1*T2
|
||||
batch_mat_madd( Qs->l1_Q3, Fs->l1_F2, _V1, Ts->t3, _O1, _O1_BYTE, _O2, _O1_BYTE ); // F1_T2 + F2_T3
|
||||
|
||||
memset( tempQ, 0, _O1_BYTE * _O2 * _O2 ); // l1_Q9
|
||||
batch_matTr_madd( tempQ, t2, _V1, _V1_BYTE, _O2, Qs->l1_Q3, _O2, _O1_BYTE ); // T2tr * ( F1_T2 + F2_T3 )
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l1_Q9, tempQ, _O2, _O1_BYTE ); // Q9
|
||||
|
||||
batch_trimatTr_madd( Qs->l1_Q3, Fs->l1_F1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F1_F1T_T2 + F2_T3 // Q3
|
||||
|
||||
batch_bmatTr_madd( Qs->l1_Q6, Fs->l1_F2, _O1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F2tr*T2
|
||||
batch_matTr_madd( Qs->l1_Q6, Ts->t1, _V1, _V1_BYTE, _O1, Qs->l1_Q3, _O2, _O1_BYTE ); // Q6
|
||||
|
||||
/*
|
||||
layer 2
|
||||
Computing:
|
||||
Q1 = F1
|
||||
Q2 = F1_F1T*T1 + F2
|
||||
Q5 = UT( T1tr( F1*T1 + F2 ) + F5 )
|
||||
*/
|
||||
memcpy( Qs->l2_Q1, Fs->l2_F1, _O2_BYTE * N_TRIANGLE_TERMS(_V1) );
|
||||
|
||||
memcpy( Qs->l2_Q2, Fs->l2_F2, _O2_BYTE * _V1 * _O1 );
|
||||
batch_trimat_madd( Qs->l2_Q2, Fs->l2_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O2_BYTE ); // F1*T1 + F2
|
||||
|
||||
memcpy( Qs->l2_Q5, Fs->l2_F5, _O2_BYTE * N_TRIANGLE_TERMS(_O1) );
|
||||
memset( tempQ, 0, _O2_BYTE * _O1 * _O1 ); // l2_Q5
|
||||
batch_matTr_madd( tempQ, Ts->t1, _V1, _V1_BYTE, _O1, Qs->l2_Q2, _O1, _O2_BYTE ); // t1_tr*(F1*T1 + F2)
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l2_Q5, tempQ, _O1, _O2_BYTE ); // UT( ... ) // Q5
|
||||
|
||||
batch_trimatTr_madd( Qs->l2_Q2, Fs->l2_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O2_BYTE ); // Q2
|
||||
|
||||
/*
|
||||
Computing:
|
||||
F1_T2 = F1 * t2
|
||||
F2_T3 = F2 * t3
|
||||
F1_F1T_T2 + F2_T3 = F1_T2 + F2_T3 + F1tr * t2
|
||||
|
||||
Q3 = F1_F1T*T2 + F2*T3 + F3
|
||||
Q9 = UT( T2tr*( F1*T2 + F2*T3 + F3 ) + T3tr*( F5*T3 + F6 ) )
|
||||
Q6 = T1tr*( F1_F1T*T2 + F2*T3 + F3 ) + F2Tr*T2 + F5_F5T*T3 + F6
|
||||
*/
|
||||
memcpy( Qs->l2_Q3, Fs->l2_F3, _O2_BYTE * _V1 * _O2 );
|
||||
batch_trimat_madd( Qs->l2_Q3, Fs->l2_F1, t2, _V1, _V1_BYTE, _O2, _O2_BYTE ); // F1*T2 + F3
|
||||
batch_mat_madd( Qs->l2_Q3, Fs->l2_F2, _V1, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // F1_T2 + F2_T3 + F3
|
||||
|
||||
memset( tempQ, 0, _O2_BYTE * _O2 * _O2 ); // l2_Q9
|
||||
batch_matTr_madd( tempQ, t2, _V1, _V1_BYTE, _O2, Qs->l2_Q3, _O2, _O2_BYTE ); // T2tr * ( ..... )
|
||||
|
||||
memcpy( Qs->l2_Q6, Fs->l2_F6, _O2_BYTE * _O1 * _O2 );
|
||||
|
||||
batch_trimat_madd( Qs->l2_Q6, Fs->l2_F5, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // F5*T3 + F6
|
||||
batch_matTr_madd( tempQ, Ts->t3, _O1, _O1_BYTE, _O2, Qs->l2_Q6, _O2, _O2_BYTE ); // T2tr*( ..... ) + T3tr*( ..... )
|
||||
memset( Qs->l2_Q9, 0, _O2_BYTE * N_TRIANGLE_TERMS(_O2) );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l2_Q9, tempQ, _O2, _O2_BYTE ); // Q9
|
||||
|
||||
batch_trimatTr_madd( Qs->l2_Q3, Fs->l2_F1, t2, _V1, _V1_BYTE, _O2, _O2_BYTE ); // F1_F1T_T2 + F2_T3 + F3 // Q3
|
||||
|
||||
batch_bmatTr_madd( Qs->l2_Q6, Fs->l2_F2, _O1, t2, _V1, _V1_BYTE, _O2, _O2_BYTE ); // F5*T3 + F6 + F2tr*T2
|
||||
batch_trimatTr_madd( Qs->l2_Q6, Fs->l2_F5, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // F2tr*T2 + F5_F5T*T3 + F6
|
||||
batch_matTr_madd( Qs->l2_Q6, Ts->t1, _V1, _V1_BYTE, _O1, Qs->l2_Q3, _O2, _O2_BYTE ); // Q6
|
||||
}
|
||||
// TODO: these defines are not really required for a clean implementation - just implement directly
|
||||
#define calculate_Q_from_F_impl calculate_Q_from_F_ref
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F( ext_cpk_t *Qs, const sk_t *Fs, const sk_t *Ts ) {
|
||||
calculate_Q_from_F_impl( Qs, Fs, Ts );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
|
||||
static
|
||||
void calculate_F_from_Q_ref( sk_t *Fs, const sk_t *Qs, sk_t *Ts ) {
|
||||
// Layer 1
|
||||
// F_sk.l1_F1s[i] = Q_pk.l1_F1s[i]
|
||||
memcpy( Fs->l1_F1, Qs->l1_F1, _O1_BYTE * N_TRIANGLE_TERMS(_V1) );
|
||||
|
||||
// F_sk.l1_F2s[i] = ( Q_pk.l1_F1s[i] + Q_pk.l1_F1s[i].transpose() ) * T_sk.t1 + Q_pk.l1_F2s[i]
|
||||
memcpy( Fs->l1_F2, Qs->l1_F2, _O1_BYTE * _V1 * _O1 );
|
||||
batch_2trimat_madd( Fs->l1_F2, Qs->l1_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O1_BYTE );
|
||||
|
||||
/*
|
||||
Layer 2
|
||||
computations:
|
||||
|
||||
F_sk.l2_F1s[i] = Q_pk.l2_F1s[i]
|
||||
|
||||
Q1_T1 = Q_pk.l2_F1s[i]*T_sk.t1
|
||||
F_sk.l2_F2s[i] = Q1_T1 + Q_pk.l2_F2s[i] + Q_pk.l2_F1s[i].transpose() * T_sk.t1
|
||||
F_sk.l2_F5s[i] = UT( t1_tr* ( Q1_T1 + Q_pk.l2_F2s[i] ) ) + Q_pk.l2_F5s[i]
|
||||
|
||||
Q1_Q1T_T4 = (Q_pk.l2_F1s[i] + Q_pk.l2_F1s[i].transpose()) * t4
|
||||
#Q1_Q1T_T4 = Q1_Q1T * t4
|
||||
Q2_T3 = Q_pk.l2_F2s[i]*T_sk.t3
|
||||
F_sk.l2_F3s[i] = Q1_Q1T_T4 + Q2_T3 + Q_pk.l2_F3s[i]
|
||||
F_sk.l2_F6s[i] = t1_tr * ( Q1_Q1T_T4 + Q2_T3 + Q_pk.l2_F3s[i] )
|
||||
+ Q_pk.l2_F2s[i].transpose() * t4
|
||||
+ (Q_pk.l2_F5s[i] + Q_pk.l2_F5s[i].transpose())*T_sk.t3 + Q_pk.l2_F6s[i]
|
||||
|
||||
*/
|
||||
memcpy( Fs->l2_F1, Qs->l2_F1, _O2_BYTE * N_TRIANGLE_TERMS(_V1) ); // F_sk.l2_F1s[i] = Q_pk.l2_F1s[i]
|
||||
|
||||
|
||||
// F_sk.l2_F2s[i] = Q1_T1 + Q_pk.l2_F2s[i] + Q_pk.l2_F1s[i].transpose() * T_sk.t1
|
||||
// F_sk.l2_F5s[i] = UT( t1_tr* ( Q1_T1 + Q_pk.l2_F2s[i] ) ) + Q_pk.l2_F5s[i]
|
||||
memcpy( Fs->l2_F2, Qs->l2_F2, _O2_BYTE * _V1 * _O1 );
|
||||
batch_trimat_madd( Fs->l2_F2, Qs->l2_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O2_BYTE ); // Q1_T1+ Q2
|
||||
|
||||
unsigned char tempQ[_O1 * _O1 * _O2_BYTE + 32];
|
||||
memset( tempQ, 0, _O1 * _O1 * _O2_BYTE );
|
||||
batch_matTr_madd( tempQ, Ts->t1, _V1, _V1_BYTE, _O1, Fs->l2_F2, _O1, _O2_BYTE ); // t1_tr*(Q1_T1+Q2)
|
||||
memcpy( Fs->l2_F5, Qs->l2_F5, _O2_BYTE * N_TRIANGLE_TERMS(_O1) ); // F5
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Fs->l2_F5, tempQ, _O1, _O2_BYTE ); // UT( ... )
|
||||
|
||||
batch_trimatTr_madd( Fs->l2_F2, Qs->l2_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O2_BYTE ); // F2 = Q1_T1 + Q2 + Q1^tr*t1
|
||||
|
||||
// Q1_Q1T_T4 = (Q_pk.l2_F1s[i] + Q_pk.l2_F1s[i].transpose()) * t4
|
||||
// Q2_T3 = Q_pk.l2_F2s[i]*T_sk.t3
|
||||
// F_sk.l2_F3s[i] = Q1_Q1T_T4 + Q2_T3 + Q_pk.l2_F3s[i]
|
||||
memcpy( Fs->l2_F3, Qs->l2_F3, _V1 * _O2 * _O2_BYTE );
|
||||
batch_2trimat_madd( Fs->l2_F3, Qs->l2_F1, Ts->t4, _V1, _V1_BYTE, _O2, _O2_BYTE ); // Q1_Q1T_T4
|
||||
batch_mat_madd( Fs->l2_F3, Qs->l2_F2, _V1, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // Q2_T3
|
||||
|
||||
// F_sk.l2_F6s[i] = t1_tr * ( Q1_Q1T_T4 + Q2_T3 + Q_pk.l2_F3s[i] )
|
||||
// + Q_pk.l2_F2s[i].transpose() * t4
|
||||
// + (Q_pk.l2_F5s[i] + Q_pk.l2_F5s[i].transpose())*T_sk.t3 + Q_pk.l2_F6s[i]
|
||||
memcpy( Fs->l2_F6, Qs->l2_F6, _O1 * _O2 * _O2_BYTE );
|
||||
batch_matTr_madd( Fs->l2_F6, Ts->t1, _V1, _V1_BYTE, _O1, Fs->l2_F3, _O2, _O2_BYTE ); // t1_tr * ( Q1_Q1T_T4 + Q2_T3 + Q_pk.l2_F3s[i] )
|
||||
batch_2trimat_madd( Fs->l2_F6, Qs->l2_F5, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // (Q_pk.l2_F5s[i] + Q_pk.l2_F5s[i].transpose())*T_sk.t3
|
||||
batch_bmatTr_madd( Fs->l2_F6, Qs->l2_F2, _O1, Ts->t4, _V1, _V1_BYTE, _O2, _O2_BYTE );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static
|
||||
void calculate_Q_from_F_cyclic_ref( cpk_t *Qs, const sk_t *Fs, const sk_t *Ts ) {
|
||||
// Layer 1: Computing Q5, Q3, Q6, Q9
|
||||
|
||||
// Q_pk.l1_F5s[i] = UT( T1tr* (F1 * T1 + F2) )
|
||||
const unsigned char *t2 = Ts->t4;
|
||||
sk_t tempQ;
|
||||
memcpy( tempQ.l1_F2, Fs->l1_F2, _O1_BYTE * _V1 * _O1 );
|
||||
batch_trimat_madd( tempQ.l1_F2, Fs->l1_F1, Ts->t1, _V1, _V1_BYTE, _O1, _O1_BYTE ); // F1*T1 + F2
|
||||
memset( tempQ.l2_F1, 0, _O1_BYTE * _V1 * _O2 );
|
||||
batch_matTr_madd( tempQ.l2_F1, Ts->t1, _V1, _V1_BYTE, _O1, tempQ.l1_F2, _O1, _O1_BYTE ); // T1tr*(F1*T1 + F2)
|
||||
memset( Qs->l1_Q5, 0, _O1_BYTE * N_TRIANGLE_TERMS(_O1) );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l1_Q5, tempQ.l2_F1, _O1, _O1_BYTE ); // UT( ... ) // Q5
|
||||
|
||||
/*
|
||||
F1_T2 = F1 * t2
|
||||
F2_T3 = F2 * t3
|
||||
F1_F1T_T2 + F2_T3 = F1_T2 + F2_T3 + F1tr * t2
|
||||
Q_pk.l1_F3s[i] = F1_F1T_T2 + F2_T3
|
||||
Q_pk.l1_F6s[i] = T1tr* ( F1_F1T_T2 + F2_T3 ) + F2tr * t2
|
||||
Q_pk.l1_F9s[i] = UT( T2tr* ( F1_T2 + F2_T3 ) )
|
||||
*/
|
||||
memset( Qs->l1_Q3, 0, _O1_BYTE * _V1 * _O2 );
|
||||
memset( Qs->l1_Q6, 0, _O1_BYTE * _O1 * _O2 );
|
||||
memset( Qs->l1_Q9, 0, _O1_BYTE * N_TRIANGLE_TERMS(_O2) );
|
||||
|
||||
batch_trimat_madd( Qs->l1_Q3, Fs->l1_F1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F1*T2
|
||||
batch_mat_madd( Qs->l1_Q3, Fs->l1_F2, _V1, Ts->t3, _O1, _O1_BYTE, _O2, _O1_BYTE ); // F1_T2 + F2_T3
|
||||
|
||||
memset( tempQ.l1_F2, 0, _O1_BYTE * _V1 * _O2 ); // should be F3. assuming: _O1 >= _O2
|
||||
batch_matTr_madd( tempQ.l1_F2, t2, _V1, _V1_BYTE, _O2, Qs->l1_Q3, _O2, _O1_BYTE ); // T2tr * ( F1_T2 + F2_T3 )
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l1_Q9, tempQ.l1_F2, _O2, _O1_BYTE ); // Q9
|
||||
|
||||
batch_trimatTr_madd( Qs->l1_Q3, Fs->l1_F1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F1_F1T_T2 + F2_T3 // Q3
|
||||
|
||||
batch_bmatTr_madd( Qs->l1_Q6, Fs->l1_F2, _O1, t2, _V1, _V1_BYTE, _O2, _O1_BYTE ); // F2tr*T2
|
||||
batch_matTr_madd( Qs->l1_Q6, Ts->t1, _V1, _V1_BYTE, _O1, Qs->l1_Q3, _O2, _O1_BYTE ); // Q6
|
||||
/*
|
||||
Layer 2
|
||||
Computing Q9:
|
||||
|
||||
F1_T2 = F1 * t2
|
||||
F2_T3 = F2 * t3
|
||||
Q9 = UT( T2tr*( F1*T2 + F2*T3 + F3 ) + T3tr*( F5*T3 + F6 ) )
|
||||
*/
|
||||
sk_t tempQ2;
|
||||
memcpy( tempQ2.l2_F3, Fs->l2_F3, _O2_BYTE * _V1 * _O2 ); /// F3 actually.
|
||||
batch_trimat_madd( tempQ2.l2_F3, Fs->l2_F1, t2, _V1, _V1_BYTE, _O2, _O2_BYTE ); // F1*T2 + F3
|
||||
batch_mat_madd( tempQ2.l2_F3, Fs->l2_F2, _V1, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // F1_T2 + F2_T3 + F3
|
||||
|
||||
memset( tempQ.l2_F3, 0, _O2_BYTE * _V1 * _O2 );
|
||||
batch_matTr_madd( tempQ.l2_F3, t2, _V1, _V1_BYTE, _O2, tempQ2.l2_F3, _O2, _O2_BYTE ); // T2tr * ( ..... )
|
||||
|
||||
memcpy( tempQ.l2_F6, Fs->l2_F6, _O2_BYTE * _O1 * _O2 );
|
||||
batch_trimat_madd( tempQ.l2_F6, Fs->l2_F5, Ts->t3, _O1, _O1_BYTE, _O2, _O2_BYTE ); // F5*T3 + F6
|
||||
|
||||
batch_matTr_madd( tempQ.l2_F3, Ts->t3, _O1, _O1_BYTE, _O2, tempQ.l2_F6, _O2, _O2_BYTE ); // T2tr*( ..... ) + T3tr*( ..... )
|
||||
memset( Qs->l2_Q9, 0, _O2_BYTE * N_TRIANGLE_TERMS(_O2) );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_UpperTrianglize( Qs->l2_Q9, tempQ.l2_F3, _O2, _O2_BYTE ); // Q9
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Choosing implementations depends on the macros: _BLAS_SSE_ and _BLAS_AVX2_
|
||||
#define calculate_F_from_Q_impl calculate_F_from_Q_ref
|
||||
#define calculate_Q_from_F_cyclic_impl calculate_Q_from_F_cyclic_ref
|
||||
|
||||
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_F_from_Q( sk_t *Fs, const sk_t *Qs, sk_t *Ts ) {
|
||||
calculate_F_from_Q_impl( Fs, Qs, Ts );
|
||||
}
|
||||
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F_cyclic( cpk_t *Qs, const sk_t *Fs, const sk_t *Ts ) {
|
||||
calculate_Q_from_F_cyclic_impl( Qs, Fs, Ts );
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,84 @@
|
||||
#ifndef _RAINBOW_KEYPAIR_COMP_H_
|
||||
#define _RAINBOW_KEYPAIR_COMP_H_
|
||||
/// @file rainbow_keypair_computation.h
|
||||
/// @brief Functions for calculating pk/sk while generating keys.
|
||||
///
|
||||
/// Defining an internal structure of public key.
|
||||
/// Functions for calculating pk/sk for key generation.
|
||||
///
|
||||
|
||||
|
||||
|
||||
#include "rainbow_keypair.h"
|
||||
|
||||
#if defined _RAINBOW_CYCLIC || defined _RAINBOW_CLASSIC
|
||||
/// @brief The (internal use) public key for rainbow
|
||||
///
|
||||
/// The (internal use) public key for rainbow. The public
|
||||
/// polynomials are divided into l1_Q1, l1_Q2, ... l1_Q9,
|
||||
/// l2_Q1, .... , l2_Q9.
|
||||
///
|
||||
typedef
|
||||
struct rainbow_extend_publickey {
|
||||
unsigned char l1_Q1[_O1_BYTE * N_TRIANGLE_TERMS(_V1)];
|
||||
unsigned char l1_Q2[_O1_BYTE * _V1 * _O1];
|
||||
unsigned char l1_Q3[_O1_BYTE * _V1 * _O2];
|
||||
unsigned char l1_Q5[_O1_BYTE * N_TRIANGLE_TERMS(_O1)];
|
||||
unsigned char l1_Q6[_O1_BYTE * _O1 * _O2];
|
||||
unsigned char l1_Q9[_O1_BYTE * N_TRIANGLE_TERMS(_O2)];
|
||||
|
||||
unsigned char l2_Q1[_O2_BYTE * N_TRIANGLE_TERMS(_V1)];
|
||||
unsigned char l2_Q2[_O2_BYTE * _V1 * _O1];
|
||||
unsigned char l2_Q3[_O2_BYTE * _V1 * _O2];
|
||||
unsigned char l2_Q5[_O2_BYTE * N_TRIANGLE_TERMS(_O1)];
|
||||
unsigned char l2_Q6[_O2_BYTE * _O1 * _O2];
|
||||
unsigned char l2_Q9[_O2_BYTE * N_TRIANGLE_TERMS(_O2)];
|
||||
} ext_cpk_t;
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// @brief converting formats of public keys : from ext_cpk_t version to pk_t
|
||||
///
|
||||
/// @param[out] pk - the classic public key.
|
||||
/// @param[in] cpk - the internel public key.
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_extcpk_to_pk( pk_t *pk, const ext_cpk_t *cpk );
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
///
|
||||
/// @brief Computing public key from secret key
|
||||
///
|
||||
/// @param[out] Qs - the public key
|
||||
/// @param[in] Fs - parts of the secret key: l1_F1, l1_F2, l2_F1, l2_F2, l2_F3, l2_F5, l2_F6
|
||||
/// @param[in] Ts - parts of the secret key: T1, T4, T3
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F( ext_cpk_t *Qs, const sk_t *Fs, const sk_t *Ts );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_RAINBOW_CYCLIC) || defined(_RAINBOW_CYCLIC_COMPRESSED)
|
||||
|
||||
|
||||
///
|
||||
/// @brief Computing parts of the sk from parts of pk and sk
|
||||
///
|
||||
/// @param[out] Fs - parts of the sk: l1_F1, l1_F2, l2_F1, l2_F2, l2_F3, l2_F5, l2_F6
|
||||
/// @param[in] Qs - parts of the pk: l1_Q1, l1_Q2, l2_Q1, l2_Q2, l2_Q3, l2_Q5, l2_Q6
|
||||
/// @param[in] Ts - parts of the sk: T1, T4, T3
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_F_from_Q( sk_t *Fs, const sk_t *Qs, sk_t *Ts );
|
||||
|
||||
///
|
||||
/// @brief Computing parts of the pk from the secret key
|
||||
///
|
||||
/// @param[out] Qs - parts of the pk: l1_Q3, l1_Q5, l2_Q6, l1_Q9, l2_Q9
|
||||
/// @param[in] Fs - parts of the sk: l1_F1, l1_F2, l2_F1, l2_F2, l2_F3, l2_F5, l2_F6
|
||||
/// @param[in] Ts - parts of the sk: T1, T4, T3
|
||||
///
|
||||
void PQCLEAN_RAINBOWIACYCLIC_CLEAN_calculate_Q_from_F_cyclic( cpk_t *Qs, const sk_t *Fs, const sk_t *Ts );
|
||||
#endif
|
||||
|
||||
#endif // _RAINBOW_KEYPAIR_COMP_H_
|
||||
|
148
crypto_sign/rainbowIa-cyclic/clean/sign.c
Normal file
148
crypto_sign/rainbowIa-cyclic/clean/sign.c
Normal file
@ -0,0 +1,148 @@
|
||||
/// @file sign.c
|
||||
/// @brief the implementations for functions in api.h
|
||||
///
|
||||
///
|
||||
|
||||
#include "api.h"
|
||||
#include "rainbow.h"
|
||||
#include "rainbow_config.h"
|
||||
#include "rainbow_keypair.h"
|
||||
#include "randombytes.h"
|
||||
#include "utils_hash.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
int
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk) {
|
||||
unsigned char sk_seed[LEN_SKSEED] = {0};
|
||||
randombytes( sk_seed, LEN_SKSEED );
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair( (pk_t *) pk, (sk_t *) sk, sk_seed );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
|
||||
unsigned char pk_seed[LEN_PKSEED] = {0};
|
||||
randombytes( pk_seed, LEN_PKSEED );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_keypair_cyclic( (cpk_t *) pk, (sk_t *) sk, pk_seed, sk_seed );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
unsigned char pk_seed[LEN_PKSEED] = {0};
|
||||
randombytes( pk_seed, LEN_PKSEED );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_generate_compact_keypair_cyclic( (cpk_t *) pk, (csk_t *) sk, pk_seed, sk_seed );
|
||||
|
||||
#else
|
||||
error here
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign(unsigned char *sm, size_t *smlen, const unsigned char *m, size_t mlen, const unsigned char *sk) {
|
||||
unsigned char digest[_HASH_LEN];
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( digest, _HASH_LEN, m, mlen );
|
||||
|
||||
memcpy( sm, m, mlen );
|
||||
smlen[0] = mlen + _SIGNATURE_BYTE;
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( sm + mlen, (const sk_t *)sk, digest );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( sm + mlen, (const sk_t *)sk, digest );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign_cyclic( sm + mlen, (const csk_t *)sk, digest );
|
||||
|
||||
#else
|
||||
error here
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_open(unsigned char *m, size_t *mlen, const unsigned char *sm, size_t smlen, const unsigned char *pk) {
|
||||
//TODO: this should not copy out the message if verification fails
|
||||
if ( _SIGNATURE_BYTE > smlen ) {
|
||||
return -1;
|
||||
}
|
||||
memcpy( m, sm, smlen - _SIGNATURE_BYTE );
|
||||
mlen[0] = smlen - _SIGNATURE_BYTE;
|
||||
|
||||
unsigned char digest[_HASH_LEN];
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( digest, _HASH_LEN, m, *mlen );
|
||||
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify( digest, sm + mlen[0], (const pk_t *)pk );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( digest, sm + mlen[0], (const cpk_t *)pk );
|
||||
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( digest, sm + mlen[0], (const cpk_t *)pk );
|
||||
|
||||
#else
|
||||
error here
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_signature(
|
||||
uint8_t *sig, size_t *siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *sk) {
|
||||
unsigned char digest[_HASH_LEN];
|
||||
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( digest, _HASH_LEN, m, mlen );
|
||||
*siglen = _SIGNATURE_BYTE;
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( sig, (const sk_t *)sk, digest );
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign( sig, (const sk_t *)sk, digest );
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_sign_cyclic( sig, (const csk_t *)sk, digest );
|
||||
#else
|
||||
error here
|
||||
#endif
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_crypto_sign_verify(
|
||||
const uint8_t *sig, size_t siglen,
|
||||
const uint8_t *m, size_t mlen, const uint8_t *pk) {
|
||||
if (siglen != _SIGNATURE_BYTE) {
|
||||
return -1;
|
||||
}
|
||||
unsigned char digest[_HASH_LEN];
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( digest, _HASH_LEN, m, mlen );
|
||||
#if defined _RAINBOW_CLASSIC
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify( digest, sig, (const pk_t *)pk );
|
||||
#elif defined _RAINBOW_CYCLIC
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( digest, sig, (const cpk_t *)pk );
|
||||
#elif defined _RAINBOW_CYCLIC_COMPRESSED
|
||||
return PQCLEAN_RAINBOWIACYCLIC_CLEAN_rainbow_verify_cyclic( digest, sig, (const cpk_t *)pk );
|
||||
#else
|
||||
error here
|
||||
#endif
|
||||
|
||||
}
|
63
crypto_sign/rainbowIa-cyclic/clean/utils_hash.c
Normal file
63
crypto_sign/rainbowIa-cyclic/clean/utils_hash.c
Normal file
@ -0,0 +1,63 @@
|
||||
/// @file utils_hash.c
|
||||
/// @brief the adapter for SHA2 families.
|
||||
///
|
||||
///
|
||||
|
||||
#include "rainbow_config.h"
|
||||
#include "sha2.h"
|
||||
#include "utils_hash.h"
|
||||
|
||||
static inline
|
||||
int _hash( unsigned char *digest, const unsigned char *m, size_t mlen ) {
|
||||
#if 32 == _HASH_LEN
|
||||
sha256(digest, m, mlen);
|
||||
#elif 48 == _HASH_LEN
|
||||
sha384(digest, m, mlen);
|
||||
#elif 64 == _HASH_LEN
|
||||
sha512(digest, m, mlen);
|
||||
#else
|
||||
#error "unsupported _HASH_LEN"
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
int expand_hash(unsigned char *digest, size_t n_digest, const unsigned char *hash) {
|
||||
if ( _HASH_LEN >= n_digest ) {
|
||||
for (size_t i = 0; i < n_digest; i++) {
|
||||
digest[i] = hash[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < _HASH_LEN; i++) {
|
||||
digest[i] = hash[i];
|
||||
}
|
||||
n_digest -= _HASH_LEN;
|
||||
|
||||
|
||||
while (_HASH_LEN <= n_digest ) {
|
||||
_hash( digest + _HASH_LEN, digest, _HASH_LEN );
|
||||
|
||||
n_digest -= _HASH_LEN;
|
||||
digest += _HASH_LEN;
|
||||
}
|
||||
unsigned char temp[_HASH_LEN];
|
||||
if ( n_digest ) {
|
||||
_hash( temp, digest, _HASH_LEN );
|
||||
for (size_t i = 0; i < n_digest; i++) {
|
||||
digest[_HASH_LEN + i] = temp[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg(unsigned char *digest,
|
||||
size_t len_digest,
|
||||
const unsigned char *m,
|
||||
size_t mlen) {
|
||||
unsigned char buf[_HASH_LEN];
|
||||
_hash(buf, m, mlen);
|
||||
return expand_hash(digest, len_digest, buf);
|
||||
}
|
||||
|
||||
|
14
crypto_sign/rainbowIa-cyclic/clean/utils_hash.h
Normal file
14
crypto_sign/rainbowIa-cyclic/clean/utils_hash.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _UTILS_HASH_H_
|
||||
#define _UTILS_HASH_H_
|
||||
/// @file utils_hash.h
|
||||
/// @brief the interface for adapting hash functions.
|
||||
///
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( unsigned char *digest, size_t len_digest, const unsigned char *m, size_t mlen );
|
||||
|
||||
|
||||
|
||||
#endif // _UTILS_HASH_H_
|
||||
|
96
crypto_sign/rainbowIa-cyclic/clean/utils_prng.c
Normal file
96
crypto_sign/rainbowIa-cyclic/clean/utils_prng.c
Normal file
@ -0,0 +1,96 @@
|
||||
/// @file utils_prng.c
|
||||
/// @brief The implementation of PRNG related functions.
|
||||
///
|
||||
|
||||
#include "aes.h"
|
||||
#include "randombytes.h"
|
||||
#include "utils_hash.h"
|
||||
#include "utils_prng.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void prng_update(const unsigned char *provided_data,
|
||||
unsigned char *Key,
|
||||
unsigned char *V) {
|
||||
unsigned char temp[48];
|
||||
aes256ctx ctx;
|
||||
aes256_keyexp(&ctx, Key);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
//increment V
|
||||
for (int j = 15; j >= 0; j--) {
|
||||
if ( V[j] == 0xff) {
|
||||
V[j] = 0x00;
|
||||
} else {
|
||||
V[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
aes256_ecb(temp + 16 * i, V, 1, &ctx);
|
||||
}
|
||||
if ( provided_data != NULL ) {
|
||||
for (int i = 0; i < 48; i++) {
|
||||
temp[i] ^= provided_data[i];
|
||||
}
|
||||
}
|
||||
memcpy(Key, temp, 32);
|
||||
memcpy(V, temp + 32, 16);
|
||||
}
|
||||
static void randombytes_init_with_state(prng_t *state,
|
||||
unsigned char *entropy_input_48bytes ) {
|
||||
memset(state->Key, 0x00, 32);
|
||||
memset(state->V, 0x00, 16);
|
||||
prng_update(entropy_input_48bytes, state->Key, state->V);
|
||||
}
|
||||
|
||||
static int randombytes_with_state(prng_t *state,
|
||||
unsigned char *x,
|
||||
size_t xlen) {
|
||||
|
||||
unsigned char block[16];
|
||||
int i = 0;
|
||||
|
||||
aes256ctx ctx;
|
||||
aes256_keyexp(&ctx, state->Key);
|
||||
|
||||
|
||||
while ( xlen > 0 ) {
|
||||
//increment V
|
||||
for (int j = 15; j >= 0; j--) {
|
||||
if ( state->V[j] == 0xff ) {
|
||||
state->V[j] = 0x00;
|
||||
} else {
|
||||
state->V[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
aes256_ecb(block, state->V, 1, &ctx);
|
||||
if ( xlen > 15 ) {
|
||||
memcpy(x + i, block, 16);
|
||||
i += 16;
|
||||
xlen -= 16;
|
||||
} else {
|
||||
memcpy(x + i, block, xlen);
|
||||
xlen = 0;
|
||||
}
|
||||
}
|
||||
prng_update(NULL, state->Key, state->V);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set(prng_t *ctx, const void *prng_seed, unsigned long prng_seedlen) {
|
||||
unsigned char seed[48];
|
||||
if ( prng_seedlen >= 48 ) {
|
||||
memcpy( seed, prng_seed, 48 );
|
||||
} else {
|
||||
memcpy( seed, prng_seed, prng_seedlen );
|
||||
PQCLEAN_RAINBOWIACYCLIC_CLEAN_hash_msg( seed + prng_seedlen, 48 - (unsigned)prng_seedlen, (const unsigned char *)prng_seed, prng_seedlen);
|
||||
}
|
||||
|
||||
randombytes_init_with_state( ctx, seed );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen(prng_t *ctx, unsigned char *out, unsigned long outlen) {
|
||||
return randombytes_with_state( ctx, out, outlen);
|
||||
}
|
22
crypto_sign/rainbowIa-cyclic/clean/utils_prng.h
Normal file
22
crypto_sign/rainbowIa-cyclic/clean/utils_prng.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef _UTILS_PRNG_H_
|
||||
#define _UTILS_PRNG_H_
|
||||
/// @file utils_prng.h
|
||||
/// @brief the interface for adapting PRNG functions.
|
||||
///
|
||||
///
|
||||
|
||||
|
||||
#include "randombytes.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned char Key[32];
|
||||
unsigned char V[16];
|
||||
} prng_t;
|
||||
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_set(prng_t *ctx, const void *prng_seed, unsigned long prng_seedlen);
|
||||
int PQCLEAN_RAINBOWIACYCLIC_CLEAN_prng_gen(prng_t *ctx, unsigned char *out, unsigned long outlen);
|
||||
|
||||
|
||||
#endif // _UTILS_PRNG_H_
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user