diff --git a/README.md b/README.md index e14916a..721289b 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,6 @@ In this case, only the implementations named "rhys" and "armsrc_NEC" will be com After the compilation is finished, you will see the results in the build directory specified in the -b argument. For each compiled implementation, a subdirectory will be present containing the firmware.elf file and the logs of the stdout and stderr of the make command. -The compile_all.py script will also include the test vectors text file for each compiled algorithm from the test_vectors directory - make sure you have the test vectors for every algorithm you want to compile. - ## Running the tests Once the algorithms you plan to test are compiled, you can start the benchmarks. @@ -106,7 +104,12 @@ Make sure your Logic Analyzer is capturing. If you plan on using sigrok-mux, sta ``` This will create a UNIX domain socket at `$XDG_RUNTIME_DIR/lwc-logic-socket` which the `LogicMultiplexerTimeMeasurements` class from `test_common.py` will connect to. -Now, you can start the benchmark of an individual build algorithm by calling the `test.py` script of the appropriate template: +Place a test vector file in the directory of the tested algorithm: +```bash +cp test_vectors/romulusn1/LWC_AEAD_KAT_*.txt build/romulus.romulusn1.armsrc_NEC/LWC_AEAD_KAT.txt +``` + +Now you can start a benchmark by calling the `test.py` script of the appropriate template: ```bash PYTHONPATH="$PYTHONPATH:$(pwd)" templates/f1-libopencm3/test.py build/romulus.romulusn1.armsrc_NEC/ ``` diff --git a/compile_all.py b/compile_all.py index c89a44e..09094d6 100755 --- a/compile_all.py +++ b/compile_all.py @@ -83,18 +83,6 @@ def build(algo_dir, template_dir, build_dir): return True -# Find test vectors in the test_vectors directory -def find_test_vectors(variant): - kat = None - test_vectors_dir = os.path.join("test_vectors", variant) - for f in os.listdir(test_vectors_dir): - if f.startswith("LWC_AEAD_KAT_") and f.endswith(".txt"): - if kat is not None: - raise Exception("Multiple test vectors?") - kat = os.path.join(test_vectors_dir, f) - return kat - - def main(argv): include_list = None @@ -169,10 +157,6 @@ def main(argv): assert os.path.isdir(d) print(d) - # Test vectors file t - t = find_test_vectors(variant) - print(t) - # if include_list was provided, skip elements not in the list if include_list is not None: if n not in include_list: @@ -186,7 +170,7 @@ def main(argv): st_mtime = max(st_mtime, os.stat(path).st_mtime) # Put all in a tuple and count - files.append((t, d, n, st_mtime)) + files.append((d, n, st_mtime)) # Uncomment next line for testing, if we only want to do 1 # files = files[:1] @@ -198,7 +182,7 @@ def main(argv): print() # Build all found algorithms - for t, d, name, st_mtime in files: + for d, name, st_mtime in files: print() print(d) try: @@ -206,8 +190,6 @@ def main(argv): build(d, template_dir, build_dir) - shutil.copyfile(t, os.path.join(build_dir, 'LWC_AEAD_KAT.txt')) - mdate_path = os.path.join(build_dir, 'cipher_mtime.txt') with open(mdate_path, 'wt') as mdate_file: print(int(st_mtime), file=mdate_file) diff --git a/process_zip.sh b/process_zip.sh index 2573e35..a831223 100755 --- a/process_zip.sh +++ b/process_zip.sh @@ -50,7 +50,12 @@ function run() { for cipher in $TMPDIR/*; do if [[ ! -d $cipher ]]; then continue; fi - CIPHER_SLUG=$(basename $cipher) + CIPHER_SLUG=$(basename $cipher); + FAMILY="${CIPHER_SLUG%%.*}"; + REM="${CIPHER_SLUG#*.}"; + VARIANT="${REM%%.*}"; + IMPLEMENTATION="${REM#*.}"; + CIPHER_TIMESTAMP=$(cat "$cipher/cipher_mtime.txt") TEST_PATH="$DESTDIR/$CIPHER_SLUG" @@ -58,7 +63,7 @@ function run() { TEST_PATH=$(realpath $TEST_PATH) mv $cipher/*.log "$TEST_PATH" - mv "$cipher/LWC_AEAD_KAT.txt" "$TEST_PATH" + cp test_vectors/$VARIANT/LWC_AEAD_KAT_*.txt "$TEST_PATH/LWC_AEAD_KAT.txt" || exit 1 case $TEMPLATE in f1-libopencm3) mv $cipher/firmware.{bin,elf} "$TEST_PATH" diff --git a/templates/bluepill/src/main.ino b/templates/bluepill/src/main.ino index c84e1eb..27a1eb2 100644 --- a/templates/bluepill/src/main.ino +++ b/templates/bluepill/src/main.ino @@ -2,8 +2,8 @@ #include "api.h" #include "uartp.h" -#define MAX_BYTES 100 -#define CMDBUF_LEN 72 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 static uint8_t cmdbuf[CMDBUF_LEN]; #define CRYPTO_BUSY A7 diff --git a/templates/esp32/src/main.ino b/templates/esp32/src/main.ino index 24be19c..0d49a6f 100644 --- a/templates/esp32/src/main.ino +++ b/templates/esp32/src/main.ino @@ -2,8 +2,8 @@ #include "api.h" #include "uartp.h" -#define MAX_BYTES 100 -#define CMDBUF_LEN 72 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 static uint8_t cmdbuf[CMDBUF_LEN]; #define CRYPTO_BUSY 12 diff --git a/templates/f1-libopencm3/main.c b/templates/f1-libopencm3/main.c index 4ebdd7b..270c9ac 100644 --- a/templates/f1-libopencm3/main.c +++ b/templates/f1-libopencm3/main.c @@ -13,8 +13,8 @@ uint8_t uart_rbyte(void); static void loop(void); static void my_assert(bool b); -#define MAX_BYTES 100 -#define CMDBUF_LEN 72 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 static uint8_t cmdbuf[CMDBUF_LEN]; uint8_t npub[CRYPTO_NPUBBYTES]; diff --git a/templates/f7/Src/test.c b/templates/f7/Src/test.c index eb7ced8..b3b9927 100644 --- a/templates/f7/Src/test.c +++ b/templates/f7/Src/test.c @@ -8,7 +8,9 @@ #include "uartp.h" #include "main.h" -#define MAX_BYTES 100 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 +static uint8_t cmdbuf[CMDBUF_LEN]; uint8_t npub[CRYPTO_NPUBBYTES]; uint8_t nsec[CRYPTO_NSECBYTES]; @@ -76,15 +78,14 @@ void test_setup() { void test_loop() { - static uint8_t buf[256]; - uint16_t len = uartp_recv(buf, 255); - uint8_t action = buf[0]; + uint16_t len = uartp_recv(cmdbuf, 255); + uint8_t action = cmdbuf[0]; if (len == 0 || len > 255) return; uint16_t l = len - 1; uint16_t rl = 0; - uint8_t *var = buf+1; + uint8_t *var = cmdbuf+1; switch (action) { case 'm': my_assert(l <= MAX_BYTES); memcpy(m, var, l); mlen = l; break; case 'c': my_assert(l <= MAX_BYTES); memcpy(c, var, l); clen = l; break; @@ -120,7 +121,7 @@ void test_loop() { default: my_assert(false); } - buf[0] = action; - memcpy(buf+1, var, rl); - uartp_send(buf, rl+1); + cmdbuf[0] = action; + memcpy(cmdbuf+1, var, rl); + uartp_send(cmdbuf, rl+1); } diff --git a/templates/maixduino/src/main.ino b/templates/maixduino/src/main.ino index e0ee9c4..8a9f55c 100644 --- a/templates/maixduino/src/main.ino +++ b/templates/maixduino/src/main.ino @@ -2,8 +2,8 @@ #include "api.h" #include "uartp.h" -#define MAX_BYTES 100 -#define CMDBUF_LEN 72 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 static uint8_t cmdbuf[CMDBUF_LEN]; #define CRYPTO_BUSY 12 diff --git a/templates/uno/src/main.ino b/templates/uno/src/main.ino index dc1f117..c030bbc 100644 --- a/templates/uno/src/main.ino +++ b/templates/uno/src/main.ino @@ -2,8 +2,8 @@ #include "api.h" #include "uartp.h" -#define MAX_BYTES 100 -#define CMDBUF_LEN 72 +#define MAX_BYTES 172 +#define CMDBUF_LEN 200 static uint8_t cmdbuf[CMDBUF_LEN]; #define CRYPTO_BUSY 12 diff --git a/test_common.py b/test_common.py index 6eaeaa4..6084606 100644 --- a/test_common.py +++ b/test_common.py @@ -156,7 +156,8 @@ def run_nist_aead_test_line(dut, i, m, ad, k, npub, c): eprint(" ad = %s" % ad.hex()) eprint("npub = %s" % npub.hex()) eprint(" k = %s" % k.hex()) - eprint(" c = %s" % c.hex()) + if c is not None: + eprint(" c = %s" % c.hex()) dut.send_var(ord('c'), b"\0" * (len(m) + 32)) dut.send_var(ord('s'), b"") @@ -169,10 +170,13 @@ def run_nist_aead_test_line(dut, i, m, ad, k, npub, c): dut.do_cmd(ord('e')) output = dut.obtain_var(ord('C')) print(" c = %s" % output.hex()) - if c != output: + if c is not None and c != output: raise Exception( ("output of encryption (%s) is different from " + "expected ciphertext (%s)") % (output.hex(), c.hex())) + else: + c = output + eprint(" c = %s" % c.hex()) dut.send_var(ord('m'), b"\0" * len(c)) dut.send_var(ord('s'), b"") @@ -196,23 +200,23 @@ def parse_nist_aead_test_vectors(test_file_path): lineprog = re.compile( r"^\s*([A-Z]+)\s*=\s*(([0-9a-f])*)\s*$", re.IGNORECASE) - m = b"" - ad = b"" - k = b"" - npub = b"" - c = b"" i = -1 + m = None + ad = None + k = None + npub = None + c = None for line in test_file.readlines(): line = line.strip() res = lineprog.match(line) if line == "": yield i, m, ad, k, npub, c i = -1 - m = b"" - ad = b"" - k = b"" - npub = b"" - c = b"" + m = None + ad = None + k = None + npub = None + c = None elif res is not None: if res[1].lower() == 'count': i = int(res[2], 10) @@ -622,11 +626,32 @@ def identify_test_vector(kat_path): return False return True + def is_ae_128B(kat): + if len(kat) != 2: + return False + + def genstr(length): + return bytes([b % 256 for b in range(length)]) + expected_k = genstr(len(kat[0][3])) + expected_npub = genstr(len(kat[0][4])) + expected_i = 0 + expected_ad = b"" + for i, m, ad, k, npub, c in kat: + expected_m = genstr(0 if i == 1 else 128) + expected_i += 1 + if not (expected_i == i and expected_m == m and + expected_k == k and expected_ad == ad and + expected_npub == npub): + return False + return True + if is_nist_aead_kat(kat): return "NIST AEAD KAT" if is_nist_aead_kat_no_ad(kat): return "NIST AEAD KAT NO AD" - return None + if is_ae_128B(kat): + return "AE 128B" + raise Exception("Unknown test vector") def run_nist_lws_aead_test(dut, vectors_file, build_dir,