From 4f4ed3cc8b000b12924d8e0bf822b4ceca69044d Mon Sep 17 00:00:00 2001 From: "Matthias J. Kannwischer" Date: Wed, 8 May 2019 17:33:08 +0200 Subject: [PATCH] add newhope512cpa --- crypto_kem/newhope512cpa/META.yml | 20 + crypto_kem/newhope512cpa/clean/LICENSE | 1 + crypto_kem/newhope512cpa/clean/Makefile | 19 + .../clean/Makefile.Microsoft_nmake | 19 + crypto_kem/newhope512cpa/clean/api.h | 15 + crypto_kem/newhope512cpa/clean/cpapke.c | 192 +++++++++ crypto_kem/newhope512cpa/clean/cpapke.h | 16 + crypto_kem/newhope512cpa/clean/kem.c | 71 ++++ crypto_kem/newhope512cpa/clean/ntt.c | 112 ++++++ crypto_kem/newhope512cpa/clean/ntt.h | 14 + crypto_kem/newhope512cpa/clean/params.h | 25 ++ crypto_kem/newhope512cpa/clean/poly.c | 366 ++++++++++++++++++ crypto_kem/newhope512cpa/clean/poly.h | 32 ++ crypto_kem/newhope512cpa/clean/precomp.c | 179 +++++++++ crypto_kem/newhope512cpa/clean/reduce.c | 26 ++ crypto_kem/newhope512cpa/clean/reduce.h | 8 + crypto_kem/newhope512cpa/clean/verify.c | 49 +++ crypto_kem/newhope512cpa/clean/verify.h | 12 + 18 files changed, 1176 insertions(+) create mode 100644 crypto_kem/newhope512cpa/META.yml create mode 100644 crypto_kem/newhope512cpa/clean/LICENSE create mode 100644 crypto_kem/newhope512cpa/clean/Makefile create mode 100644 crypto_kem/newhope512cpa/clean/Makefile.Microsoft_nmake create mode 100644 crypto_kem/newhope512cpa/clean/api.h create mode 100644 crypto_kem/newhope512cpa/clean/cpapke.c create mode 100644 crypto_kem/newhope512cpa/clean/cpapke.h create mode 100644 crypto_kem/newhope512cpa/clean/kem.c create mode 100644 crypto_kem/newhope512cpa/clean/ntt.c create mode 100644 crypto_kem/newhope512cpa/clean/ntt.h create mode 100644 crypto_kem/newhope512cpa/clean/params.h create mode 100644 crypto_kem/newhope512cpa/clean/poly.c create mode 100644 crypto_kem/newhope512cpa/clean/poly.h create mode 100644 crypto_kem/newhope512cpa/clean/precomp.c create mode 100644 crypto_kem/newhope512cpa/clean/reduce.c create mode 100644 crypto_kem/newhope512cpa/clean/reduce.h create mode 100644 crypto_kem/newhope512cpa/clean/verify.c create mode 100644 crypto_kem/newhope512cpa/clean/verify.h diff --git a/crypto_kem/newhope512cpa/META.yml b/crypto_kem/newhope512cpa/META.yml new file mode 100644 index 00000000..8db17433 --- /dev/null +++ b/crypto_kem/newhope512cpa/META.yml @@ -0,0 +1,20 @@ +name: NewHope512CPA +type: kem +claimed-nist-level: 1 +length-public-key: 928 +length-secret-key: 896 +length-ciphertext: 1088 +length-shared-secret: 32 +nistkat-sha256: 42444446b96f45c9b7221c4fde8afd5dfc0b3c2ff05b9a88ff12ea3949fbb76c +principal-submitter: Thomas Pöppelmann +auxiliary-submitters: +- Erdem Alkim +- Roberto Avanzi +- Joppe Bos +- Léo Ducas +- Antonio de la Piedra +- Peter Schwabe +- Douglas Stebila +implementations: +- name: clean + version: https://github.com/newhopecrypto/newhope/commit/3fc68c6090b23c56cc190a78af2f43ee8900e9d0 diff --git a/crypto_kem/newhope512cpa/clean/LICENSE b/crypto_kem/newhope512cpa/clean/LICENSE new file mode 100644 index 00000000..d5d21fff --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/LICENSE @@ -0,0 +1 @@ +Public Domain diff --git a/crypto_kem/newhope512cpa/clean/Makefile b/crypto_kem/newhope512cpa/clean/Makefile new file mode 100644 index 00000000..8f5967d5 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/Makefile @@ -0,0 +1,19 @@ +# This Makefile can be used with GNU Make or BSD Make + +LIB=libnewhope512cpa_clean.a +HEADERS=api.h cpapke.h ntt.h params.h poly.h reduce.h verify.h +OBJECTS=cpapke.o kem.o ntt.o poly.o precomp.o reduce.o verify.o + +CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wvla -Werror -Wmissing-prototypes -std=c99 -I../../../common $(EXTRAFLAGS) + +all: $(LIB) + +%.o: %.c $(HEADERS) + $(CC) $(CFLAGS) -c -o $@ $< + +$(LIB): $(OBJECTS) + $(AR) -r $@ $(OBJECTS) + +clean: + $(RM) $(OBJECTS) + $(RM) $(LIB) diff --git a/crypto_kem/newhope512cpa/clean/Makefile.Microsoft_nmake b/crypto_kem/newhope512cpa/clean/Makefile.Microsoft_nmake new file mode 100644 index 00000000..249a7d1f --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/Makefile.Microsoft_nmake @@ -0,0 +1,19 @@ +# This Makefile can be used with Microsoft Visual Studio's nmake using the command: +# nmake /f Makefile.Microsoft_nmake + +LIBRARY=libnewhope512cpa_clean.lib +OBJECTS=cpapke.obj kem.obj ntt.obj poly.obj precomp.obj reduce.obj verify.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) diff --git a/crypto_kem/newhope512cpa/clean/api.h b/crypto_kem/newhope512cpa/clean/api.h new file mode 100644 index 00000000..791d72af --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/api.h @@ -0,0 +1,15 @@ +#ifndef PQCLEAN_NEWHOPE512CPA_CLEAN_API_H +#define PQCLEAN_NEWHOPE512CPA_CLEAN_API_H + + +#define PQCLEAN_NEWHOPE512CPA_CLEAN_CRYPTO_SECRETKEYBYTES 896 +#define PQCLEAN_NEWHOPE512CPA_CLEAN_CRYPTO_PUBLICKEYBYTES 928 +#define PQCLEAN_NEWHOPE512CPA_CLEAN_CRYPTO_CIPHERTEXTBYTES 1088 +#define PQCLEAN_NEWHOPE512CPA_CLEAN_CRYPTO_BYTES 32 +#define PQCLEAN_NEWHOPE512CPA_CLEAN_CRYPTO_ALGNAME "NewHope512-CPAKEM" + +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk); +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk); +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk); + +#endif diff --git a/crypto_kem/newhope512cpa/clean/cpapke.c b/crypto_kem/newhope512cpa/clean/cpapke.c new file mode 100644 index 00000000..dbcc3434 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/cpapke.c @@ -0,0 +1,192 @@ +#include "api.h" +#include "cpapke.h" +#include "fips202.h" +#include "poly.h" +#include "randombytes.h" +#include + +/************************************************* +* Name: encode_pk +* +* Description: Serialize the public key as concatenation of the +* serialization of the polynomial pk and the public seed +* used to generete the polynomial a. +* +* Arguments: unsigned char *r: pointer to the output serialized public key +* const poly *pk: pointer to the input public-key polynomial +* const unsigned char *seed: pointer to the input public seed +**************************************************/ +static void encode_pk(unsigned char *r, const poly *pk, const unsigned char *seed) { + int i; + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tobytes(r, pk); + for (i = 0; i < NEWHOPE_SYMBYTES; i++) { + r[NEWHOPE_POLYBYTES + i] = seed[i]; + } +} + +/************************************************* +* Name: decode_pk +* +* Description: De-serialize the public key; inverse of encode_pk +* +* Arguments: poly *pk: pointer to output public-key polynomial +* unsigned char *seed: pointer to output public seed +* const unsigned char *r: pointer to input byte array +**************************************************/ +static void decode_pk(poly *pk, unsigned char *seed, const unsigned char *r) { + int i; + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frombytes(pk, r); + for (i = 0; i < NEWHOPE_SYMBYTES; i++) { + seed[i] = r[NEWHOPE_POLYBYTES + i]; + } +} + +/************************************************* +* Name: encode_c +* +* Description: Serialize the ciphertext as concatenation of the +* serialization of the polynomial b and serialization +* of the compressed polynomial v +* +* Arguments: - unsigned char *r: pointer to the output serialized ciphertext +* - const poly *b: pointer to the input polynomial b +* - const poly *v: pointer to the input polynomial v +**************************************************/ +static void encode_c(unsigned char *r, const poly *b, const poly *v) { + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tobytes(r, b); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_compress(r + NEWHOPE_POLYBYTES, v); +} + +/************************************************* +* Name: decode_c +* +* Description: de-serialize the ciphertext; inverse of encode_c +* +* Arguments: - poly *b: pointer to output polynomial b +* - poly *v: pointer to output polynomial v +* - const unsigned char *r: pointer to input byte array +**************************************************/ +static void decode_c(poly *b, poly *v, const unsigned char *r) { + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frombytes(b, r); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_decompress(v, r + NEWHOPE_POLYBYTES); +} + +/************************************************* +* Name: gen_a +* +* Description: Deterministically generate public polynomial a from seed +* +* Arguments: - poly *a: pointer to output polynomial a +* - const unsigned char *seed: pointer to input seed +**************************************************/ +static void gen_a(poly *a, const unsigned char *seed) { + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_uniform(a, seed); +} + + +/************************************************* +* Name: cpapke_keypair +* +* Description: Generates public and private key +* for the CPA public-key encryption scheme underlying +* the NewHope KEMs +* +* Arguments: - unsigned char *pk: pointer to output public key +* - unsigned char *sk: pointer to output private key +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_keypair(unsigned char *pk, + unsigned char *sk) { + poly ahat, ehat, ahat_shat, bhat, shat; + unsigned char z[2 * NEWHOPE_SYMBYTES]; + unsigned char *publicseed = z; + unsigned char *noiseseed = z + NEWHOPE_SYMBYTES; + + randombytes(z, NEWHOPE_SYMBYTES); + shake256(z, 2 * NEWHOPE_SYMBYTES, z, NEWHOPE_SYMBYTES); + + gen_a(&ahat, publicseed); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(&shat, noiseseed, 0); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(&shat); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(&ehat, noiseseed, 1); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(&ehat); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(&ahat_shat, &shat, &ahat); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(&bhat, &ehat, &ahat_shat); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tobytes(sk, &shat); + encode_pk(pk, &bhat, publicseed); +} + +/************************************************* +* Name: cpapke_enc +* +* Description: Encryption function of +* the CPA public-key encryption scheme underlying +* the NewHope KEMs +* +* Arguments: - unsigned char *c: pointer to output ciphertext +* - const unsigned char *m: pointer to input message (of length NEWHOPE_SYMBYTES bytes) +* - const unsigned char *pk: pointer to input public key +* - const unsigned char *coin: pointer to input random coins used as seed +* to deterministically generate all randomness +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_enc(unsigned char *c, + const unsigned char *m, + const unsigned char *pk, + const unsigned char *coin) { + poly sprime, eprime, vprime, ahat, bhat, eprimeprime, uhat, v; + unsigned char publicseed[NEWHOPE_SYMBYTES]; + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frommsg(&v, m); + + decode_pk(&bhat, publicseed, pk); + gen_a(&ahat, publicseed); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(&sprime, coin, 0); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(&eprime, coin, 1); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(&eprimeprime, coin, 2); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(&sprime); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(&eprime); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(&uhat, &ahat, &sprime); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(&uhat, &uhat, &eprime); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(&vprime, &bhat, &sprime); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_invntt(&vprime); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(&vprime, &vprime, &eprimeprime); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(&vprime, &vprime, &v); // add message + + encode_c(c, &uhat, &vprime); +} + + +/************************************************* +* Name: cpapke_dec +* +* Description: Decryption function of +* the CPA public-key encryption scheme underlying +* the NewHope KEMs +* +* Arguments: - unsigned char *m: pointer to output decrypted message +* - const unsigned char *c: pointer to input ciphertext +* - const unsigned char *sk: pointer to input secret key +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_dec(unsigned char *m, + const unsigned char *c, + const unsigned char *sk) { + poly vprime, uhat, tmp, shat; + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frombytes(&shat, sk); + + decode_c(&uhat, &vprime, c); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(&tmp, &shat, &uhat); + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_invntt(&tmp); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sub(&tmp, &tmp, &vprime); + + PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tomsg(m, &tmp); +} diff --git a/crypto_kem/newhope512cpa/clean/cpapke.h b/crypto_kem/newhope512cpa/clean/cpapke.h new file mode 100644 index 00000000..43539e07 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/cpapke.h @@ -0,0 +1,16 @@ +#ifndef INDCPA_H +#define INDCPA_H + +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_keypair(unsigned char *pk, + unsigned char *sk); + +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_enc(unsigned char *c, + const unsigned char *m, + const unsigned char *pk, + const unsigned char *coins); + +void PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_dec(unsigned char *m, + const unsigned char *c, + const unsigned char *sk); + +#endif diff --git a/crypto_kem/newhope512cpa/clean/kem.c b/crypto_kem/newhope512cpa/clean/kem.c new file mode 100644 index 00000000..95fbd4ff --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/kem.c @@ -0,0 +1,71 @@ +#include "api.h" +#include "cpapke.h" +#include "fips202.h" +#include "params.h" +#include "randombytes.h" +#include "verify.h" +#include + +/************************************************* +* Name: crypto_kem_keypair +* +* Description: Generates public and private key +* for CCA secure NewHope key encapsulation +* mechanism +* +* Arguments: - unsigned char *pk: pointer to output public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) +* - unsigned char *sk: pointer to output private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { + PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_keypair(pk, sk); /* First put the actual secret key into sk */ + + return 0; +} + +/************************************************* +* Name: crypto_kem_enc +* +* Description: Generates cipher text and shared +* secret for given public key +* +* Arguments: - unsigned char *ct: pointer to output cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) +* - unsigned char *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) +* - const unsigned char *pk: pointer to input public key (an already allocated array of CRYPTO_PUBLICKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk) { + unsigned char buf[2 * NEWHOPE_SYMBYTES]; + + randombytes(buf, NEWHOPE_SYMBYTES); + + shake256(buf, 2 * NEWHOPE_SYMBYTES, buf, NEWHOPE_SYMBYTES); /* Don't release system RNG output */ + + PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_enc(ct, buf, pk, buf + NEWHOPE_SYMBYTES); /* coins are in buf+NEWHOPE_SYMBYTES */ + + shake256(ss, NEWHOPE_SYMBYTES, buf, NEWHOPE_SYMBYTES); /* hash pre-k to ss */ + return 0; +} + + +/************************************************* +* Name: crypto_kem_dec +* +* Description: Generates shared secret for given +* cipher text and private key +* +* Arguments: - unsigned char *ss: pointer to output shared secret (an already allocated array of CRYPTO_BYTES bytes) +* - const unsigned char *ct: pointer to input cipher text (an already allocated array of CRYPTO_CIPHERTEXTBYTES bytes) +* - const unsigned char *sk: pointer to input private key (an already allocated array of CRYPTO_SECRETKEYBYTES bytes) +* +* Returns 0 (success) +**************************************************/ +int PQCLEAN_NEWHOPE512CPA_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk) { + PQCLEAN_NEWHOPE512CPA_CLEAN_cpapke_dec(ss, ct, sk); + + shake256(ss, NEWHOPE_SYMBYTES, ss, NEWHOPE_SYMBYTES); /* hash pre-k to ss */ + + return 0; +} diff --git a/crypto_kem/newhope512cpa/clean/ntt.c b/crypto_kem/newhope512cpa/clean/ntt.c new file mode 100644 index 00000000..7a449088 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/ntt.c @@ -0,0 +1,112 @@ +#include "inttypes.h" +#include "ntt.h" +#include "params.h" +#include "reduce.h" + +/************************************************************ +* Name: bitrev_table +* +* Description: Contains bit-reversed 9-bit indices to be used to re-order +* polynomials before number theoratic transform +************************************************************/ +static uint16_t bitrev_table [512] = { + 0, 256, 128, 384, 64, 320, 192, 448, 32, 288, 160, 416, 96, 352, 224, 480, 16, 272, 144, 400, 80, 336, 208, 464, 48, 304, 176, 432, 112, 368, 240, 496, 8, + 264, 136, 392, 72, 328, 200, 456, 40, 296, 168, 424, 104, 360, 232, 488, 24, 280, 152, 408, 88, 344, 216, 472, 56, 312, 184, 440, 120, 376, 248, 504, 4, + 260, 132, 388, 68, 324, 196, 452, 36, 292, 164, 420, 100, 356, 228, 484, 20, 276, 148, 404, 84, 340, 212, 468, 52, 308, 180, 436, 116, 372, 244, 500, 12, + 268, 140, 396, 76, 332, 204, 460, 44, 300, 172, 428, 108, 364, 236, 492, 28, 284, 156, 412, 92, 348, 220, 476, 60, 316, 188, 444, 124, 380, 252, 508, 2, + 258, 130, 386, 66, 322, 194, 450, 34, 290, 162, 418, 98, 354, 226, 482, 18, 274, 146, 402, 82, 338, 210, 466, 50, 306, 178, 434, 114, 370, 242, 498, 10, + 266, 138, 394, 74, 330, 202, 458, 42, 298, 170, 426, 106, 362, 234, 490, 26, 282, 154, 410, 90, 346, 218, 474, 58, 314, 186, 442, 122, 378, 250, 506, 6, + 262, 134, 390, 70, 326, 198, 454, 38, 294, 166, 422, 102, 358, 230, 486, 22, 278, 150, 406, 86, 342, 214, 470, 54, 310, 182, 438, 118, 374, 246, 502, 14, + 270, 142, 398, 78, 334, 206, 462, 46, 302, 174, 430, 110, 366, 238, 494, 30, 286, 158, 414, 94, 350, 222, 478, 62, 318, 190, 446, 126, 382, 254, 510, 1, + 257, 129, 385, 65, 321, 193, 449, 33, 289, 161, 417, 97, 353, 225, 481, 17, 273, 145, 401, 81, 337, 209, 465, 49, 305, 177, 433, 113, 369, 241, 497, 9, + 265, 137, 393, 73, 329, 201, 457, 41, 297, 169, 425, 105, 361, 233, 489, 25, 281, 153, 409, 89, 345, 217, 473, 57, 313, 185, 441, 121, 377, 249, 505, 5, + 261, 133, 389, 69, 325, 197, 453, 37, 293, 165, 421, 101, 357, 229, 485, 21, 277, 149, 405, 85, 341, 213, 469, 53, 309, 181, 437, 117, 373, 245, 501, 13, + 269, 141, 397, 77, 333, 205, 461, 45, 301, 173, 429, 109, 365, 237, 493, 29, 285, 157, 413, 93, 349, 221, 477, 61, 317, 189, 445, 125, 381, 253, 509, 3, + 259, 131, 387, 67, 323, 195, 451, 35, 291, 163, 419, 99, 355, 227, 483, 19, 275, 147, 403, 83, 339, 211, 467, 51, 307, 179, 435, 115, 371, 243, 499, 11, + 267, 139, 395, 75, 331, 203, 459, 43, 299, 171, 427, 107, 363, 235, 491, 27, 283, 155, 411, 91, 347, 219, 475, 59, 315, 187, 443, 123, 379, 251, 507, 7, + 263, 135, 391, 71, 327, 199, 455, 39, 295, 167, 423, 103, 359, 231, 487, 23, 279, 151, 407, 87, 343, 215, 471, 55, 311, 183, 439, 119, 375, 247, 503, 15, + 271, 143, 399, 79, 335, 207, 463, 47, 303, 175, 431, 111, 367, 239, 495, 31, 287, 159, 415, 95, 351, 223, 479, 63, 319, 191, 447, 127, 383, 255, 511 +}; + +/************************************************* +* Name: bitrev_vector +* +* Description: Permutes coefficients of a polynomial into bitreversed order +* +* Arguments: - uint16_t* poly: pointer to in/output polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_bitrev_vector(uint16_t *poly) { + unsigned int i, r; + uint16_t tmp; + + for (i = 0; i < NEWHOPE_N; i++) { + r = bitrev_table[i]; + if (i < r) { + tmp = poly[i]; + poly[i] = poly[r]; + poly[r] = tmp; + } + } +} + +/************************************************* +* Name: mul_coefficients +* +* Description: Performs pointwise (coefficient-wise) multiplication +* of two polynomials +* Arguments: - uint16_t* poly: pointer to in/output polynomial +* - const uint16_t* factors: pointer to input polynomial, coefficients +* are assumed to be in Montgomery representation +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_mul_coefficients(uint16_t *poly, const uint16_t *factors) { + unsigned int i; + + for (i = 0; i < NEWHOPE_N; i++) { + poly[i] = PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce((poly[i] * factors[i])); + } +} + + +/************************************************* +* Name: ntt +* +* Description: Computes number-theoretic transform (NTT) of +* a polynomial in place; inputs assumed to be in +* bitreversed order, output in normal order +* +* Arguments: - uint16_t * a: pointer to in/output polynomial +* - const uint16_t* omega: pointer to input powers of root of unity omega; +* assumed to be in Montgomery domain +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_ntt(uint16_t *a, const uint16_t *omega) { + int i, start, j, jTwiddle, distance; + uint16_t temp, W; + + + for (i = 0; i < 9; i += 2) { + // Even level + distance = (1 << i); + for (start = 0; start < distance; start++) { + jTwiddle = 0; + for (j = start; j < NEWHOPE_N - 1; j += 2 * distance) { + W = omega[jTwiddle++]; + temp = a[j]; + a[j] = (temp + a[j + distance]); // Omit reduction (be lazy) + a[j + distance] = PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce((W * ((uint32_t)temp + 3 * NEWHOPE_Q - a[j + distance]))); + } + } + if (i + 1 < 9) { + // Odd level + distance <<= 1; + for (start = 0; start < distance; start++) { + jTwiddle = 0; + for (j = start; j < NEWHOPE_N - 1; j += 2 * distance) { + W = omega[jTwiddle++]; + temp = a[j]; + a[j] = (temp + a[j + distance]) % NEWHOPE_Q; + a[j + distance] = PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce((W * ((uint32_t)temp + 3 * NEWHOPE_Q - a[j + distance]))); + } + } + } + } +} diff --git a/crypto_kem/newhope512cpa/clean/ntt.h b/crypto_kem/newhope512cpa/clean/ntt.h new file mode 100644 index 00000000..6d17c247 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/ntt.h @@ -0,0 +1,14 @@ +#ifndef NTT_H +#define NTT_H + +#include "inttypes.h" + +extern const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_omegas_inv_bitrev_montgomery[]; +extern const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_bitrev_montgomery[]; +extern const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_inv_montgomery[]; + +void PQCLEAN_NEWHOPE512CPA_CLEAN_bitrev_vector(uint16_t *poly); +void PQCLEAN_NEWHOPE512CPA_CLEAN_mul_coefficients(uint16_t *poly, const uint16_t *factors); +void PQCLEAN_NEWHOPE512CPA_CLEAN_ntt(uint16_t *a, const uint16_t *omegas); + +#endif diff --git a/crypto_kem/newhope512cpa/clean/params.h b/crypto_kem/newhope512cpa/clean/params.h new file mode 100644 index 00000000..f9de0856 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/params.h @@ -0,0 +1,25 @@ +#ifndef PQCLEAN_NEWHOPE512CPA_CLEAN_PARAMS_H +#define PQCLEAN_NEWHOPE512CPA_CLEAN_PARAMS_H + +#define NEWHOPE_N 512 +#define NEWHOPE_Q 12289 +#define NEWHOPE_K 8 /* used in noise sampling */ + +#define NEWHOPE_SYMBYTES 32 /* size of shared key, seeds/coins, and hashes */ + +#define NEWHOPE_POLYBYTES ((14*NEWHOPE_N)/8) +#define NEWHOPE_POLYCOMPRESSEDBYTES (( 3*NEWHOPE_N)/8) + +#define NEWHOPE_CPAPKE_PUBLICKEYBYTES (NEWHOPE_POLYBYTES + NEWHOPE_SYMBYTES) +#define NEWHOPE_CPAPKE_SECRETKEYBYTES (NEWHOPE_POLYBYTES) +#define NEWHOPE_CPAPKE_CIPHERTEXTBYTES (NEWHOPE_POLYBYTES + NEWHOPE_POLYCOMPRESSEDBYTES) + +#define NEWHOPE_CPAKEM_PUBLICKEYBYTES NEWHOPE_CPAPKE_PUBLICKEYBYTES +#define NEWHOPE_CPAKEM_SECRETKEYBYTES NEWHOPE_CPAPKE_SECRETKEYBYTES +#define NEWHOPE_CPAKEM_CIPHERTEXTBYTES NEWHOPE_CPAPKE_CIPHERTEXTBYTES + +#define NEWHOPE_CCAKEM_PUBLICKEYBYTES NEWHOPE_CPAPKE_PUBLICKEYBYTES +#define NEWHOPE_CCAKEM_SECRETKEYBYTES (NEWHOPE_CPAPKE_SECRETKEYBYTES + NEWHOPE_CPAPKE_PUBLICKEYBYTES + 2*NEWHOPE_SYMBYTES) +#define NEWHOPE_CCAKEM_CIPHERTEXTBYTES (NEWHOPE_CPAPKE_CIPHERTEXTBYTES + NEWHOPE_SYMBYTES) /* Second part is for Targhi-Unruh */ + +#endif diff --git a/crypto_kem/newhope512cpa/clean/poly.c b/crypto_kem/newhope512cpa/clean/poly.c new file mode 100644 index 00000000..cd6cac24 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/poly.c @@ -0,0 +1,366 @@ +#include "fips202.h" +#include "ntt.h" +#include "poly.h" +#include "reduce.h" + +/************************************************* +* Name: coeff_freeze +* +* Description: Fully reduces an integer modulo q in constant time +* +* Arguments: uint16_t x: input integer to be reduced +* +* Returns integer in {0,...,q-1} congruent to x modulo q +**************************************************/ +static uint16_t coeff_freeze(uint16_t x) { + uint16_t m, r; + int16_t c; + r = x % NEWHOPE_Q; + + m = r - NEWHOPE_Q; + c = m; + c >>= 15; + r = m ^ ((r ^ m)&c); + + return r; +} + +/************************************************* +* Name: flipabs +* +* Description: Computes |(x mod q) - Q/2| +* +* Arguments: uint16_t x: input coefficient +* +* Returns |(x mod q) - Q/2| +**************************************************/ +static uint16_t flipabs(uint16_t x) { + int16_t r, m; + r = coeff_freeze(x); + + r = r - NEWHOPE_Q / 2; + m = r >> 15; + return (r + m) ^ m; +} + +/************************************************* +* Name: poly_frombytes +* +* Description: De-serialization of a polynomial +* +* Arguments: - poly *r: pointer to output polynomial +* - const unsigned char *a: pointer to input byte array +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frombytes(poly *r, const unsigned char *a) { + int i; + for (i = 0; i < NEWHOPE_N / 4; i++) { + r->coeffs[4 * i + 0] = a[7 * i + 0] | (((uint16_t)a[7 * i + 1] & 0x3f) << 8); + r->coeffs[4 * i + 1] = (a[7 * i + 1] >> 6) | (((uint16_t)a[7 * i + 2]) << 2) | (((uint16_t)a[7 * i + 3] & 0x0f) << 10); + r->coeffs[4 * i + 2] = (a[7 * i + 3] >> 4) | (((uint16_t)a[7 * i + 4]) << 4) | (((uint16_t)a[7 * i + 5] & 0x03) << 12); + r->coeffs[4 * i + 3] = (a[7 * i + 5] >> 2) | (((uint16_t)a[7 * i + 6]) << 6); + } +} + +/************************************************* +* Name: poly_tobytes +* +* Description: Serialization of a polynomial +* +* Arguments: - unsigned char *r: pointer to output byte array +* - const poly *p: pointer to input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tobytes(unsigned char *r, const poly *p) { + int i; + uint16_t t0, t1, t2, t3; + for (i = 0; i < NEWHOPE_N / 4; i++) { + t0 = coeff_freeze(p->coeffs[4 * i + 0]); + t1 = coeff_freeze(p->coeffs[4 * i + 1]); + t2 = coeff_freeze(p->coeffs[4 * i + 2]); + t3 = coeff_freeze(p->coeffs[4 * i + 3]); + + r[7 * i + 0] = t0 & 0xff; + r[7 * i + 1] = (unsigned char) ((t0 >> 8) | (t1 << 6)); + r[7 * i + 2] = (unsigned char) ((t1 >> 2)); + r[7 * i + 3] = (unsigned char) ((t1 >> 10) | (t2 << 4)); + r[7 * i + 4] = (unsigned char) ((t2 >> 4)); + r[7 * i + 5] = (unsigned char) ((t2 >> 12) | (t3 << 2)); + r[7 * i + 6] = (unsigned char) ((t3 >> 6)); + } +} + +/************************************************* +* Name: poly_compress +* +* Description: Compression and subsequent serialization of a polynomial +* +* Arguments: - unsigned char *r: pointer to output byte array +* - const poly *p: pointer to input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_compress(unsigned char *r, const poly *p) { + unsigned int i, j, k = 0; + + uint32_t t[8]; + + for (i = 0; i < NEWHOPE_N; i += 8) { + for (j = 0; j < 8; j++) { + t[j] = coeff_freeze(p->coeffs[i + j]); + t[j] = (((t[j] << 3) + NEWHOPE_Q / 2) / NEWHOPE_Q) & 0x7; + } + + r[k] = (unsigned char) (t[0] | (t[1] << 3) | (t[2] << 6)); + r[k + 1] = (unsigned char) ((t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7)); + r[k + 2] = (unsigned char) ((t[5] >> 1) | (t[6] << 2) | (t[7] << 5)); + k += 3; + } +} + +/************************************************* +* Name: poly_decompress +* +* Description: De-serialization and subsequent decompression of a polynomial; +* approximate inverse of poly_compress +* +* Arguments: - poly *r: pointer to output polynomial +* - const unsigned char *a: pointer to input byte array +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_decompress(poly *r, const unsigned char *a) { + unsigned int i, j; + for (i = 0; i < NEWHOPE_N; i += 8) { + r->coeffs[i + 0] = a[0] & 7; + r->coeffs[i + 1] = (a[0] >> 3) & 7; + r->coeffs[i + 2] = (a[0] >> 6) | ((a[1] << 2) & 4); + r->coeffs[i + 3] = (a[1] >> 1) & 7; + r->coeffs[i + 4] = (a[1] >> 4) & 7; + r->coeffs[i + 5] = (a[1] >> 7) | ((a[2] << 1) & 6); + r->coeffs[i + 6] = (a[2] >> 2) & 7; + r->coeffs[i + 7] = (a[2] >> 5); + a += 3; + for (j = 0; j < 8; j++) { + r->coeffs[i + j] = ((uint32_t)r->coeffs[i + j] * NEWHOPE_Q + 4) >> 3; + } + } +} + +/************************************************* +* Name: poly_frommsg +* +* Description: Convert 32-byte message to polynomial +* +* Arguments: - poly *r: pointer to output polynomial +* - const unsigned char *msg: pointer to input message +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frommsg(poly *r, const unsigned char *msg) { + unsigned int i, j, mask; + for (i = 0; i < 32; i++) { // XXX: MACRO for 32 + for (j = 0; j < 8; j++) { + mask = -((msg[i] >> j) & 1); + r->coeffs[8 * i + j + 0] = mask & (NEWHOPE_Q / 2); + r->coeffs[8 * i + j + 256] = mask & (NEWHOPE_Q / 2); + } + } +} + +/************************************************* +* Name: poly_tomsg +* +* Description: Convert polynomial to 32-byte message +* +* Arguments: - unsigned char *msg: pointer to output message +* - const poly *x: pointer to input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tomsg(unsigned char *msg, const poly *x) { + unsigned int i; + uint16_t t; + + for (i = 0; i < 32; i++) { + msg[i] = 0; + } + + for (i = 0; i < 256; i++) { + t = flipabs(x->coeffs[i + 0]); + t += flipabs(x->coeffs[i + 256]); + t = ((t - NEWHOPE_Q / 2)); + + t >>= 15; + msg[i >> 3] |= t << (i & 7); + } +} + +/************************************************* +* Name: poly_uniform +* +* Description: Sample a polynomial deterministically from a seed, +* with output polynomial looking uniformly random +* +* Arguments: - poly *a: pointer to output polynomial +* - const unsigned char *seed: pointer to input seed +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_uniform(poly *a, const unsigned char *seed) { + unsigned int ctr = 0; + uint16_t val; + uint64_t state[25]; + uint8_t buf[SHAKE128_RATE]; + uint8_t extseed[NEWHOPE_SYMBYTES + 1]; + int i, j; + + for (i = 0; i < NEWHOPE_SYMBYTES; i++) { + extseed[i] = seed[i]; + } + + for (i = 0; i < NEWHOPE_N / 64; i++) { /* generate a in blocks of 64 coefficients */ + ctr = 0; + extseed[NEWHOPE_SYMBYTES] = (unsigned char) i; /* domain-separate the 16 independent calls */ + shake128_absorb(state, extseed, NEWHOPE_SYMBYTES + 1); + while (ctr < 64) { /* Very unlikely to run more than once */ + shake128_squeezeblocks(buf, 1, state); + for (j = 0; j < SHAKE128_RATE && ctr < 64; j += 2) { + val = (buf[j] | ((uint16_t) buf[j + 1] << 8)); + if (val < 5 * NEWHOPE_Q) { + a->coeffs[i * 64 + ctr] = val; + ctr++; + } + } + } + } +} + +/************************************************* +* Name: hw +* +* Description: Compute the Hamming weight of a byte +* +* Arguments: - unsigned char a: input byte +**************************************************/ +static unsigned char hw(unsigned char a) { + unsigned char i, r = 0; + for (i = 0; i < 8; i++) { + r += (a >> i) & 1; + } + return r; +} + +/************************************************* +* Name: poly_sample +* +* Description: Sample a polynomial deterministically from a seed and a nonce, +* with output polynomial close to centered binomial distribution +* with parameter k=8 +* +* Arguments: - poly *r: pointer to output polynomial +* - const unsigned char *seed: pointer to input seed +* - unsigned char nonce: one-byte input nonce +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(poly *r, const unsigned char *seed, unsigned char nonce) { + unsigned char buf[128], a, b; +// uint32_t t, d, a, b, c; + int i, j; + + unsigned char extseed[NEWHOPE_SYMBYTES + 2]; + + for (i = 0; i < NEWHOPE_SYMBYTES; i++) { + extseed[i] = seed[i]; + } + extseed[NEWHOPE_SYMBYTES] = nonce; + + for (i = 0; i < NEWHOPE_N / 64; i++) { /* Generate noise in blocks of 64 coefficients */ + extseed[NEWHOPE_SYMBYTES + 1] = (unsigned char) i; + shake256(buf, 128, extseed, NEWHOPE_SYMBYTES + 2); + for (j = 0; j < 64; j++) { + a = buf[2 * j]; + b = buf[2 * j + 1]; + r->coeffs[64 * i + j] = hw(a) + NEWHOPE_Q - hw(b); + /* + t = buf[j] | ((uint32_t)buf[j+1] << 8) | ((uint32_t)buf[j+2] << 16) | ((uint32_t)buf[j+3] << 24); + d = 0; + for(k=0;k<8;k++) + d += (t >> k) & 0x01010101; + a = d & 0xff; + b = ((d >> 8) & 0xff); + c = ((d >> 16) & 0xff); + d >>= 24; + r->coeffs[64*i+j/2] = a + NEWHOPE_Q - b; + r->coeffs[64*i+j/2+1] = c + NEWHOPE_Q - d; + */ + } + } +} + +/************************************************* +* Name: poly_pointwise +* +* Description: Multiply two polynomials pointwise (i.e., coefficient-wise). +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(poly *r, const poly *a, const poly *b) { + int i; + uint16_t t; + for (i = 0; i < NEWHOPE_N; i++) { + t = PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce(3186 * b->coeffs[i]); /* t is now in Montgomery domain */ + r->coeffs[i] = PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce(a->coeffs[i] * t); /* r->coeffs[i] is back in normal domain */ + } +} + +/************************************************* +* Name: poly_add +* +* Description: Add two polynomials +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(poly *r, const poly *a, const poly *b) { + int i; + for (i = 0; i < NEWHOPE_N; i++) { + r->coeffs[i] = (a->coeffs[i] + b->coeffs[i]) % NEWHOPE_Q; + } +} + +/************************************************* +* Name: poly_sub +* +* Description: Subtract two polynomials +* +* Arguments: - poly *r: pointer to output polynomial +* - const poly *a: pointer to first input polynomial +* - const poly *b: pointer to second input polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sub(poly *r, const poly *a, const poly *b) { + int i; + for (i = 0; i < NEWHOPE_N; i++) { + r->coeffs[i] = (a->coeffs[i] + 3 * NEWHOPE_Q - b->coeffs[i]) % NEWHOPE_Q; + } +} + +/************************************************* +* Name: poly_ntt +* +* Description: Forward NTT transform of a polynomial in place +* Input is assumed to have coefficients in bitreversed order +* Output has coefficients in normal order +* +* Arguments: - poly *r: pointer to in/output polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(poly *r) { + PQCLEAN_NEWHOPE512CPA_CLEAN_mul_coefficients(r->coeffs, PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_bitrev_montgomery); + PQCLEAN_NEWHOPE512CPA_CLEAN_ntt((uint16_t *)r->coeffs, PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_bitrev_montgomery); +} + +/************************************************* +* Name: poly_invntt +* +* Description: Inverse NTT transform of a polynomial in place +* Input is assumed to have coefficients in normal order +* Output has coefficients in normal order +* +* Arguments: - poly *r: pointer to in/output polynomial +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_invntt(poly *r) { + PQCLEAN_NEWHOPE512CPA_CLEAN_bitrev_vector(r->coeffs); + PQCLEAN_NEWHOPE512CPA_CLEAN_ntt((uint16_t *)r->coeffs, PQCLEAN_NEWHOPE512CPA_CLEAN_omegas_inv_bitrev_montgomery); + PQCLEAN_NEWHOPE512CPA_CLEAN_mul_coefficients(r->coeffs, PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_inv_montgomery); +} + diff --git a/crypto_kem/newhope512cpa/clean/poly.h b/crypto_kem/newhope512cpa/clean/poly.h new file mode 100644 index 00000000..18b5e9a9 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/poly.h @@ -0,0 +1,32 @@ +#ifndef POLY_H +#define POLY_H + +#include "params.h" +#include + +/* + * Elements of R_q = Z_q[X]/(X^n + 1). Represents polynomial + * coeffs[0] + X*coeffs[1] + X^2*xoeffs[2] + ... + X^{n-1}*coeffs[n-1] + */ +typedef struct { + uint16_t coeffs[NEWHOPE_N]; +} poly; + +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_uniform(poly *a, const unsigned char *seed); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sample(poly *r, const unsigned char *seed, unsigned char nonce); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_add(poly *r, const poly *a, const poly *b); + +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_ntt(poly *r); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_invntt(poly *r); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_mul_pointwise(poly *r, const poly *a, const poly *b); + +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frombytes(poly *r, const unsigned char *a); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tobytes(unsigned char *r, const poly *p); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_compress(unsigned char *r, const poly *p); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_decompress(poly *r, const unsigned char *a); + +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_frommsg(poly *r, const unsigned char *msg); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_tomsg(unsigned char *msg, const poly *x); +void PQCLEAN_NEWHOPE512CPA_CLEAN_poly_sub(poly *r, const poly *a, const poly *b); + +#endif diff --git a/crypto_kem/newhope512cpa/clean/precomp.c b/crypto_kem/newhope512cpa/clean/precomp.c new file mode 100644 index 00000000..039d671b --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/precomp.c @@ -0,0 +1,179 @@ +#include "inttypes.h" +#include "ntt.h" +#include "params.h" + +/* Precomputed NTT contants generated by Pari/GP script as follows: + * + * For n = 512: + * + * brv = [0,256,128,384,64,320,192,448,32,288,160,416,96,352,224,480,16,272,144,400,80,336,208,464,48,304,176,432,112,368,240,496,8, + * 264,136,392,72,328,200,456,40,296,168,424,104,360,232,488,24,280,152,408,88,344,216,472,56,312,184,440,120,376,248,504,4, + * 260,132,388,68,324,196,452,36,292,164,420,100,356,228,484,20,276,148,404,84,340,212,468,52,308,180,436,116,372,244,500,12, + * 268,140,396,76,332,204,460,44,300,172,428,108,364,236,492,28,284,156,412,92,348,220,476,60,316,188,444,124,380,252,508,2, + * 258,130,386,66,322,194,450,34,290,162,418,98,354,226,482,18,274,146,402,82,338,210,466,50,306,178,434,114,370,242,498,10, + * 266,138,394,74,330,202,458,42,298,170,426,106,362,234,490,26,282,154,410,90,346,218,474,58,314,186,442,122,378,250,506,6, + * 262,134,390,70,326,198,454,38,294,166,422,102,358,230,486,22,278,150,406,86,342,214,470,54,310,182,438,118,374,246,502,14, + * 270,142,398,78,334,206,462,46,302,174,430,110,366,238,494,30,286,158,414,94,350,222,478,62,318,190,446,126,382,254,510,1, + * 257,129,385,65,321,193,449,33,289,161,417,97,353,225,481,17,273,145,401,81,337,209,465,49,305,177,433,113,369,241,497,9, + * 265,137,393,73,329,201,457,41,297,169,425,105,361,233,489,25,281,153,409,89,345,217,473,57,313,185,441,121,377,249,505,5, + * 261,133,389,69,325,197,453,37,293,165,421,101,357,229,485,21,277,149,405,85,341,213,469,53,309,181,437,117,373,245,501,13, + * 269,141,397,77,333,205,461,45,301,173,429,109,365,237,493,29,285,157,413,93,349,221,477,61,317,189,445,125,381,253,509,3, + * 259,131,387,67,323,195,451,35,291,163,419,99,355,227,483,19,275,147,403,83,339,211,467,51,307,179,435,115,371,243,499,11, + * 267,139,395,75,331,203,459,43,299,171,427,107,363,235,491,27,283,155,411,91,347,219,475,59,315,187,443,123,379,251,507,7, + * 263,135,391,71,327,199,455,39,295,167,423,103,359,231,487,23,279,151,407,87,343,215,471,55,311,183,439,119,375,247,503,15, + * 271,143,399,79,335,207,463,47,303,175,431,111,367,239,495,31,287,159,415,95,351,223,479,63,319,191,447,127,383,255,511] + * n = 512; q = 12289; mont=2^18 + * g = Mod(10968, q); + * omegas_inv_bitrev_montgomery = lift(vector(n/2, i, (g^2)^(-brv[2*(i-1)+1])*mont)) + * gammas_bitrev_montgomery = lift(vector(n, i, g^(brv[i])*mont)) + * gammas_inv_montgomery = lift(vector(n, i, g^(-(i-1))/n*mont)) + * + * + * For n = 1024: + * + * brv = [0,512,256,768,128,640,384,896,64,576,320,832,192,704,448,960,32,544,288,800,160,672,416,928,96,608,352,864,224,736,480,992, \ + * 16,528,272,784,144,656,400,912,80,592,336,848,208,720,464,976,48,560,304,816,176,688,432,944,112,624,368,880,240,752,496,1008, \ + * 8,520,264,776,136,648,392,904,72,584,328,840,200,712,456,968,40,552,296,808,168,680,424,936,104,616,360,872,232,744,488,1000, \ + * 24,536,280,792,152,664,408,920,88,600,344,856,216,728,472,984,56,568,312,824,184,696,440,952,120,632,376,888,248,760,504,1016, \ + * 4,516,260,772,132,644,388,900,68,580,324,836,196,708,452,964,36,548,292,804,164,676,420,932,100,612,356,868,228,740,484,996, \ + * 20,532,276,788,148,660,404,916,84,596,340,852,212,724,468,980,52,564,308,820,180,692,436,948,116,628,372,884,244,756,500,1012, \ + * 12,524,268,780,140,652,396,908,76,588,332,844,204,716,460,972,44,556,300,812,172,684,428,940,108,620,364,876,236,748,492,1004, \ + * 28,540,284,796,156,668,412,924,92,604,348,860,220,732,476,988,60,572,316,828,188,700,444,956,124,636,380,892,252,764,508,1020, \ + * 2,514,258,770,130,642,386,898,66,578,322,834,194,706,450,962,34,546,290,802,162,674,418,930,98,610,354,866,226,738,482,994, \ + * 18,530,274,786,146,658,402,914,82,594,338,850,210,722,466,978,50,562,306,818,178,690,434,946,114,626,370,882,242,754,498,1010, \ + * 10,522,266,778,138,650,394,906,74,586,330,842,202,714,458,970,42,554,298,810,170,682,426,938,106,618,362,874,234,746,490,1002, \ + * 26,538,282,794,154,666,410,922,90,602,346,858,218,730,474,986,58,570,314,826,186,698,442,954,122,634,378,890,250,762,506,1018, \ + * 6,518,262,774,134,646,390,902,70,582,326,838,198,710,454,966,38,550,294,806,166,678,422,934,102,614,358,870,230,742,486,998, \ + * 22,534,278,790,150,662,406,918,86,598,342,854,214,726,470,982,54,566,310,822,182,694,438,950,118,630,374,886,246,758,502,1014, \ + * 14,526,270,782,142,654,398,910,78,590,334,846,206,718,462,974,46,558,302,814,174,686,430,942,110,622,366,878,238,750,494,1006, \ + * 30,542,286,798,158,670,414,926,94,606,350,862,222,734,478,990,62,574,318,830,190,702,446,958,126,638,382,894,254,766,510,1022, \ + * 1,513,257,769,129,641,385,897,65,577,321,833,193,705,449,961,33,545,289,801,161,673,417,929,97,609,353,865,225,737,481,993, \ + * 17,529,273,785,145,657,401,913,81,593,337,849,209,721,465,977,49,561,305,817,177,689,433,945,113,625,369,881,241,753,497,1009, \ + * 9,521,265,777,137,649,393,905,73,585,329,841,201,713,457,969,41,553,297,809,169,681,425,937,105,617,361,873,233,745,489,1001, \ + * 25,537,281,793,153,665,409,921,89,601,345,857,217,729,473,985,57,569,313,825,185,697,441,953,121,633,377,889,249,761,505,1017, \ + * 5,517,261,773,133,645,389,901,69,581,325,837,197,709,453,965,37,549,293,805,165,677,421,933,101,613,357,869,229,741,485,997, \ + * 21,533,277,789,149,661,405,917,85,597,341,853,213,725,469,981,53,565,309,821,181,693,437,949,117,629,373,885,245,757,501,1013, \ + * 13,525,269,781,141,653,397,909,77,589,333,845,205,717,461,973,45,557,301,813,173,685,429,941,109,621,365,877,237,749,493,1005, \ + * 29,541,285,797,157,669,413,925,93,605,349,861,221,733,477,989,61,573,317,829,189,701,445,957,125,637,381,893,253,765,509,1021, \ + * 3,515,259,771,131,643,387,899,67,579,323,835,195,707,451,963,35,547,291,803,163,675,419,931,99,611,355,867,227,739,483,995, \ + * 19,531,275,787,147,659,403,915,83,595,339,851,211,723,467,979,51,563,307,819,179,691,435,947,115,627,371,883,243,755,499,1011, \ + * 11,523,267,779,139,651,395,907,75,587,331,843,203,715,459,971,43,555,299,811,171,683,427,939,107,619,363,875,235,747,491,1003, \ + * 27,539,283,795,155,667,411,923,91,603,347,859,219,731,475,987,59,571,315,827,187,699,443,955,123,635,379,891,251,763,507,1019, \ + * 7,519,263,775,135,647,391,903,71,583,327,839,199,711,455,967,39,551,295,807,167,679,423,935,103,615,359,871,231,743,487,999, \ + * 23,535,279,791,151,663,407,919,87,599,343,855,215,727,471,983,55,567,311,823,183,695,439,951,119,631,375,887,247,759,503,1015, \ + * 15,527,271,783,143,655,399,911,79,591,335,847,207,719,463,975,47,559,303,815,175,687,431,943,111,623,367,879,239,751,495,1007, \ + * 31,543,287,799,159,671,415,927,95,607,351,863,223,735,479,991,63,575,319,831,191,703,447,959,127,639,383,895,255,767,511,1023] + * + * n = 1024; q = 12289; mont=2^18 + * g = Mod(7, q); + * omegas_inv_bitrev_montgomery = lift(vector(n/2, i, (g^2)^(-brv[2*(i-1)+1])*mont)) + * gammas_bitrev_montgomery = lift(vector(n, i, g^(brv[i])*mont)) + * gammas_inv_montgomery = lift(vector(n, i, g^(-(i-1))/n*mont)) +*/ + +/************************************************************ +* Name: omegas_inv_bitrev_montgomery +* +* Description: Contains inverses of powers of nth root of unity +* in Montgomery domain with R=2^18 in bit-reversed order +************************************************************/ +const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_omegas_inv_bitrev_montgomery[NEWHOPE_N / 2] = { + 4075, 6974, 4916, 4324, 7210, 3262, 2169, 11767, 3514, 1041, 5925, 11271, 6715, 10316, 11011, 9945, + 1190, 9606, 3818, 6118, 1050, 7753, 8429, 6844, 4449, 6833, 147, 3789, 7540, 6752, 4467, 4789, + 10367, 3879, 2033, 3998, 11316, 1254, 6854, 1359, 3988, 468, 11907, 11973, 8579, 6196, 5446, 6950, + 1987, 10587, 654, 3565, 3199, 12233, 7083, 6760, 6427, 6153, 3643, 6874, 4948, 6152, 11889, 1728, + 7280, 10333, 6008, 11404, 3532, 11286, 241, 12231, 11314, 4212, 8851, 9445, 3477, 6608, 12147, 1105, + 5594, 9260, 5886, 7507, 4213, 11785, 2302, 11684, 8687, 6221, 8209, 421, 7665, 6212, 8689, 3263, + 10710, 431, 9784, 5906, 9450, 8332, 2127, 151, 3174, 52, 1323, 9523, 6415, 11612, 3336, 6234, + 7048, 9369, 4169, 3127, 11279, 6821, 787, 3482, 3445, 4780, 7232, 7591, 7377, 2049, 1321, 192, + 9551, 6421, 5735, 9634, 10596, 9280, 723, 12115, 9364, 347, 1975, 3757, 10431, 7535, 11863, 3315, + 4493, 3202, 5369, 10232, 350, 10777, 6906, 10474, 1483, 6374, 49, 1263, 10706, 6347, 1489, 9789, + 7552, 1293, 4774, 5429, 3772, 418, 6381, 453, 9522, 156, 3969, 3991, 6956, 10258, 10008, 6413, + 8855, 3529, 218, 9381, 9259, 8174, 2361, 10446, 10335, 2051, 9407, 10484, 9842, 6147, 3963, 576, + 6523, 11637, 6099, 11994, 9370, 3762, 8273, 4077, 11964, 1404, 11143, 11341, 1159, 6299, 4049, 8561, + 5961, 7183, 1962, 10695, 9597, 12121, 8960, 7991, 6992, 6170, 10929, 8333, 2555, 6167, 11089, 5184, + 3570, 4240, 11454, 6065, 3150, 10970, 709, 8243, 1058, 8210, 441, 11367, 10331, 7967, 1112, 2078, + 10542, 3123, 5486, 9235, 7856, 6370, 8455, 5257, 9341, 9786, 6507, 10723, 2459, 683, 8633, 64, +}; + +/************************************************************ +* Name: gammas_bitrev_montgomery +* +* Description: Contains powers of nth root of -1 in Montgomery +* domain with R=2^18 in bit-reversed order +************************************************************/ +const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_bitrev_montgomery[NEWHOPE_N] = { + 4075, 5315, 7965, 7373, 522, 10120, 9027, 5079, 2344, 1278, 1973, 5574, 1018, 6364, 11248, 8775, + 7500, 7822, 5537, 4749, 8500, 12142, 5456, 7840, 5445, 3860, 4536, 11239, 6171, 8471, 2683, 11099, + 10561, 400, 6137, 7341, 5415, 8646, 6136, 5862, 5529, 5206, 56, 9090, 8724, 11635, 1702, 10302, + 5339, 6843, 6093, 3710, 316, 382, 11821, 8301, 10930, 5435, 11035, 973, 8291, 10256, 8410, 1922, + 12097, 10968, 10240, 4912, 4698, 5057, 7509, 8844, 8807, 11502, 5468, 1010, 9162, 8120, 2920, 5241, + 6055, 8953, 677, 5874, 2766, 10966, 12237, 9115, 12138, 10162, 3957, 2839, 6383, 2505, 11858, 1579, + 9026, 3600, 6077, 4624, 11868, 4080, 6068, 3602, 605, 9987, 504, 8076, 4782, 6403, 3029, 6695, + 11184, 142, 5681, 8812, 2844, 3438, 8077, 975, 58, 12048, 1003, 8757, 885, 6281, 1956, 5009, + 12225, 3656, 11606, 9830, 1566, 5782, 2503, 2948, 7032, 3834, 5919, 4433, 3054, 6803, 9166, 1747, + 10211, 11177, 4322, 1958, 922, 11848, 4079, 11231, 4046, 11580, 1319, 9139, 6224, 835, 8049, 8719, + 7105, 1200, 6122, 9734, 3956, 1360, 6119, 5297, 4298, 3329, 168, 2692, 1594, 10327, 5106, 6328, + 3728, 8240, 5990, 11130, 948, 1146, 10885, 325, 8212, 4016, 8527, 2919, 295, 6190, 652, 5766, + 11713, 8326, 6142, 2447, 1805, 2882, 10238, 1954, 1843, 9928, 4115, 3030, 2908, 12071, 8760, 3434, + 5876, 2281, 2031, 5333, 8298, 8320, 12133, 2767, 11836, 5908, 11871, 8517, 6860, 7515, 10996, 4737, + 2500, 10800, 5942, 1583, 11026, 12240, 5915, 10806, 1815, 5383, 1512, 11939, 2057, 6920, 9087, 7796, + 8974, 426, 4754, 1858, 8532, 10314, 11942, 2925, 174, 11566, 3009, 1693, 2655, 6554, 5868, 2738, + 11796, 8193, 9908, 5444, 10911, 1912, 7952, 435, 404, 7644, 11224, 10146, 7012, 11121, 11082, 9041, + 9723, 2187, 9867, 6250, 3646, 9852, 6267, 2987, 8509, 875, 4976, 10682, 8005, 5088, 7278, 11287, + 9223, 27, 3763, 10849, 11272, 7404, 5084, 10657, 8146, 4714, 12047, 10752, 2678, 3704, 545, 7270, + 1067, 5101, 442, 2401, 390, 11516, 3778, 8456, 1045, 9430, 9808, 5012, 9377, 6591, 11935, 4861, + 7852, 3, 3149, 12129, 12176, 4919, 10123, 3915, 3636, 7351, 2704, 5291, 1663, 1777, 1426, 7635, + 1484, 7394, 2780, 7094, 8236, 2645, 7247, 2305, 2847, 7875, 7917, 10115, 10600, 8925, 4057, 3271, + 9273, 243, 9289, 11618, 3136, 5191, 8889, 9890, 11869, 5559, 10111, 10745, 11813, 8758, 4905, 3985, + 9603, 9042, 3978, 9320, 3510, 5332, 9424, 2370, 9405, 11136, 2249, 8241, 10659, 10163, 9103, 6882, + 10810, 1, 5146, 4043, 8155, 5736, 11567, 1305, 1212, 10643, 9094, 5860, 8747, 8785, 8668, 2545, + 4591, 6561, 5023, 6461, 10938, 4978, 6512, 8961, 949, 2625, 2639, 7468, 11726, 2975, 9545, 9283, + 3091, 81, 11289, 7969, 9238, 9923, 2963, 7393, 12149, 1853, 11563, 7678, 8034, 11112, 1635, 9521, + 3201, 3014, 1326, 7203, 1170, 9970, 11334, 790, 3135, 3712, 4846, 2747, 3553, 7484, 11227, 2294, + 11267, 9, 9447, 11809, 11950, 2468, 5791, 11745, 10908, 9764, 8112, 3584, 4989, 5331, 4278, 10616, + 4452, 9893, 8340, 8993, 130, 7935, 9452, 6915, 8541, 11336, 11462, 5767, 7222, 2197, 12171, 9813, + 3241, 729, 3289, 10276, 9408, 3284, 2089, 5092, 11029, 4388, 5755, 7657, 10861, 1696, 2426, 11955, + 4231, 2548, 11934, 3382, 10530, 3707, 3694, 7110, 3637, 8830, 6747, 145, 7399, 5911, 2731, 8357, +}; + +/************************************************************ +* Name: gammas_inv_montgomery +* +* Description: Contains inverses of powers of nth root of -1 +* divided by n in Montgomery domain with R=2^18 +************************************************************/ +const uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_gammas_inv_montgomery[NEWHOPE_N] = { + 512, 3944, 4267, 5411, 9615, 5900, 3205, 6063, 9261, 2021, 3087, 4770, 1029, 1590, 343, 530, + 8307, 4273, 2769, 9617, 923, 7302, 4404, 2434, 1468, 9004, 8682, 11194, 2894, 11924, 5061, 8071, + 1687, 10883, 8755, 7724, 11111, 6671, 7800, 6320, 2600, 6203, 4963, 6164, 9847, 6151, 11475, 10243, + 3825, 11607, 1275, 3869, 425, 5386, 4238, 9988, 5509, 11522, 10029, 7937, 3343, 6742, 9307, 10440, + 11295, 3480, 3765, 1160, 1255, 4483, 8611, 9687, 11063, 3229, 7784, 9269, 6691, 7186, 10423, 10588, + 11667, 11722, 3889, 12100, 9489, 12226, 3163, 12268, 9247, 12282, 11275, 4094, 11951, 5461, 8080, 10013, + 10886, 7434, 7725, 2478, 2575, 826, 9051, 8468, 3017, 6919, 5102, 10499, 5797, 7596, 10125, 2532, + 3375, 844, 1125, 8474, 375, 6921, 125, 2307, 4138, 769, 9572, 8449, 7287, 11009, 2429, 7766, + 4906, 6685, 9828, 10421, 3276, 7570, 1092, 10716, 364, 3572, 8314, 5287, 10964, 9955, 7751, 11511, + 6680, 3837, 6323, 1279, 6204, 8619, 2068, 2873, 8882, 5054, 7057, 5781, 10545, 1927, 3515, 8835, + 5268, 2945, 1756, 5078, 8778, 5789, 2926, 6026, 9168, 6105, 3056, 2035, 5115, 8871, 1705, 2957, + 8761, 5082, 11113, 1694, 11897, 4661, 8062, 5650, 10880, 10076, 7723, 7455, 10767, 2485, 3589, 9021, + 9389, 3007, 7226, 9195, 6505, 3065, 10361, 5118, 7550, 1706, 6613, 4665, 10397, 1555, 7562, 8711, + 6617, 7000, 6302, 10526, 6197, 7605, 6162, 2535, 2054, 845, 4781, 4378, 5690, 9652, 5993, 11410, + 6094, 11996, 10224, 8095, 3408, 10891, 1136, 11823, 4475, 3941, 5588, 5410, 5959, 9996, 10179, 3332, + 3393, 5207, 1131, 5832, 377, 1944, 4222, 648, 9600, 216, 3200, 72, 5163, 24, 1721, 8, + 4670, 4099, 5653, 9559, 10077, 11379, 3359, 3793, 5216, 9457, 5835, 11345, 1945, 7878, 8841, 2626, + 2947, 9068, 9175, 7119, 11251, 2373, 11943, 791, 3981, 4360, 1327, 9646, 8635, 11408, 11071, 7899, + 11883, 2633, 3961, 4974, 9513, 1658, 3171, 4649, 1057, 5646, 8545, 1882, 11041, 8820, 11873, 2940, + 8054, 980, 6781, 4423, 10453, 9667, 11677, 11415, 12085, 3805, 12221, 9461, 8170, 7250, 10916, 6513, + 7735, 2171, 10771, 4820, 11783, 5703, 8024, 1901, 6771, 4730, 2257, 5673, 8945, 1891, 7078, 8823, + 10552, 2941, 11710, 9173, 12096, 7154, 4032, 6481, 1344, 10353, 448, 3451, 8342, 9343, 6877, 11307, + 10485, 3769, 3495, 9449, 1165, 7246, 8581, 10608, 11053, 3536, 11877, 5275, 3959, 9951, 5416, 3317, + 9998, 5202, 7429, 1734, 10669, 578, 11749, 4289, 12109, 5526, 12229, 1842, 12269, 614, 8186, 4301, + 6825, 5530, 2275, 10036, 8951, 11538, 7080, 3846, 2360, 1282, 4883, 8620, 5724, 11066, 1908, 7785, + 636, 2595, 212, 865, 4167, 8481, 1389, 2827, 463, 9135, 8347, 3045, 10975, 1015, 11851, 8531, + 12143, 6940, 8144, 10506, 6811, 3502, 10463, 9360, 7584, 3120, 2528, 1040, 4939, 4443, 9839, 1481, + 7376, 4590, 6555, 1530, 2185, 510, 8921, 170, 7070, 4153, 6453, 9577, 2151, 11385, 717, 3795, + 239, 1265, 4176, 4518, 1392, 1506, 464, 502, 4251, 8360, 1417, 6883, 8665, 10487, 11081, 7592, + 7790, 6627, 6693, 2209, 2231, 8929, 4840, 11169, 9806, 3723, 7365, 1241, 2455, 4510, 9011, 9696, + 7100, 3232, 6463, 9270, 10347, 3090, 3449, 1030, 5246, 8536, 5845, 11038, 10141, 11872, 11573, 12150, + 7954, 4050, 10844, 1350, 7711, 450, 10763, 150, 7684, 50, 10754, 4113, 7681, 1371, 10753, 457, +}; diff --git a/crypto_kem/newhope512cpa/clean/reduce.c b/crypto_kem/newhope512cpa/clean/reduce.c new file mode 100644 index 00000000..75d23570 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/reduce.c @@ -0,0 +1,26 @@ +#include "reduce.h" +#include "params.h" + +static const uint32_t qinv = 12287; // -inverse_mod(p,2^18) +static const uint32_t rlog = 18; + +/************************************************* +* Name: verify +* +* Description: Montgomery reduction; given a 32-bit integer a, computes +* 16-bit integer congruent to a * R^-1 mod q, +* where R=2^18 (see value of rlog) +* +* Arguments: - uint32_t a: input unsigned integer to be reduced; has to be in {0,...,1073491968} +* +* Returns: unsigned integer in {0,...,2^14-1} congruent to a * R^-1 modulo q. +**************************************************/ +uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce(uint32_t a) { + uint32_t u; + + u = (a * qinv); + u &= ((1 << rlog) - 1); + u *= NEWHOPE_Q; + a = a + u; + return a >> 18; +} diff --git a/crypto_kem/newhope512cpa/clean/reduce.h b/crypto_kem/newhope512cpa/clean/reduce.h new file mode 100644 index 00000000..d7424375 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/reduce.h @@ -0,0 +1,8 @@ +#ifndef REDUCE_H +#define REDUCE_H + +#include + +uint16_t PQCLEAN_NEWHOPE512CPA_CLEAN_montgomery_reduce(uint32_t a); + +#endif diff --git a/crypto_kem/newhope512cpa/clean/verify.c b/crypto_kem/newhope512cpa/clean/verify.c new file mode 100644 index 00000000..449bc219 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/verify.c @@ -0,0 +1,49 @@ +#include "verify.h" +#include +#include + +/************************************************* +* Name: verify +* +* Description: Compare two arrays for equality in constant time. +* +* Arguments: const unsigned char *a: pointer to first byte array +* const unsigned char *b: pointer to second byte array +* size_t len: length of the byte arrays +* +* Returns 0 if the byte arrays are equal, 1 otherwise +**************************************************/ +int PQCLEAN_NEWHOPE512CPA_CLEAN_verify(const unsigned char *a, const unsigned char *b, size_t len) { + uint64_t r; + size_t i; + r = 0; + + for (i = 0; i < len; i++) { + r |= a[i] ^ b[i]; + } + + r = (-(int64_t)r) >> 63; + return (int)r; +} + +/************************************************* +* Name: cmov +* +* Description: Copy len bytes from x to r if b is 1; +* don't modify x if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: unsigned char *r: pointer to output byte array +* const unsigned char *x: pointer to input byte array +* size_t len: Amount of bytes to be copied +* unsigned char b: Condition bit; has to be in {0,1} +**************************************************/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_cmov(unsigned char *r, const unsigned char *x, size_t len, unsigned char b) { + size_t i; + + b = -b; + for (i = 0; i < len; i++) { + r[i] ^= b & (x[i] ^ r[i]); + } +} diff --git a/crypto_kem/newhope512cpa/clean/verify.h b/crypto_kem/newhope512cpa/clean/verify.h new file mode 100644 index 00000000..64385a42 --- /dev/null +++ b/crypto_kem/newhope512cpa/clean/verify.h @@ -0,0 +1,12 @@ +#ifndef VERIFY_H +#define VERIFY_H + +#include + +/* returns 0 for equal strings, 1 for non-equal strings */ +int PQCLEAN_NEWHOPE512CPA_CLEAN_verify(const unsigned char *a, const unsigned char *b, size_t len); + +/* b = 1 means mov, b = 0 means don't mov*/ +void PQCLEAN_NEWHOPE512CPA_CLEAN_cmov(unsigned char *r, const unsigned char *x, size_t len, unsigned char b); + +#endif