Skip to content

Commit

Permalink
Upgrade implementation to round-4 submission
Browse files Browse the repository at this point in the history
This is a breaking change. Most notably, ciphertexts are now 32 bytes
smaller than before. See "Description of modifications from round 3 to
round 4" (mceliece-mods3-20221023.pdf).
  • Loading branch information
tniessen committed May 29, 2023
1 parent d411b70 commit 882ad43
Show file tree
Hide file tree
Showing 127 changed files with 4,615 additions and 337 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This package provides Node.js bindings for the reference implementation that is
part of the [NIST submission](https://classic.mceliece.org/nist.html) by
Bernstein et al.

This version is based on the round-3 submission `mceliece-20201010`.
This version is based on the round-4 submission `mceliece-20221023`.
See [`deps/mceliece`](deps/mceliece).

## Installation
Expand Down
12 changes: 6 additions & 6 deletions deps/mceliece/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ The `kem` directory contains the reference implementation of the Classic
McEliece KEM that was provided by Bernstein et al. as part of the
[Classic McEliece NIST submission](https://classic.mceliece.org/nist.html).

- Source: Round-3 submission package
- Revision: `mceliece-20201010`
- File: [`mceliece-20201010.tar.gz`](https://classic.mceliece.org/nist/mceliece-20201010.tar.gz)
- `3efe3af6b08c84743589d8bdb98e9c79` (md5)
- `7095f7b5776e836a13d6e6d4b75d2704df1d412a` (sha1)
- `1b8aca59430ca7a0569e4e918e1c0c165f67dd0ccde44760f314eaa40f75dafe` (sha256)
- Source: Round-4 submission package
- Revision: `mceliece-20221023`
- File: [`mceliece-20221023.tar.gz`](https://classic.mceliece.org/nist/mceliece-20221023.tar.gz)
- `37bc7bddf9b061cb52992afe27f40f82` (md5)
- `e939e24b0f840a1a78c474575b846c50986d4651` (sha1)
- `sha256: 0428f1c9aeb3472ab580f21693d7fa26ccc92f29beee40a78cc88dab79dfb7a3` (sha256)

## Automatically applied patches

Expand Down
30 changes: 30 additions & 0 deletions deps/mceliece/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
'kem/mceliece348864/transpose.c',
'kem/mceliece348864/util.c',
],
'include_dirs': [
'kem/mceliece348864/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece348864_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece348864_##x',
Expand All @@ -58,6 +61,9 @@
'kem/mceliece348864f/transpose.c',
'kem/mceliece348864f/util.c',
],
'include_dirs': [
'kem/mceliece348864f/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece348864f_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece348864f_##x',
Expand All @@ -82,6 +88,9 @@
'kem/mceliece460896/transpose.c',
'kem/mceliece460896/util.c',
],
'include_dirs': [
'kem/mceliece460896/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece460896_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece460896_##x',
Expand All @@ -106,6 +115,9 @@
'kem/mceliece460896f/transpose.c',
'kem/mceliece460896f/util.c',
],
'include_dirs': [
'kem/mceliece460896f/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece460896f_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece460896f_##x',
Expand All @@ -130,6 +142,9 @@
'kem/mceliece6688128/transpose.c',
'kem/mceliece6688128/util.c',
],
'include_dirs': [
'kem/mceliece6688128/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece6688128_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece6688128_##x',
Expand All @@ -154,6 +169,9 @@
'kem/mceliece6688128f/transpose.c',
'kem/mceliece6688128f/util.c',
],
'include_dirs': [
'kem/mceliece6688128f/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece6688128f_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece6688128f_##x',
Expand All @@ -178,6 +196,9 @@
'kem/mceliece6960119/transpose.c',
'kem/mceliece6960119/util.c',
],
'include_dirs': [
'kem/mceliece6960119/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece6960119_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece6960119_##x',
Expand All @@ -202,6 +223,9 @@
'kem/mceliece6960119f/transpose.c',
'kem/mceliece6960119f/util.c',
],
'include_dirs': [
'kem/mceliece6960119f/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece6960119f_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece6960119f_##x',
Expand All @@ -226,6 +250,9 @@
'kem/mceliece8192128/transpose.c',
'kem/mceliece8192128/util.c',
],
'include_dirs': [
'kem/mceliece8192128/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece8192128_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece8192128_##x',
Expand All @@ -250,6 +277,9 @@
'kem/mceliece8192128f/transpose.c',
'kem/mceliece8192128f/util.c',
],
'include_dirs': [
'kem/mceliece8192128f/subroutines',
],
'defines': [
'CRYPTO_NAMESPACE(x)=pqcrypto_kem_mceliece8192128f_##x',
'_CRYPTO_NAMESPACE(x)=_pqcrypto_kem_mceliece8192128f_##x',
Expand Down
2 changes: 1 addition & 1 deletion deps/mceliece/build-wasm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ compile_algorithm() {
target=$obj_dir/${source%.c}.bc
echo " $source -> $target"
mkdir -p `dirname $target`
emcc -std=c11 -Oz -fvisibility=default $variables -c $source -o $target
emcc -std=c11 -Oz -Ikem/$id/subroutines -fvisibility=default $variables -c $source -o $target
done
}

Expand Down
8 changes: 6 additions & 2 deletions deps/mceliece/extract-kem-from-nist-submission
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/bin/bash
set -e
set -euo pipefail
shopt -s inherit_errexit

# Remove the old implementation.
rm -rf kem

archive=mceliece-20201010
archive=mceliece-20221023
archfile=$archive.tar.gz

echo -n "md5: "; md5sum $archfile | cut -c 1-32
Expand Down Expand Up @@ -43,6 +44,9 @@ add_gyp() {
echo " '$source',"
done
echo " ],"
echo " 'include_dirs': ["
echo " 'kem/$id/subroutines',"
echo " ],"
echo " 'defines': ["
for def in ${variables[@]}; do
echo " '$def',"
Expand Down
14 changes: 9 additions & 5 deletions deps/mceliece/kem/mceliece348864/controlbits.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
/* See also https://cr.yp.to/papers/controlbits-20200923.pdf */

#include <string.h>
#include "crypto_declassify.h"
#include "controlbits.h"
#include "int32_sort.h"
typedef int16_t int16;
typedef int32_t int32;
#include "crypto_int32.h"
#define int32_min crypto_int32_min
#include "crypto_int16.h"

/* parameters: 1 <= w <= 14; n = 2^w */
/* input: permutation pi of {0,1,...,n-1} */
Expand Down Expand Up @@ -34,8 +38,7 @@ static void cbrecursion(unsigned char *out,long long pos,long long step,const in
for (x = 0;x < n;++x) {
int32 Ax = A[x];
int32 px = Ax&0xffff;
int32 cx = px;
if (x < cx) cx = x;
int32 cx = int32_min(px,x);
B[x] = (px<<16)|cx;
}
/* B = (p<<16)+c */
Expand All @@ -61,8 +64,7 @@ static void cbrecursion(unsigned char *out,long long pos,long long step,const in
for (x = 0;x < n;++x) {
int32 ppcpx = A[x]&0xfffff;
int32 ppcx = (A[x]&0xffc00)|(B[x]&0x3ff);
if (ppcpx < ppcx) ppcx = ppcpx;
B[x] = ppcx;
B[x] = int32_min(ppcx,ppcpx);
}
}
for (x = 0;x < n;++x) B[x] &= 0x3ff;
Expand Down Expand Up @@ -90,7 +92,7 @@ static void cbrecursion(unsigned char *out,long long pos,long long step,const in
/* A = id<<16+cp */
for (x = 0;x < n;++x) {
int32 cpx = (B[x]&~0xffff)|(A[x]&0xffff);
if (cpx < B[x]) B[x] = cpx;
B[x] = int32_min(B[x],cpx);
}
}
for (x = 0;x < n;++x) B[x] &= 0xffff;
Expand Down Expand Up @@ -209,6 +211,8 @@ void controlbitsfrompermutation(unsigned char *out,const int16 *pi,long long w,l
for (i = 0; i < n; i++)
diff |= pi[i] ^ pi_test[i];

diff = crypto_int16_nonzero_mask(diff);
crypto_declassify(&diff,sizeof diff);
if (diff == 0)
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define crypto_kem_mceliece348864_ref_PUBLICKEYBYTES 261120
#define crypto_kem_mceliece348864_ref_SECRETKEYBYTES 6492
#define crypto_kem_mceliece348864_ref_CIPHERTEXTBYTES 128
#define crypto_kem_mceliece348864_ref_CIPHERTEXTBYTES 96
#define crypto_kem_mceliece348864_ref_BYTES 32


Expand Down
21 changes: 19 additions & 2 deletions deps/mceliece/kem/mceliece348864/encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@
#include <string.h>

#include "gf.h"
#include "crypto_declassify.h"
#include "crypto_uint16.h"
#include "crypto_uint32.h"

static inline crypto_uint16 uint16_is_smaller_declassify(uint16_t t,uint16_t u)
{
crypto_uint16 mask = crypto_uint16_smaller_mask(t,u);
crypto_declassify(&mask,sizeof mask);
return mask;
}

static inline crypto_uint32 uint32_is_equal_declassify(uint32_t t,uint32_t u)
{
crypto_uint32 mask = crypto_uint32_equal_mask(t,u);
crypto_declassify(&mask,sizeof mask);
return mask;
}

static inline unsigned char same_mask(uint16_t x, uint16_t y)
{
Expand Down Expand Up @@ -53,7 +70,7 @@ static void gen_e(unsigned char *e)

count = 0;
for (i = 0; i < SYS_T*2 && count < SYS_T; i++)
if (buf.nums[i] < SYS_N)
if (uint16_is_smaller_declassify(buf.nums[i],SYS_N))
ind[ count++ ] = buf.nums[i];

if (count < SYS_T) continue;
Expand All @@ -64,7 +81,7 @@ static void gen_e(unsigned char *e)

for (i = 1; i < SYS_T; i++)
for (j = 0; j < i; j++)
if (ind[i] == ind[j])
if (uint32_is_equal_declassify(ind[i],ind[j]))
eq = 1;

if (eq == 0)
Expand Down
25 changes: 7 additions & 18 deletions deps/mceliece/kem/mceliece348864/operations.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@ int crypto_kem_enc(
const unsigned char *pk
)
{
unsigned char two_e[ 1 + SYS_N/8 ] = {2};
unsigned char *e = two_e + 1;
unsigned char one_ec[ 1 + SYS_N/8 + (SYND_BYTES + 32) ] = {1};
unsigned char e[ SYS_N/8 ];
unsigned char one_ec[ 1 + SYS_N/8 + SYND_BYTES ] = {1};

//

encrypt(c, pk, e);

crypto_hash_32b(c + SYND_BYTES, two_e, sizeof(two_e));

memcpy(one_ec + 1, e, SYS_N/8);
memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES + 32);
memcpy(one_ec + 1 + SYS_N/8, c, SYND_BYTES);

crypto_hash_32b(key, one_ec, sizeof(one_ec));

Expand All @@ -45,36 +42,28 @@ int crypto_kem_dec(
{
int i;

unsigned char ret_confirm = 0;
unsigned char ret_decrypt = 0;

uint16_t m;

unsigned char conf[32];
unsigned char two_e[ 1 + SYS_N/8 ] = {2};
unsigned char *e = two_e + 1;
unsigned char preimage[ 1 + SYS_N/8 + (SYND_BYTES + 32) ];
unsigned char e[ SYS_N/8 ];
unsigned char preimage[ 1 + SYS_N/8 + SYND_BYTES ];
unsigned char *x = preimage;
const unsigned char *s = sk + 40 + IRR_BYTES + COND_BYTES;

//

ret_decrypt = decrypt(e, sk + 40, c);

crypto_hash_32b(conf, two_e, sizeof(two_e));

for (i = 0; i < 32; i++)
ret_confirm |= conf[i] ^ c[SYND_BYTES + i];

m = ret_decrypt | ret_confirm;
m = ret_decrypt;
m -= 1;
m >>= 8;

*x++ = m & 1;
for (i = 0; i < SYS_N/8; i++)
*x++ = (~m & s[i]) | (m & e[i]);

for (i = 0; i < SYND_BYTES + 32; i++)
for (i = 0; i < SYND_BYTES; i++)
*x++ = c[i];

crypto_hash_32b(key, preimage, sizeof(preimage));
Expand Down
20 changes: 18 additions & 2 deletions deps/mceliece/kem/mceliece348864/pk_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
#include "benes.h"
#include "root.h"
#include "util.h"
#include "crypto_declassify.h"
#include "crypto_uint64.h"

static crypto_uint64 uint64_is_equal_declassify(uint64_t t,uint64_t u)
{
crypto_uint64 mask = crypto_uint64_equal_mask(t,u);
crypto_declassify(&mask,sizeof mask);
return mask;
}

static crypto_uint64 uint64_is_zero_declassify(uint64_t t)
{
crypto_uint64 mask = crypto_uint64_zero_mask(t);
crypto_declassify(&mask,sizeof mask);
return mask;
}

/* input: secret key sk */
/* output: public key pk */
Expand Down Expand Up @@ -48,7 +64,7 @@ int pk_gen(unsigned char * pk, unsigned char * sk, uint32_t * perm, int16_t * pi
uint64_sort(buf, 1 << GFBITS);

for (i = 1; i < (1 << GFBITS); i++)
if ((buf[i-1] >> 31) == (buf[i] >> 31))
if (uint64_is_equal_declassify(buf[i-1] >> 31,buf[i] >> 31))
return -1;

for (i = 0; i < (1 << GFBITS); i++) pi[i] = buf[i] & GFMASK;
Expand Down Expand Up @@ -108,7 +124,7 @@ int pk_gen(unsigned char * pk, unsigned char * sk, uint32_t * perm, int16_t * pi
mat[ row ][ c ] ^= mat[ k ][ c ] & mask;
}

if ( ((mat[ row ][ i ] >> j) & 1) == 0 ) // return if not systematic
if ( uint64_is_zero_declassify((mat[ row ][ i ] >> j) & 1) ) // return if not systematic
{
return -1;
}
Expand Down
11 changes: 10 additions & 1 deletion deps/mceliece/kem/mceliece348864/sk_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
#include "params.h"
#include "util.h"
#include "gf.h"
#include "crypto_declassify.h"
#include "crypto_uint16.h"

static inline crypto_uint16 gf_is_zero_declassify(gf t)
{
crypto_uint16 mask = crypto_uint16_zero_mask(t);
crypto_declassify(&mask,sizeof mask);
return mask;
}

/* input: f, element in GF((2^m)^t) */
/* output: out, minimal polynomial of f */
Expand Down Expand Up @@ -46,7 +55,7 @@ int genpoly_gen(gf *out, gf *f)

}

if ( mat[ j ][ j ] == 0 ) // return if not systematic
if ( gf_is_zero_declassify(mat[ j ][ j ]) ) // return if not systematic
{
return -1;
}
Expand Down
Loading

0 comments on commit 882ad43

Please sign in to comment.