Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checksum KAT to Github Workflow #29

Merged
45 changes: 33 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,48 @@
name: Build
on:
push:
branches: [ '*' ]
branches: ["*"]
pull_request:
branches: [ "main" ]
branches: ["main"]
jobs:
build_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup nix
uses: ./.github/actions/setup-nix
- name: Astyle
shell: nix develop .#ci -c bash -e {0}
run: |
- uses: actions/checkout@v4
- name: Setup nix
uses: ./.github/actions/setup-nix
- name: Astyle
shell: nix develop .#ci -c bash -e {0}
run: |
err=$(astyle $(git ls-files "*.c" "*.h") --options=.astylerc --dry-run --formatted | awk '{print $2}')
if [[ ${#err} != 0 ]]; then
echo "$err" | while IFS= read -r file; do
echo "::error file={"$file"},title={checking}::Formatted $file"
done
exit 1
fi
- name: Build targets
shell: nix develop .#ci -c bash -e {0}
run: |
make
- name: Build targets
shell: nix develop .#ci -c bash -e {0}
run: |
make mlkem
./test/test_kyber512
./test/test_kyber768
./test/test_kyber1024
- name: Compare gen_KAT with known hash
shell: nix develop .#ci -c bash -e {0}
run: |
make kat;
./checksum.sh ./test/gen_KAT512 ec4ac397e595ac7457cb7d8830921faf3290898a10d7dd3864aab89ea61fe9a3
./checksum.sh ./test/gen_KAT768 9a0826ad3c5232dfd3b21bc4801408655c565a491b760f509b2ee2cd7180babe
./checksum.sh ./test/gen_KAT1024 6dafb867599b750a6a831b03e494cf41dea748c78a0e275e7b268bbb893cf37d
- name: Compare gen_NISTKAT with known hash
shell: nix develop .#ci -c bash -e {0}
run: |
make nistkat;
./checksum.sh ./test/gen_NISTKAT512 4b88ac7643ff60209af1175e025f354272e88df827a0ce1c056e403629b88e04
./checksum.sh ./test/gen_NISTKAT768 21b4a1e1ea34a13c26a9da5eeb9325afb5ca11596ca6f3704c3f2637e3ea7524
./checksum.sh ./test/gen_NISTKAT1024 6471398b0a728ee1ef39e93bb89b526fbf59587a3662edadbcfc6c88a512cd71
- name: Clean up
shell: nix develop .#ci -c bash -e {0}
run: |
make clean
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@
test/test_kyber512
test/test_kyber768
test/test_kyber1024
test/gen_KAT512
test/gen_KAT768
test/gen_KAT1024
test/gen_NISTKAT512
test/gen_NISTKAT768
test/gen_NISTKAT1024
68 changes: 55 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,39 +1,81 @@
CC ?= /usr/bin/cc
CFLAGS_FIPS202 = -I fips202
CFLAGS_MLKEM = -I mlkem
CFLAGS_RANDOMBYTES = -I randombytes
CFLAGS_TEST = -I test
INCLUDE_FIPS202 = -I fips202
INCLUDE_MLKEM = -I mlkem
INCLUDE_RANDOM = -I randombytes
INCLUDE_NISTRANDOM = -I test/nistrng
CFLAGS += -Wall -Wextra -Wpedantic -Wmissing-prototypes -Wredundant-decls \
-Wshadow -Wpointer-arith -O3 -fomit-frame-pointer -pedantic \
${CFLAGS_RANDOMBYTES} ${CFLAGS_MLKEM} ${CFLAGS_FIPS202} ${CFLAGS_TEST}
${INCLUDE_MLKEM} ${INCLUDE_FIPS202}
CFLAGS_RANDOMBYTES = ${CFLAGS} ${INCLUDE_RANDOM}
CFLAGS_NISTRANDOMBYTES = ${CFLAGS} ${INCLUDE_NISTRANDOM}
NISTFLAGS += -Wno-unused-result -O3 -fomit-frame-pointer
RM = /bin/rm

SOURCES = mlkem/kem.c mlkem/indcpa.c mlkem/polyvec.c mlkem/poly.c mlkem/ntt.c mlkem/cbd.c mlkem/reduce.c mlkem/verify.c
SOURCESKECCAK = $(SOURCES) fips202/keccakf1600.c fips202/fips202.c mlkem/symmetric-shake.c
SOURCESKECCAKRANDOM = $(SOURCESKECCAK) randombytes/randombytes.c
SOURCESNISTKATS = $(SOURCESKECCAK) test/nistrng/aes.c test/nistrng/rng.c

HEADERS = mlkem/params.h mlkem/kem.h mlkem/indcpa.h mlkem/polyvec.h mlkem/poly.h mlkem/ntt.h mlkem/cbd.h mlkem/reduce.c mlkem/verify.h mlkem/symmetric.h
HEADERSKECCAK = $(HEADERS) fips202/keccakf1600.h fips202/fips202.h
HEADERSKECCAKRANDOM = $(HEADERSKECCAK) randombytes/randombytes.h
HEADERNISTKATS = $(HEADERSKECCAK) test/nistrng/aes.h test/nistrng/randombytes.h

.PHONY: all mlkem clean
.PHONY: all mlkem kat nistkat clean

all: mlkem
all: mlkem kat nistkat

mlkem: \
test/test_kyber512 \
test/test_kyber768 \
test/test_kyber1024

test/test_kyber512: $(SOURCESKECCAK) $(HEADERSKECCAK) test/test_kyber.c randombytes/randombytes.c
$(CC) $(CFLAGS) -DKYBER_K=2 $(SOURCESKECCAK) randombytes/randombytes.c test/test_kyber.c -o $@
nistkat: \
test/gen_NISTKAT512 \
test/gen_NISTKAT768 \
test/gen_NISTKAT1024

kat: \
test/gen_KAT512 \
test/gen_KAT768 \
test/gen_KAT1024

test/test_kyber512: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/test_kyber.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=2 $(SOURCESKECCAKRANDOM) test/test_kyber.c -o $@

test/test_kyber768: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/test_kyber.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=3 $(SOURCESKECCAKRANDOM) test/test_kyber.c -o $@

test/test_kyber1024: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/test_kyber.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=4 $(SOURCESKECCAKRANDOM) test/test_kyber.c -o $@

test/gen_KAT512: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/gen_KAT.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=2 $(SOURCESKECCAKRANDOM) test/gen_KAT.c -o $@

test/gen_KAT768: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/gen_KAT.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=3 $(SOURCESKECCAKRANDOM) test/gen_KAT.c -o $@

test/gen_KAT1024: $(SOURCESKECCAKRANDOM) $(HEADERSKECCAKRANDOM) test/gen_KAT.c
$(CC) $(CFLAGS_RANDOMBYTES) -DKYBER_K=4 $(SOURCESKECCAKRANDOM) test/gen_KAT.c -o $@

test/gen_NISTKAT512: $(SOURCESNISTKATS) $(HEADERNISTKATS) test/gen_NISTKAT.c
$(CC) $(CFLAGS_NISTRANDOMBYTES) -DKYBER_K=2 $(SOURCESNISTKATS) test/gen_NISTKAT.c -o $@

test/gen_NISTKAT768: $(SOURCESNISTKATS) $(HEADERNISTKATS) test/gen_NISTKAT.c
$(CC) $(CFLAGS_NISTRANDOMBYTES) -DKYBER_K=3 $(SOURCESNISTKATS) test/gen_NISTKAT.c -o $@

test/test_kyber768: $(SOURCESKECCAK) $(HEADERSKECCAK) test/test_kyber.c randombytes/randombytes.c
$(CC) $(CFLAGS) -DKYBER_K=3 $(SOURCESKECCAK) randombytes/randombytes.c test/test_kyber.c -o $@
test/gen_NISTKAT1024: $(SOURCESNISTKATS) $(HEADERNISTKATS) test/gen_NISTKAT.c
$(CC) $(CFLAGS_NISTRANDOMBYTES) -DKYBER_K=4 $(SOURCESNISTKATS) test/gen_NISTKAT.c -o $@

test/test_kyber1024: $(SOURCESKECCAK) $(HEADERSKECCAK) test/test_kyber.c randombytes/randombytes.c
$(CC) $(CFLAGS) -DKYBER_K=4 $(SOURCESKECCAK) randombytes/randombytes.c test/test_kyber.c -o $@

clean:
-$(RM) -rf *.gcno *.gcda *.lcov *.o *.so
-$(RM) -rf test/test_kyber512
-$(RM) -rf test/test_kyber768
-$(RM) -rf test/test_kyber1024
-$(RM) -rf test/gen_KAT512
-$(RM) -rf test/gen_KAT768
-$(RM) -rf test/gen_KAT1024
-$(RM) -rf test/gen_NISTKAT512
-$(RM) -rf test/gen_NISTKAT768
-$(RM) -rf test/gen_NISTKAT1024
14 changes: 14 additions & 0 deletions checksum.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
cothan marked this conversation as resolved.
Show resolved Hide resolved
# SPDX-License-Identifier: Apache-2.0

# This script executes a binary file, captures its output, then generates and compares its SHA-256 hash with a provided one.

output_hash=$(./$1 | sha256sum | awk '{ print $1 }')

if [[ ${output_hash} == "${2}" ]]; then
echo "${1} Hashes match."
exit 0
else
echo "${1} Hashes do not match: ${output_hash} vs ${2}"
exit 1
fi
64 changes: 64 additions & 0 deletions test/gen_KAT.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: Apache-2.0
#include <stddef.h>
cothan marked this conversation as resolved.
Show resolved Hide resolved
#include <stdio.h>
#include <string.h>
#include "fips202.h"
#include "kem.h"
#include "params.h"

#define NTESTS 10000

static void print_hex(const char *label, const uint8_t *data, size_t size) {
printf("%s = ", label);
for (size_t i = 0; i < size; i++) {
printf("%02x", data[i]);
}
printf("\n");
}

static void shake256_absorb(shake256incctx *state, const uint8_t *input, size_t inlen) {
shake256_inc_init(state);
shake256_inc_absorb(state, input, inlen);
shake256_inc_finalize(state);
}

int main(void) {
uint8_t coins[3 * KYBER_SYMBYTES];
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
uint8_t sk[CRYPTO_SECRETKEYBYTES];
uint8_t ct[CRYPTO_CIPHERTEXTBYTES];
uint8_t ss1[CRYPTO_BYTES];
uint8_t ss2[CRYPTO_BYTES];

const uint8_t seed[64] = {32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
};

shake256incctx state;
shake256_absorb(&state, seed, sizeof(seed));

for (unsigned int i = 0; i < NTESTS; i++) {

shake256_inc_squeeze(coins, sizeof(coins), &state);

crypto_kem_keypair_derand(pk, sk, coins);
print_hex("pk", pk, sizeof(pk));
print_hex("sk", sk, sizeof(sk));

crypto_kem_enc_derand(ct, ss1, pk, coins + 2 * KYBER_SYMBYTES);
print_hex("ct", ct, sizeof(ct));

crypto_kem_dec(ss2, ct, sk);

if (memcmp(ss1, ss2, sizeof(ss1))) {
fprintf(stderr, "ERROR\n");
return -1;
}

print_hex("ss", ss1, sizeof(ss1));
}

return 0;
}
89 changes: 89 additions & 0 deletions test/gen_NISTKAT.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: Apache-2.0

#include <stdio.h>
#include <string.h>

#include "kem.h"
#include "randombytes.h"

static void fprintBstr(FILE *fp, const char *S, const uint8_t *A, size_t L) {
size_t i;
fprintf(fp, "%s", S);
for (i = 0; i < L; i++) {
fprintf(fp, "%02X", A[i]);
}
if (L == 0) {
fprintf(fp, "00");
}
fprintf(fp, "\n");
}

static void randombytes_nth(uint8_t *seed, size_t nth, size_t len) {
uint8_t entropy_input[48] = {0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47
};
nist_kat_init(entropy_input, NULL, 256);

for (size_t i = 0; i < nth + 1; i++) {
randombytes(seed, len);
}
}

int main(void) {
uint8_t seed[48];
FILE *fh = stdout;
uint8_t public_key[CRYPTO_PUBLICKEYBYTES];
uint8_t secret_key[CRYPTO_SECRETKEYBYTES];
uint8_t ciphertext[CRYPTO_CIPHERTEXTBYTES];
uint8_t shared_secret_e[CRYPTO_BYTES];
uint8_t shared_secret_d[CRYPTO_BYTES];
int rc;

int count = 0;

fprintf(fh, "# %s\n\n", CRYPTO_ALGNAME);

do {
fprintf(fh, "count = %d\n", count);
randombytes_nth(seed, count, 48);
fprintBstr(fh, "seed = ", seed, 48);

nist_kat_init(seed, NULL, 256);

rc = crypto_kem_keypair(public_key, secret_key);
if (rc != 0) {
fprintf(stderr, "[kat_kem] %s ERROR: crypto_kem_keypair failed!\n", CRYPTO_ALGNAME);
return -1;
}
fprintBstr(fh, "pk = ", public_key, CRYPTO_PUBLICKEYBYTES);
fprintBstr(fh, "sk = ", secret_key, CRYPTO_SECRETKEYBYTES);

rc = crypto_kem_enc(ciphertext, shared_secret_e, public_key);
if (rc != 0) {
fprintf(stderr, "[kat_kem] %s ERROR: crypto_kem_enc failed!\n", CRYPTO_ALGNAME);
return -2;
}
fprintBstr(fh, "ct = ", ciphertext, CRYPTO_CIPHERTEXTBYTES);
fprintBstr(fh, "ss = ", shared_secret_e, CRYPTO_BYTES);
fprintf(fh, "\n");

rc = crypto_kem_dec(shared_secret_d, ciphertext, secret_key);
if (rc != 0) {
fprintf(stderr, "[kat_kem] %s ERROR: crypto_kem_dec failed!\n", CRYPTO_ALGNAME);
return -3;
}

rc = memcmp(shared_secret_e, shared_secret_d, CRYPTO_BYTES);
if (rc != 0) {
fprintf(stderr, "[kat_kem] %s ERROR: shared secrets are not equal\n", CRYPTO_ALGNAME);
return -4;
}
count++;
} while (count < 100);

return 0;
}
Loading