├── ref-c ├── param_select.h ├── template │ ├── param_select.h │ ├── nist_random.h │ ├── clean-kat.sh │ ├── build-kat.sh │ ├── ct_util.h │ ├── ct_util.c │ ├── keccakf1600.h │ ├── api.h │ ├── LICENSE │ ├── mask_random.h │ ├── racc_param.h │ ├── racc_serial.h │ ├── xof_sample.h │ ├── README.txt │ ├── racc_core.h │ ├── sha3_t.h │ ├── rng.h │ ├── mont64.h │ ├── sha3_t.c │ ├── racc_api.c │ ├── polyr.h │ ├── polyr.c │ ├── xof_sample.c │ ├── mont32.h │ ├── keccakf1600.c │ ├── plat_local.h │ └── rng.c ├── README.md ├── genkats.sh ├── Makefile.kat ├── inc │ ├── ct_util.h │ ├── keccakf1600.h │ ├── nist_random.h │ ├── test_aes1kt.h │ ├── sha3_t.h │ └── plat_local.h ├── bench.sh ├── Makefile ├── util │ ├── ct_util.c │ ├── nist_random.c │ ├── sha3_t.c │ └── keccakf1600.c ├── api.h ├── LICENSE ├── mask_random.h ├── racc_param.h ├── racc_serial.h ├── xof_sample.h ├── racc_core.h ├── nist │ ├── api-orig.h │ ├── rng.h │ └── rng.c ├── mont64.h ├── racc_api.c ├── polyr.h ├── polyr.c ├── xof_sample.c ├── mont32.h ├── test_main.c └── mask_random.c ├── doc ├── raccoon.pdf └── delivery-readme.txt ├── ref-py ├── requirements.txt ├── Makefile ├── README.md ├── LICENSE ├── nist_kat_drbg.py ├── mask_random.py ├── test_genkat.py ├── test_ntt.py ├── test_histo.py └── test_genlist.py ├── Makefile ├── ref-data ├── kat100 │ └── hashes.sh ├── bench │ ├── bench_RACCOON_128_1.txt │ ├── bench_RACCOON_128_2.txt │ ├── bench_RACCOON_128_4.txt │ ├── bench_RACCOON_128_8.txt │ ├── bench_RACCOON_192_1.txt │ ├── bench_RACCOON_192_2.txt │ ├── bench_RACCOON_192_4.txt │ ├── bench_RACCOON_192_8.txt │ ├── bench_RACCOON_256_1.txt │ ├── bench_RACCOON_256_2.txt │ ├── bench_RACCOON_256_4.txt │ ├── bench_RACCOON_256_8.txt │ ├── bench_RACCOON_128_16.txt │ ├── bench_RACCOON_128_32.txt │ ├── bench_RACCOON_192_16.txt │ ├── bench_RACCOON_192_32.txt │ ├── bench_RACCOON_256_16.txt │ ├── bench_RACCOON_256_32.txt │ └── table.sh ├── rsp-hashes10.txt └── rsp-hashes100.txt ├── .gitignore ├── LICENSE └── README.md /ref-c/param_select.h: -------------------------------------------------------------------------------- 1 | #define RACCOON_128_1 2 | 3 | -------------------------------------------------------------------------------- /ref-c/template/param_select.h: -------------------------------------------------------------------------------- 1 | #define RACCOON_128_1 2 | 3 | -------------------------------------------------------------------------------- /doc/raccoon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/masksign/raccoon/HEAD/doc/raccoon.pdf -------------------------------------------------------------------------------- /ref-c/template/nist_random.h: -------------------------------------------------------------------------------- 1 | #ifndef rng_h 2 | #include "rng.h" 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /ref-c/template/clean-kat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -f *.req *.rsp PQCgenKAT_sign 3 | 4 | -------------------------------------------------------------------------------- /ref-c/template/build-kat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | gcc -o PQCgenKAT_sign -Wall -O2 *.c -lcrypto 3 | -------------------------------------------------------------------------------- /ref-py/requirements.txt: -------------------------------------------------------------------------------- 1 | pycryptodome # https://pypi.org/project/pycryptodome/ 2 | 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | rm -rf Raccoon 3 | cd ref-py && $(MAKE) clean 4 | cd ref-c && $(MAKE) -f Makefile.kat clean 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ref-py/Makefile: -------------------------------------------------------------------------------- 1 | clean: 2 | $(RM) -f stat_* 3 | $(RM) -f *.pyc *.cprof */*.pyc *.rsp 4 | $(RM) -rf __pycache__ */__pycache__ 5 | 6 | -------------------------------------------------------------------------------- /ref-data/kat100/hashes.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | for x in *.rsp 4 | do 5 | echo -n `head -1 $x | colrm 1 2`$':\t' | expand 6 | sha256sum $x 7 | done 8 | -------------------------------------------------------------------------------- /ref-c/README.md: -------------------------------------------------------------------------------- 1 | # raccoon/ref-c 2 | 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | *(Original code was written by Markku-Juhani O. Saarinen.)* 5 | 6 | "ANSI C" Reference Implementation of Masked Raccoon for NIST API testing. 7 | 8 | -------------------------------------------------------------------------------- /ref-c/genkats.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | make clean 4 | mkdir -p kat 5 | 6 | for iut in \ 7 | RACCOON_128_1 RACCOON_128_2 RACCOON_128_4 \ 8 | RACCOON_128_8 RACCOON_128_16 RACCOON_128_32 \ 9 | RACCOON_192_1 RACCOON_192_2 RACCOON_192_4 \ 10 | RACCOON_192_8 RACCOON_192_16 RACCOON_192_32 \ 11 | RACCOON_256_1 RACCOON_256_2 RACCOON_256_4 \ 12 | RACCOON_256_8 RACCOON_256_16 RACCOON_256_32 13 | do 14 | echo === $iut === 15 | make -f Makefile.kat IUT="$iut" obj-clean 16 | make -f Makefile.kat IUT="$iut" 17 | cd kat 18 | ./xgen_$iut 19 | cd .. 20 | done 21 | -------------------------------------------------------------------------------- /ref-c/Makefile.kat: -------------------------------------------------------------------------------- 1 | # Makefile for NIST KAT files 2 | 3 | # called with different IUT parameters by genkats.sh, or directly: 4 | # make -f Makefile.kat IUT="RACCOON_128_8" 5 | 6 | # default value (ignored if set) 7 | IUT ?= "RACCOON_128_8" 8 | 9 | # number of vectors 10 | KATNUM ?= 100 11 | 12 | # name of the generating binary 13 | XBIN = kat/xgen_$(IUT) 14 | 15 | # NIST stuff 16 | CFLAGS += -DNIST_KAT -D$(IUT) -DKATNUM=$(KATNUM) -I. 17 | LDLIBS += -lcrypto 18 | CSRC += $(wildcard nist/*.c) 19 | 20 | # execute the main makefile 21 | include Makefile 22 | 23 | -------------------------------------------------------------------------------- /ref-c/inc/ct_util.h: -------------------------------------------------------------------------------- 1 | // ct_util.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Generic constant time utilities. 5 | 6 | #ifndef _CT_UTIL_H_ 7 | #define _CT_UTIL_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // returns true for equal strings, false for non-equal strings 14 | bool ct_equal(const void *a, const void *b, size_t len); 15 | 16 | // conditional move. b = 1: move x to r, b = 0: don't move, just process 17 | void ct_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); 18 | 19 | // copy memory 20 | void ct_memcpy(void *dest, const void *src, size_t len); 21 | 22 | // _CT_UTIL_H_ 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /ref-c/template/ct_util.h: -------------------------------------------------------------------------------- 1 | // ct_util.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Generic constant time utilities. 5 | 6 | #ifndef _CT_UTIL_H_ 7 | #define _CT_UTIL_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | // returns true for equal strings, false for non-equal strings 14 | bool ct_equal(const void *a, const void *b, size_t len); 15 | 16 | // conditional move. b = 1: move x to r, b = 0: don't move, just process 17 | void ct_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); 18 | 19 | // copy memory 20 | void ct_memcpy(void *dest, const void *src, size_t len); 21 | 22 | // _CT_UTIL_H_ 23 | #endif 24 | 25 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_1.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-1 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 14800 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-1.pk: ca6083ab7e255ce0788ef0f4dc483ff7 (2256) 6 | Raccoon-128-1.sk: 0f8c86ef927f80ca81ed0bff32e7aace (14800) 7 | Raccoon-128-1.sm: 04991bfe1e031906058cffc423676e6a (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-1 KeyGen() 2048: 1.000 ms 2.112 Mcyc 11 | Raccoon-128-1 Sign() 1024: 2.281 ms 4.817 Mcyc 12 | Raccoon-128-1 Verify() 4096: 0.832 ms 1.757 Mcyc 13 | racc_core.c:265:6:RACCOON_128_1_core_keygen 24784 static 14 | racc_core.c:324:6:RACCOON_128_1_core_sign 155952 static 15 | racc_core.c:465:6:RACCOON_128_1_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_2.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-2 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 14816 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-2.pk: 1a509fe62bda40f0d923f24066f6fa97 (2256) 6 | Raccoon-128-2.sk: 273bdcaf1162ee88f3b5bb2601e8bcca (14816) 7 | Raccoon-128-2.sm: 7c04046bd45b95991048a5bc8bdbea29 (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-2 KeyGen() 2048: 1.242 ms 2.624 Mcyc 11 | Raccoon-128-2 Sign() 1024: 2.563 ms 5.412 Mcyc 12 | Raccoon-128-2 Verify() 4096: 0.785 ms 1.659 Mcyc 13 | racc_core.c:265:6:RACCOON_128_2_core_keygen 24800 static 14 | racc_core.c:324:6:RACCOON_128_2_core_sign 180560 static 15 | racc_core.c:465:6:RACCOON_128_2_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_4.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-4 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 14848 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-4.pk: cb6881779c5c20ae167df22ccdc88ae4 (2256) 6 | Raccoon-128-4.sk: b86693141a59d4ffab68d9e3f294b5df (14848) 7 | Raccoon-128-4.sm: b2619479ac0e4cecfdbe540873803e1d (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-4 KeyGen() 2048: 1.646 ms 3.477 Mcyc 11 | Raccoon-128-4 Sign() 1024: 3.061 ms 6.465 Mcyc 12 | Raccoon-128-4 Verify() 4096: 0.788 ms 1.664 Mcyc 13 | racc_core.c:265:6:RACCOON_128_4_core_keygen 33040 static 14 | racc_core.c:324:6:RACCOON_128_4_core_sign 229776 static 15 | racc_core.c:465:6:RACCOON_128_4_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_8.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-8 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 14912 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-8.pk: d8d1079d64fc2d968ba74b8be614203b (2256) 6 | Raccoon-128-8.sk: 94c4bbcc169aaca32cba37f3dfcec91c (14912) 7 | Raccoon-128-8.sm: 2e820f503680a4bf3b93d6e4e49923db (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-8 KeyGen() 512: 4.457 ms 9.413 Mcyc 11 | Raccoon-128-8 Sign() 256: 8.361 ms 17.658 Mcyc 12 | Raccoon-128-8 Verify() 4096: 0.784 ms 1.656 Mcyc 13 | racc_core.c:265:6:RACCOON_128_8_core_keygen 49472 static 14 | racc_core.c:324:6:RACCOON_128_8_core_sign 328144 static 15 | racc_core.c:465:6:RACCOON_128_8_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_1.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-1 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 18840 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-1.pk: 7726626d0b4669c236b2caf41d025ed8 (3160) 6 | Raccoon-192-1.sk: bf258dfcb1b47c042870245f60254443 (18840) 7 | Raccoon-192-1.sm: 8f266eaf26dd436b214af8cb0169b8ab (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-1 KeyGen() 2048: 1.540 ms 3.252 Mcyc 11 | Raccoon-192-1 Sign() 1024: 3.248 ms 6.860 Mcyc 12 | Raccoon-192-1 Verify() 2048: 1.309 ms 2.764 Mcyc 13 | racc_core.c:265:6:RACCOON_192_1_core_keygen 28896 static 14 | racc_core.c:324:6:RACCOON_192_1_core_sign 233808 static 15 | racc_core.c:465:6:RACCOON_192_1_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_2.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-2 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 18864 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-2.pk: 8b30cffe0a52cbc88f56ff1d262ba3bd (3160) 6 | Raccoon-192-2.sk: 170406a3688b80f6698f591170a70dbb (18864) 7 | Raccoon-192-2.sm: 3337859a30e03b960cb7e8fe5ee651b4 (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-2 KeyGen() 2048: 1.872 ms 3.953 Mcyc 11 | Raccoon-192-2 Sign() 1024: 3.644 ms 7.697 Mcyc 12 | Raccoon-192-2 Verify() 2048: 1.296 ms 2.737 Mcyc 13 | racc_core.c:265:6:RACCOON_192_2_core_keygen 28928 static 14 | racc_core.c:324:6:RACCOON_192_2_core_sign 262512 static 15 | racc_core.c:465:6:RACCOON_192_2_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_4.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-4 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 18912 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-4.pk: ff65508952885e0106719f16d2a490e0 (3160) 6 | Raccoon-192-4.sk: 5d6e636c89318c4e3e079d806b5ba3f0 (18912) 7 | Raccoon-192-4.sm: 784eb49302051e682af3bd9a2b9d431f (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-4 KeyGen() 1024: 2.415 ms 5.101 Mcyc 11 | Raccoon-192-4 Sign() 512: 4.292 ms 9.064 Mcyc 12 | Raccoon-192-4 Verify() 2048: 1.308 ms 2.762 Mcyc 13 | racc_core.c:265:6:RACCOON_192_4_core_keygen 37152 static 14 | racc_core.c:324:6:RACCOON_192_4_core_sign 319904 static 15 | racc_core.c:465:6:RACCOON_192_4_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_8.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-8 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 19008 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-8.pk: ff6143f9d6b7c32b2eeeefb8ecfc51d3 (3160) 6 | Raccoon-192-8.sk: a536dcd0ba4a884caadc7c0c13e6790b (19008) 7 | Raccoon-192-8.sm: a79fe7e162766f02e1b819f7fabc39c8 (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-8 KeyGen() 512: 6.282 ms 13.268 Mcyc 11 | Raccoon-192-8 Sign() 256: 11.410 ms 24.099 Mcyc 12 | Raccoon-192-8 Verify() 2048: 1.297 ms 2.739 Mcyc 13 | racc_core.c:265:6:RACCOON_192_8_core_keygen 53600 static 14 | racc_core.c:324:6:RACCOON_192_8_core_sign 434672 static 15 | racc_core.c:465:6:RACCOON_192_8_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_1.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-1 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 26016 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-1.pk: b48aac1f59722e997006125b128c11da (4064) 6 | Raccoon-256-1.sk: d42420db34d02465c62e21288f873860 (26016) 7 | Raccoon-256-1.sm: 4951a986e19fadacaf71ad59654fabf3 (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-1 KeyGen() 1024: 2.462 ms 5.199 Mcyc 11 | Raccoon-256-1 Sign() 512: 4.764 ms 10.062 Mcyc 12 | Raccoon-256-1 Verify() 1024: 2.156 ms 4.554 Mcyc 13 | racc_core.c:265:6:RACCOON_256_1_core_keygen 37088 static 14 | racc_core.c:324:6:RACCOON_256_1_core_sign 373072 static 15 | racc_core.c:465:6:RACCOON_256_1_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_2.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-2 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 26048 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-2.pk: 7410ea49fffa347930e1b1ad39129024 (4064) 6 | Raccoon-256-2.sk: 88f65ccb24f36927a8961904c44df274 (26048) 7 | Raccoon-256-2.sm: abceec849d5beb18707ad3e32cba9680 (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-2 KeyGen() 1024: 2.926 ms 6.180 Mcyc 11 | Raccoon-256-2 Sign() 512: 5.266 ms 11.123 Mcyc 12 | Raccoon-256-2 Verify() 1024: 2.140 ms 4.520 Mcyc 13 | racc_core.c:265:6:RACCOON_256_2_core_keygen 37120 static 14 | racc_core.c:324:6:RACCOON_256_2_core_sign 409968 static 15 | racc_core.c:465:6:RACCOON_256_2_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_4.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-4 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 26112 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-4.pk: 69e13519be82a2e71ff00efb48caef61 (4064) 6 | Raccoon-256-4.sk: 1f76b5e3de4be5b4b0ba1be08774e368 (26112) 7 | Raccoon-256-4.sm: 5c6ad99c417328ad83a8115a6c54907c (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-4 KeyGen() 1024: 3.699 ms 7.811 Mcyc 11 | Raccoon-256-4 Sign() 512: 6.238 ms 13.174 Mcyc 12 | Raccoon-256-4 Verify() 1024: 2.141 ms 4.522 Mcyc 13 | racc_core.c:265:6:RACCOON_256_4_core_keygen 45344 static 14 | racc_core.c:324:6:RACCOON_256_4_core_sign 483744 static 15 | racc_core.c:465:6:RACCOON_256_4_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_8.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-8 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 26240 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-8.pk: 07c0edb932fb86a16f9317c070401535 (4064) 6 | Raccoon-256-8.sk: 7f61a90c2638f6c5c31d061e2ae18b68 (26240) 7 | Raccoon-256-8.sm: 37b6805dbf13c81d6c1968133e6574a6 (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-8 KeyGen() 256: 8.870 ms 18.734 Mcyc 11 | Raccoon-256-8 Sign() 128: 15.830 ms 33.433 Mcyc 12 | Raccoon-256-8 Verify() 1024: 2.149 ms 4.539 Mcyc 13 | racc_core.c:265:6:RACCOON_256_8_core_keygen 61792 static 14 | racc_core.c:324:6:RACCOON_256_8_core_sign 631280 static 15 | racc_core.c:465:6:RACCOON_256_8_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_16.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-16 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 15040 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-16.pk: 89f1d52e5db0d76364dd11a341d0e4c4 (2256) 6 | Raccoon-128-16.sk: 6bcbd1982ec0fb31e5c6e3aa68ef7e81 (15040) 7 | Raccoon-128-16.sm: e46ee014151d157b72e90b028e68de44 (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-16 KeyGen() 512: 6.156 ms 13.001 Mcyc 11 | Raccoon-128-16 Sign() 256: 10.695 ms 22.588 Mcyc 12 | Raccoon-128-16 Verify() 4096: 0.834 ms 1.761 Mcyc 13 | racc_core.c:265:6:RACCOON_128_16_core_keygen 152048 static 14 | racc_core.c:324:6:RACCOON_128_16_core_sign 529008 static 15 | racc_core.c:465:6:RACCOON_128_16_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_128_32.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-128-32 2 | CRYPTO_PUBLICKEYBYTES = 2256 3 | CRYPTO_SECRETKEYBYTES = 15296 4 | CRYPTO_BYTES = 11524 5 | Raccoon-128-32.pk: 714c7ed092ec38c1351c35b6dbbcceda (2256) 6 | Raccoon-128-32.sk: bcd319ec206083b97335c65501d7773e (15296) 7 | Raccoon-128-32.sm: d0455e75e7c302cf9b13f718147e9e32 (11527) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-128-32 KeyGen() 128: 19.829 ms 41.879 Mcyc 11 | Raccoon-128-32 Sign() 64: 35.104 ms 74.140 Mcyc 12 | Raccoon-128-32 Verify() 4096: 0.832 ms 1.758 Mcyc 13 | racc_core.c:265:6:RACCOON_128_32_core_keygen 283360 static 14 | racc_core.c:324:6:RACCOON_128_32_core_sign 922480 static 15 | racc_core.c:465:6:RACCOON_128_32_core_verify 53488 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_16.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-16 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 19200 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-16.pk: badcb2556ef86e64b4e88e9892420a2f (3160) 6 | Raccoon-192-16.sk: b20744331811203e7cae4efd4385b3aa (19200) 7 | Raccoon-192-16.sm: d4f9b2fb6f5632c24c2a605e5f844a0f (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-16 KeyGen() 256: 8.542 ms 18.041 Mcyc 11 | Raccoon-192-16 Sign() 256: 14.476 ms 30.574 Mcyc 12 | Raccoon-192-16 Verify() 2048: 1.297 ms 2.740 Mcyc 13 | racc_core.c:265:6:RACCOON_192_16_core_keygen 156160 static 14 | racc_core.c:324:6:RACCOON_192_16_core_sign 668288 static 15 | racc_core.c:465:6:RACCOON_192_16_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_192_32.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-192-32 2 | CRYPTO_PUBLICKEYBYTES = 3160 3 | CRYPTO_SECRETKEYBYTES = 19584 4 | CRYPTO_BYTES = 14544 5 | Raccoon-192-32.pk: 6a4472f1cbfab5a4ce661c7a4a294f2b (3160) 6 | Raccoon-192-32.sk: fae910eaf944d35e78ff6e477da76817 (19584) 7 | Raccoon-192-32.sm: 106f2e46210bd85cd1e9d4577574bf64 (14547) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-192-32 KeyGen() 128: 26.451 ms 55.866 Mcyc 11 | Raccoon-192-32 Sign() 64: 46.867 ms 98.984 Mcyc 12 | Raccoon-192-32 Verify() 2048: 1.300 ms 2.746 Mcyc 13 | racc_core.c:265:6:RACCOON_192_32_core_keygen 287472 static 14 | racc_core.c:324:6:RACCOON_192_32_core_sign 1127296 static 15 | racc_core.c:465:6:RACCOON_192_32_core_verify 65776 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_16.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-16 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 26496 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-16.pk: 4279b3c1e4c20d4f8e3fb83548f2b4a0 (4064) 6 | Raccoon-256-16.sk: c17b4dead8f69b6397a1edaad4d4fc1c (26496) 7 | Raccoon-256-16.sm: 3d416f70510b970d42f710121ee4309a (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-16 KeyGen() 256: 12.149 ms 25.659 Mcyc 11 | Raccoon-256-16 Sign() 128: 20.233 ms 42.732 Mcyc 12 | Raccoon-256-16 Verify() 1024: 2.163 ms 4.568 Mcyc 13 | racc_core.c:265:6:RACCOON_256_16_core_keygen 164352 static 14 | racc_core.c:324:6:RACCOON_256_16_core_sign 930432 static 15 | racc_core.c:465:6:RACCOON_256_16_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-data/bench/bench_RACCOON_256_32.txt: -------------------------------------------------------------------------------- 1 | CRYPTO_ALGNAME = Raccoon-256-32 2 | CRYPTO_PUBLICKEYBYTES = 4064 3 | CRYPTO_SECRETKEYBYTES = 27008 4 | CRYPTO_BYTES = 20330 5 | Raccoon-256-32.pk: a6d568dd5e748108529a603fa0e7740e (4064) 6 | Raccoon-256-32.sk: 80bec5d2aea28ef72b606ad160cbd09b (27008) 7 | Raccoon-256-32.sm: 98346b52114080d4ab0f4babec7060e7 (20333) 8 | verify fail= 0 9 | === Bench === 10 | Raccoon-256-32 KeyGen() 64: 36.587 ms 77.272 Mcyc 11 | Raccoon-256-32 Sign() 32: 63.972 ms 135.111 Mcyc 12 | Raccoon-256-32 Verify() 1024: 2.083 ms 4.400 Mcyc 13 | racc_core.c:265:6:RACCOON_256_32_core_keygen 295664 static 14 | racc_core.c:324:6:RACCOON_256_32_core_sign 1520512 static 15 | racc_core.c:465:6:RACCOON_256_32_core_verify 82176 static 16 | -------------------------------------------------------------------------------- /ref-c/bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Disable frequency scaling until the next boot. Intel: 4 | # echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo 5 | # AMD: 6 | # echo 0 > /sys/devices/system/cpu/cpufreq/boost 7 | 8 | for dut in \ 9 | RACCOON_128_1 RACCOON_128_2 RACCOON_128_4 \ 10 | RACCOON_128_8 RACCOON_128_16 RACCOON_128_32 \ 11 | RACCOON_192_1 RACCOON_192_2 RACCOON_192_4 \ 12 | RACCOON_192_8 RACCOON_192_16 RACCOON_192_32 \ 13 | RACCOON_256_1 RACCOON_256_2 RACCOON_256_4 \ 14 | RACCOON_256_8 RACCOON_256_16 RACCOON_256_32 15 | do 16 | logf=bench_$dut.txt 17 | echo === $logf === 18 | make obj-clean 19 | make RACCF="-D"$dut" -DBENCH_TIMEOUT=2.0" 20 | ./xtest | tee $logf 21 | grep -e '_core_keygen' -e '_core_sign' -e '_core_verify' racc_core.su >> $logf 22 | done 23 | -------------------------------------------------------------------------------- /ref-c/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile 2 | 3 | XBIN ?= xtest 4 | CC ?= gcc 5 | CFLAGS += -Iinc $(RACCF) 6 | CFLAGS += -Wall -Wextra -Ofast -march=native -fstack-usage 7 | # slower instrumentation flags 8 | #CFLAGS = -Wall -Wextra -Wshadow -fsanitize=address,undefined -O2 -g 9 | # options 10 | #CFLAGS += -DPOLYR_Q32 11 | #CFLAGS += -DMASK_RANDOM_ASCON 12 | CSRC += $(wildcard *.c util/*.c) 13 | OBJS = $(CSRC:.c=.o) 14 | SUFILES = $(CSRC:.c=.su) 15 | LDLIBS += 16 | 17 | # Standard Linux C compile 18 | $(XBIN): $(OBJS) 19 | $(CC) $(CFLAGS) -o $(XBIN) $(OBJS) $(LDLIBS) 20 | 21 | %.o: %.[cS] 22 | $(CC) $(CFLAGS) -c $^ -o $@ 23 | 24 | # Cleanup 25 | obj-clean: 26 | $(RM) -f $(XBIN) $(OBJS) $(SUFILES) nist/*.o nist/*.su 27 | 28 | clean: obj-clean 29 | $(RM) -f bench_* 30 | $(RM) -rf kat 31 | 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # project specific 2 | xtest 3 | xgen_* 4 | __pycache__ 5 | */__pycache__ 6 | *.rsp 7 | .DS_Store 8 | firmware.* 9 | config.h 10 | *.vvp 11 | 12 | # Prerequisites 13 | *.d 14 | 15 | # Object files 16 | *.o 17 | *.ko 18 | *.obj 19 | *.elf 20 | 21 | # Linker output 22 | *.ilk 23 | *.map 24 | *.exp 25 | 26 | # Precompiled Headers 27 | *.gch 28 | *.pch 29 | 30 | # Libraries 31 | *.lib 32 | *.a 33 | *.la 34 | *.lo 35 | 36 | # Shared objects (inc. Windows DLLs) 37 | *.dll 38 | *.so 39 | *.so.* 40 | *.dylib 41 | 42 | # Executables 43 | *.exe 44 | *.out 45 | *.app 46 | *.i*86 47 | *.x86_64 48 | *.hex 49 | 50 | # Debug files 51 | *.dSYM/ 52 | *.su 53 | *.idb 54 | *.pdb 55 | 56 | # Kernel Module Compile Results 57 | *.mod* 58 | *.cmd 59 | .tmp_versions/ 60 | modules.order 61 | Module.symvers 62 | Mkfile.old 63 | dkms.conf 64 | -------------------------------------------------------------------------------- /ref-c/util/ct_util.c: -------------------------------------------------------------------------------- 1 | // ct_util.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Generic constant time utilities. 5 | 6 | #include "ct_util.h" 7 | 8 | // returns true for equal strings, false for non-equal strings 9 | 10 | bool ct_equal(const void *a, const void *b, size_t len) 11 | { 12 | size_t i; 13 | uint32_t r; 14 | 15 | r = 0; 16 | for (i = 0; i < len; i++) { 17 | r |= ((const uint8_t *)a)[i] ^ ((const uint8_t *)b)[i]; 18 | } 19 | return (((-r) >> 31) & 1) ^ 1; 20 | } 21 | 22 | // conditional move. b = 1: move x to r, b = 0: don't move, just process 23 | 24 | void ct_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) 25 | { 26 | size_t i; 27 | 28 | b = -b; 29 | for (i = 0; i < len; i++) { 30 | r[i] ^= b & (x[i] ^ r[i]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ref-c/template/ct_util.c: -------------------------------------------------------------------------------- 1 | // ct_util.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Generic constant time utilities. 5 | 6 | #include "ct_util.h" 7 | 8 | // returns true for equal strings, false for non-equal strings 9 | 10 | bool ct_equal(const void *a, const void *b, size_t len) 11 | { 12 | size_t i; 13 | uint32_t r; 14 | 15 | r = 0; 16 | for (i = 0; i < len; i++) { 17 | r |= ((const uint8_t *)a)[i] ^ ((const uint8_t *)b)[i]; 18 | } 19 | return (((-r) >> 31) & 1) ^ 1; 20 | } 21 | 22 | // conditional move. b = 1: move x to r, b = 0: don't move, just process 23 | 24 | void ct_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) 25 | { 26 | size_t i; 27 | 28 | b = -b; 29 | for (i = 0; i < len; i++) { 30 | r[i] ^= b & (x[i] ^ r[i]); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ref-c/inc/keccakf1600.h: -------------------------------------------------------------------------------- 1 | // keccakf1600.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raw Keccak f-1600 interface. 5 | 6 | #ifndef _KECCAKF1600_H_ 7 | #define _KECCAKF1600_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include "plat_local.h" 14 | 15 | // == low-level interface, keccakf1600.c or native 16 | 17 | // clear the state 18 | void keccak_clear(uint64_t state[25]); 19 | 20 | // FIPS 202 Keccak f1600 permutation, 24 rounds 21 | void keccak_f1600(uint64_t state[25]); 22 | 23 | // extract "rate" bytes from state 24 | void keccak_extract(uint64_t* state, uint8_t* data, size_t rate); 25 | 26 | // absorb "rate" bytes via xor into the state 27 | void keccak_xorbytes(uint64_t* state, const uint8_t* data, size_t rate); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif // _KECCAKF1600_H_ 34 | -------------------------------------------------------------------------------- /ref-c/template/keccakf1600.h: -------------------------------------------------------------------------------- 1 | // keccakf1600.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raw Keccak f-1600 interface. 5 | 6 | #ifndef _KECCAKF1600_H_ 7 | #define _KECCAKF1600_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include "plat_local.h" 14 | 15 | // == low-level interface, keccakf1600.c or native 16 | 17 | // clear the state 18 | void keccak_clear(uint64_t state[25]); 19 | 20 | // FIPS 202 Keccak f1600 permutation, 24 rounds 21 | void keccak_f1600(uint64_t state[25]); 22 | 23 | // extract "rate" bytes from state 24 | void keccak_extract(uint64_t* state, uint8_t* data, size_t rate); 25 | 26 | // absorb "rate" bytes via xor into the state 27 | void keccak_xorbytes(uint64_t* state, const uint8_t* data, size_t rate); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | 33 | #endif // _KECCAKF1600_H_ 34 | -------------------------------------------------------------------------------- /ref-c/api.h: -------------------------------------------------------------------------------- 1 | // api.h 2 | // === NIST Signature API 3 | 4 | #ifndef _API_H_ 5 | #define _API_H_ 6 | 7 | #include "racc_param.h" 8 | 9 | // Set these three values apropriately for your algorithm 10 | #define CRYPTO_SECRETKEYBYTES RACC_SK_SZ 11 | #define CRYPTO_PUBLICKEYBYTES RACC_PK_SZ 12 | #define CRYPTO_BYTES RACC_SIG_SZ 13 | 14 | // Change the algorithm name 15 | #define CRYPTO_ALGNAME RACC_NAME 16 | 17 | int 18 | crypto_sign_keypair(unsigned char *pk, unsigned char *sk); 19 | 20 | int 21 | crypto_sign(unsigned char *sm, unsigned long long *smlen, 22 | const unsigned char *m, unsigned long long mlen, 23 | const unsigned char *sk); 24 | 25 | int 26 | crypto_sign_open(unsigned char *m, unsigned long long *mlen, 27 | const unsigned char *sm, unsigned long long smlen, 28 | const unsigned char *pk); 29 | 30 | /* _API_H_ */ 31 | #endif 32 | -------------------------------------------------------------------------------- /ref-c/template/api.h: -------------------------------------------------------------------------------- 1 | // api.h 2 | // === NIST Signature API 3 | 4 | #ifndef _API_H_ 5 | #define _API_H_ 6 | 7 | #include "racc_param.h" 8 | 9 | // Set these three values apropriately for your algorithm 10 | #define CRYPTO_SECRETKEYBYTES RACC_SK_SZ 11 | #define CRYPTO_PUBLICKEYBYTES RACC_PK_SZ 12 | #define CRYPTO_BYTES RACC_SIG_SZ 13 | 14 | // Change the algorithm name 15 | #define CRYPTO_ALGNAME RACC_NAME 16 | 17 | int 18 | crypto_sign_keypair(unsigned char *pk, unsigned char *sk); 19 | 20 | int 21 | crypto_sign(unsigned char *sm, unsigned long long *smlen, 22 | const unsigned char *m, unsigned long long mlen, 23 | const unsigned char *sk); 24 | 25 | int 26 | crypto_sign_open(unsigned char *m, unsigned long long *mlen, 27 | const unsigned char *sm, unsigned long long smlen, 28 | const unsigned char *pk); 29 | 30 | /* _API_H_ */ 31 | #endif 32 | -------------------------------------------------------------------------------- /ref-py/README.md: -------------------------------------------------------------------------------- 1 | # raccoon/ref-py 2 | 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | *(Original Code was written by Thomas Prest and Markku-Juhani O. Saarinen.)* 5 | 6 | Python implementation of Masked Raccoon, aimed at readability. 7 | 8 | Test: `python3 test_genkat.py`: Generate .rsp KAT files for all variants. 9 | 10 | ``` 11 | Makefile Only target: make clean 12 | mask_random.py Dummy Mask Random Generator (LFSR127 MRG) 13 | nist_kat_drbg.py NIST KAT Generator DRBG 14 | polyr.py Polynomial ring arithmetic + NTT code 15 | racc_api.py Serializaton/deserialization, NIST style functions 16 | racc_core.py Raccoon signature scheme -- Core Algorithm. 17 | README.md This file 18 | requirements.txt Python requirements: pycryptodome 19 | test_genkat.py Generate NIST KAT files (.rsp files) 20 | test_genlist.py Prettyprint parameter lists for C for TeX 21 | test_histo.py Used for signature encoding design 22 | test_ntt.py Basic tests for NTT, also generate tweak tables 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /ref-data/bench/table.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for kappa in 128 192 256 4 | do 5 | echo '\hline' 6 | for d in 1 2 4 8 16 32 7 | do 8 | fn="bench_RACCOON_${kappa}_${d}.txt" 9 | echo -n $kappa-$d 10 | echo -n '&' `grep 'KeyGen()' $fn | cut -f 3 | tr -dc '0-9.'` 11 | echo -n '&' `grep 'KeyGen()' $fn | cut -f 4 | tr -dc '0-9.'` 12 | echo -n '&' `grep 'core_keygen' $fn | cut -f 2 | tr -dc '0-9.'` 13 | echo -n '&' `grep 'Sign()' $fn | cut -f 3 | tr -dc '0-9.'` 14 | echo -n '&' `grep 'Sign()' $fn | cut -f 4 | tr -dc '0-9.'` 15 | echo -n '&' `grep 'core_sign' $fn | cut -f 2 | tr -dc '0-9.'` 16 | if [ "$d" -eq "1" ] 17 | then 18 | echo -n '&' `grep 'Verify()' $fn | cut -f 3 | tr -dc '0-9.'` 19 | echo -n '&' `grep 'Verify()' $fn | cut -f 4 | tr -dc '0-9.'` 20 | echo -n '&' `grep 'core_verify' $fn | cut -f 2 | tr -dc '0-9.'` 21 | else 22 | echo -n '& = & = & = ' 23 | fi 24 | echo '\\' 25 | done 26 | done 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Raccoon Signature Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ref-c/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Raccoon Signature Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ref-py/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Raccoon Signature Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ref-c/template/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Raccoon Signature Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ref-c/inc/nist_random.h: -------------------------------------------------------------------------------- 1 | // nist_random.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === A "NIST-compatible" DRBG API 5 | 6 | #ifndef _NIST_RANDOM_H_ 7 | #define _NIST_RANDOM_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #ifdef NIST_KAT 14 | 15 | // use the original version! 16 | #include "../nist/rng.h" 17 | 18 | #else 19 | // use the built-in version 20 | #include "test_aes1kt.h" 21 | 22 | typedef struct { 23 | uint8_t key[32]; 24 | uint8_t ctr[16]; 25 | uint32_t rk[AES256_RK_WORDS]; 26 | } aes256_ctr_drbg_t; 27 | 28 | extern aes256_ctr_drbg_t aesdrbg_global_ctx; 29 | 30 | // generic random interface 31 | 32 | void nist_randombytes_init(const uint8_t entropy_input[48], 33 | const uint8_t personalization_string[48], 34 | int security_strength); 35 | 36 | int nist_randombytes(uint8_t *x, size_t xlen); 37 | 38 | // seed expander 39 | 40 | void aes256ctr_xof_init(aes256_ctr_drbg_t *ctx, const uint8_t *input48); 41 | 42 | #define randombytes(v, len) nist_randombytes(v, len) 43 | 44 | // NIST_KAT 45 | #endif 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | 51 | // _NIST_RANDOM_H_ 52 | #endif 53 | -------------------------------------------------------------------------------- /ref-py/nist_kat_drbg.py: -------------------------------------------------------------------------------- 1 | """ 2 | nist_random.py 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | 5 | === AES-256 CTR to extract "fake" DRBG outputs that are compatible with 6 | the randombutes() call in the NIST KAT testing suite. 7 | """ 8 | 9 | from Crypto.Cipher import AES 10 | 11 | class NIST_KAT_DRBG: 12 | def __init__(self, seed): 13 | self.seed_length = 48 14 | assert len(seed) == self.seed_length 15 | self.key = bytes([0])*32 16 | self.ctr = bytes([0])*16 17 | update = self.get_bytes(self.seed_length) 18 | update = bytes(a^b for a,b in zip(update,seed)) 19 | self.key = update[:32] 20 | self.ctr = update[32:] 21 | 22 | def __increment_ctr(self): 23 | x = int.from_bytes(self.ctr, 'big') + 1 24 | self.ctr = x.to_bytes(16, byteorder='big') 25 | 26 | def get_bytes(self, num_bytes): 27 | tmp = b"" 28 | cipher = AES.new(self.key, AES.MODE_ECB) 29 | while len(tmp) < num_bytes: 30 | self.__increment_ctr() 31 | tmp += cipher.encrypt(self.ctr) 32 | return tmp[:num_bytes] 33 | 34 | def random_bytes(self, num_bytes): 35 | output_bytes = self.get_bytes(num_bytes) 36 | update = self.get_bytes(48) 37 | self.key = update[:32] 38 | self.ctr = update[32:] 39 | return output_bytes 40 | 41 | -------------------------------------------------------------------------------- /ref-c/mask_random.h: -------------------------------------------------------------------------------- 1 | // mask_random.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Mask random generator interface (dummy implementations) 5 | 6 | #ifndef _MASK_RANDOM_H_ 7 | #define _MASK_RANDOM_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include "racc_param.h" 16 | 17 | #if RACC_D > 1 18 | 19 | // We are "simulating" having d-1 independent generators with these PRNGs. 20 | // This is done to illustrate API / hardware architectural considerations. 21 | 22 | typedef struct { 23 | #ifdef MASK_RANDOM_ASCON 24 | uint64_t s[RACC_D - 1][5]; // Ascon state 25 | #else 26 | uint64_t s[RACC_D - 1][2]; // LFSR-127 state 27 | #endif 28 | } mask_random_t; 29 | 30 | // trivial self-test; return 0 if ok 31 | int mask_random_selftest(); 32 | 33 | // initialize. set seed=NULL to reset. seed_sz bound to 16/36 bytes currently 34 | void mask_random_init(mask_random_t *mrg); 35 | 36 | // get a 64-bit random number -- generator 0 <= ri < d-1 37 | uint64_t mask_rand64(mask_random_t *mrg, size_t ri); 38 | 39 | // create a uniform random polynomial -- generator 0 <= ri < d-1 40 | void mask_random_poly(mask_random_t *mrg, int64_t *r, size_t ri); 41 | 42 | // === no masking 43 | #else 44 | 45 | typedef int mask_random_t; 46 | #define mask_random_selftest() 0 47 | #define mask_random_init(mrg) 48 | #define mask_random_poly(mrg, r, ri) 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | // _MASK_RANDOM_H_ 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /ref-c/template/mask_random.h: -------------------------------------------------------------------------------- 1 | // mask_random.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Mask random generator interface (dummy implementations) 5 | 6 | #ifndef _MASK_RANDOM_H_ 7 | #define _MASK_RANDOM_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include "racc_param.h" 16 | 17 | #if RACC_D > 1 18 | 19 | // We are "simulating" having d-1 independent generators with these PRNGs. 20 | // This is done to illustrate API / hardware architectural considerations. 21 | 22 | typedef struct { 23 | #ifdef MASK_RANDOM_ASCON 24 | uint64_t s[RACC_D - 1][5]; // Ascon state 25 | #else 26 | uint64_t s[RACC_D - 1][2]; // LFSR-127 state 27 | #endif 28 | } mask_random_t; 29 | 30 | // trivial self-test; return 0 if ok 31 | int mask_random_selftest(); 32 | 33 | // initialize. set seed=NULL to reset. seed_sz bound to 16/36 bytes currently 34 | void mask_random_init(mask_random_t *mrg); 35 | 36 | // get a 64-bit random number -- generator 0 <= ri < d-1 37 | uint64_t mask_rand64(mask_random_t *mrg, size_t ri); 38 | 39 | // create a uniform random polynomial -- generator 0 <= ri < d-1 40 | void mask_random_poly(mask_random_t *mrg, int64_t *r, size_t ri); 41 | 42 | // === no masking 43 | #else 44 | 45 | typedef int mask_random_t; 46 | #define mask_random_selftest() 0 47 | #define mask_random_init(mrg) 48 | #define mask_random_poly(mrg, r, ri) 49 | #endif 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | // _MASK_RANDOM_H_ 56 | #endif 57 | 58 | -------------------------------------------------------------------------------- /ref-data/rsp-hashes10.txt: -------------------------------------------------------------------------------- 1 | 91cb0f6dde5dbfdf6f4b3c53a99fe8859d61353a2f7d40e48c47fc9efdea187b PQCsignKAT_14800.rsp 2 | 4decf74a46aab72920df1eac268f37ffa71acf2340b1783a23954028cd50320b PQCsignKAT_14816.rsp 3 | 85297a8685553be2ca74773778a339f44c9d043f4eac185246ded3509e0789c5 PQCsignKAT_14848.rsp 4 | e3f7b3c6a4e134870444b49cc249428da8b95ebb9b29d754e8554ce132e6aeaa PQCsignKAT_14912.rsp 5 | 61baf358aec8ddeadb0b2a2f81af7d2b231046065a403118cdce31939fb9a999 PQCsignKAT_15040.rsp 6 | 6c78a4419e046d4ca58e9801e6423f6b42ac299c9fe6b8310564b21d82f2997d PQCsignKAT_15296.rsp 7 | 900470845964cdcbaaf7363b55d6a18ec601aab52183249cfac268d3f3d2a20b PQCsignKAT_18840.rsp 8 | a669ad9afee54e1186d06f9e31026abe503d2fc6c84cd306d846d208b974bd34 PQCsignKAT_18864.rsp 9 | 7ffe51a5fa99c33d5380476c1df9715c4d76ea7085a8a214b6cb27d8c68e3582 PQCsignKAT_18912.rsp 10 | d00ad8042b93296aafffea481c4c234ce15cc24a83bb3507182735796fc0d3f4 PQCsignKAT_19008.rsp 11 | d482939bb952f79dfcc3982f51f2fb45c8055a1bb6625187df08e9aa36bf6b58 PQCsignKAT_19200.rsp 12 | 26f84091dbe9c2f722f71c4a1f3c1c16f570627af0934b9620d2b14a5b671822 PQCsignKAT_19584.rsp 13 | 3dcebbde9c0555c7cba178a9cc845d56bd1b161d7870f9ec36416e4eaaeca866 PQCsignKAT_26016.rsp 14 | 184d9bdb021f965f30f25cb9c9b3f0547132b5eca259fb691e09e821612b8d4c PQCsignKAT_26048.rsp 15 | 62c22d543ab9c4788e1605922ea0971c41fced3e101372fd28e71f2bddc4b3c6 PQCsignKAT_26112.rsp 16 | 87316fe3621ffaaa4c027251431edc096e830a9c28143422b0de27a9d010664e PQCsignKAT_26240.rsp 17 | 3413e4c6c5e0b795420177a5f194862e6d70847949f29e14eb6edf5d18b64a1e PQCsignKAT_26496.rsp 18 | 10f0e68a50201fab882204b62c61a0d9e5f99e7703ae5e01d737c8673b62baf4 PQCsignKAT_27008.rsp 19 | -------------------------------------------------------------------------------- /ref-data/rsp-hashes100.txt: -------------------------------------------------------------------------------- 1 | 039383b9d9b29c5a9cda63cb93666771c7c09791afaadc941341e0df670229e0 PQCsignKAT_14800.rsp 2 | 71586c2fd1ae47f17cb5c44c2b5351ab48531344041a76357ffc695098d2506c PQCsignKAT_14816.rsp 3 | ae6e775feaf9d26eac5d10bec3c742fb7ab8f6716ee96a2ce3cf2c3aa23b8ef0 PQCsignKAT_14848.rsp 4 | ffbd4df642d15da96624e2b8489b5303a97a7f6a5d60416c72108880746394ea PQCsignKAT_14912.rsp 5 | 579fbaafde26049c4f4993b28568abfb657da76e5cd0c7a83239e37d4cc43325 PQCsignKAT_15040.rsp 6 | dff454bf03e9c027d70d4443bb394cae3c5af23ed81179889a62bf98a8a916d8 PQCsignKAT_15296.rsp 7 | bb577467a15ff20d6ac88c3eb7ba3fd6b3a3e7bf8e5bc627890bb027bba8bda5 PQCsignKAT_18840.rsp 8 | 1543992c77e4a3ee08cd93daf1044e2d7816efbb6c572f167e500ee5b6e68d02 PQCsignKAT_18864.rsp 9 | 82f2b834889bacdbcbb48d51f99c15639a235a764714ba858b415fdf546c9dbc PQCsignKAT_18912.rsp 10 | b21ecba12cafa88a8337a813e9dac131a50f043f860241f7cd36f8b502233971 PQCsignKAT_19008.rsp 11 | 57e3c6d014c7283806f4cd3d9c83737c6d381202a1649042c499c5c354f7606b PQCsignKAT_19200.rsp 12 | 49a552559d6a68175996de373232e0863496834c16b4d2772781f0e01469b621 PQCsignKAT_19584.rsp 13 | 031d4976f4c09b90ecec5c535b5ab3bcb020b9cb4f95e17dfdcedb10de1425fc PQCsignKAT_26016.rsp 14 | 8936afaf3fd6cf5b43716e006977e1c14a2624913bfd23adb850aa141ef2ae91 PQCsignKAT_26048.rsp 15 | 2e3ae8a29435ce8621a98390874fa2193756c87741f02934018650163c57e369 PQCsignKAT_26112.rsp 16 | 893bf614327740610c29781db7973bbfa7069010039bfa9b2ba02a9a675a78ab PQCsignKAT_26240.rsp 17 | 663ce05beb35184b0012e638ed8c918f945b379a9bd35a97e37141798c320acf PQCsignKAT_26496.rsp 18 | 594169ee1ddc6238fbbfae0178d0ed8fab9eb0205066fe382f6ff788c775bd58 PQCsignKAT_27008.rsp 19 | -------------------------------------------------------------------------------- /ref-c/racc_param.h: -------------------------------------------------------------------------------- 1 | // racc_param.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Derived parameters. 5 | 6 | #ifndef _RACC_PARAM_H_ 7 | #define _RACC_PARAM_H_ 8 | 9 | // select a default parameter if somehow not defied 10 | #if !defined(NIST_KAT) && !defined(BENCH_TIMEOUT) 11 | #include "param_select.h" 12 | #endif 13 | 14 | // include the parameter list 15 | #include "param_list.h" 16 | 17 | // Byte size of symmetric keys / pre-image security 18 | #define RACC_SEC (RACC_KAPPA / 8) 19 | 20 | // Byte size for collision resistant hashes 21 | #define RACC_CRH ((2 * RACC_KAPPA) / 8) 22 | 23 | // Size of A_seed 24 | #define RACC_AS_SZ RACC_SEC 25 | 26 | // Size of public key hash used in BUFFing -- needs CRH 27 | #define RACC_TR_SZ RACC_CRH 28 | 29 | // size of pk-bound message mu = H(H(pk), msg) 30 | #define RACC_MU_SZ RACC_CRH 31 | 32 | // Size of challenge hash 33 | #define RACC_CH_SZ RACC_CRH 34 | 35 | // Size of "mask keys" in serialized secret key 36 | #define RACC_MK_SZ RACC_SEC 37 | 38 | // shared / derived parameters 39 | #if (RACC_Q == 549824583172097) && (RACC_N == 512) 40 | #define RACC_Q_BITS 49 41 | #define RACC_LGN 9 42 | #else 43 | #error "No known parameter defined." 44 | #endif 45 | 46 | #define RACC_QMSK ((1LL << RACC_Q_BITS) - 1) 47 | #define RACC_LGW (RACC_Q_BITS - RACC_NUW) 48 | #define RACC_QT (RACC_Q >> RACC_NUT) 49 | #define RACC_QW (RACC_Q >> RACC_NUW) 50 | 51 | // "low bits" in Z encoding 52 | #define RACC_ZLBITS 40 53 | 54 | // scaled inifinity norm for hint 55 | #define RACC_BOO_H ((RACC_BOO + (1l << (RACC_NUW - 1))) >> RACC_NUW) 56 | 57 | // _RACC_PARAM_H_ 58 | #endif 59 | -------------------------------------------------------------------------------- /ref-c/racc_serial.h: -------------------------------------------------------------------------------- 1 | // racc_serial.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Serialize/deserialize. 5 | 6 | #ifndef _RACC_SERIAL_H_ 7 | #define _RACC_SERIAL_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "racc_param.h" 14 | 15 | // === Global namespace prefix 16 | 17 | #ifdef RACC_ 18 | #define racc_encode_pk RACC_(encode_pk) 19 | #define racc_decode_pk RACC_(decode_pk) 20 | #define racc_encode_sk RACC_(encode_sk) 21 | #define racc_decode_sk RACC_(decode_sk) 22 | #define racc_encode_sig RACC_(encode_sig) 23 | #define racc_decode_sig RACC_(decode_sig) 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | // Encode public key "pk" to bytes "b". Return length in bytes. 31 | size_t racc_encode_pk(uint8_t *b, const racc_pk_t *pk); 32 | 33 | // Decode a public key from "b" to "pk". Return length in bytes. 34 | size_t racc_decode_pk(racc_pk_t *pk, const uint8_t *b); 35 | 36 | // Encode secret key "sk" to bytes "b". Return length in bytes. 37 | size_t racc_encode_sk(uint8_t *b, const racc_sk_t *sk); 38 | 39 | // Decode a secret key from "b" to "sk". Return length in bytes. 40 | size_t racc_decode_sk(racc_sk_t *sk, const uint8_t *b); 41 | 42 | // Encode signature "sig" to "*b" of max "b_sz" bytes. Return length in 43 | // bytes or zero in case of overflow. 44 | size_t racc_encode_sig(uint8_t *b, size_t b_sz, const racc_sig_t *sig); 45 | 46 | // decode bytes "b" into signature "sig". Return length in bytes. 47 | size_t racc_decode_sig(racc_sig_t *sig, const uint8_t *b); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | // _RACC_SERIAL_H_ 54 | #endif 55 | -------------------------------------------------------------------------------- /ref-c/template/racc_param.h: -------------------------------------------------------------------------------- 1 | // racc_param.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Derived parameters. 5 | 6 | #ifndef _RACC_PARAM_H_ 7 | #define _RACC_PARAM_H_ 8 | 9 | // select a default parameter if somehow not defied 10 | #if !defined(NIST_KAT) && !defined(BENCH_TIMEOUT) 11 | #include "param_select.h" 12 | #endif 13 | 14 | // include the parameter list 15 | #include "param_list.h" 16 | 17 | // Byte size of symmetric keys / pre-image security 18 | #define RACC_SEC (RACC_KAPPA / 8) 19 | 20 | // Byte size for collision resistant hashes 21 | #define RACC_CRH ((2 * RACC_KAPPA) / 8) 22 | 23 | // Size of A_seed 24 | #define RACC_AS_SZ RACC_SEC 25 | 26 | // Size of public key hash used in BUFFing -- needs CRH 27 | #define RACC_TR_SZ RACC_CRH 28 | 29 | // size of pk-bound message mu = H(H(pk), msg) 30 | #define RACC_MU_SZ RACC_CRH 31 | 32 | // Size of challenge hash 33 | #define RACC_CH_SZ RACC_CRH 34 | 35 | // Size of "mask keys" in serialized secret key 36 | #define RACC_MK_SZ RACC_SEC 37 | 38 | // shared / derived parameters 39 | #if (RACC_Q == 549824583172097) && (RACC_N == 512) 40 | #define RACC_Q_BITS 49 41 | #define RACC_LGN 9 42 | #else 43 | #error "No known parameter defined." 44 | #endif 45 | 46 | #define RACC_QMSK ((1LL << RACC_Q_BITS) - 1) 47 | #define RACC_LGW (RACC_Q_BITS - RACC_NUW) 48 | #define RACC_QT (RACC_Q >> RACC_NUT) 49 | #define RACC_QW (RACC_Q >> RACC_NUW) 50 | 51 | // "low bits" in Z encoding 52 | #define RACC_ZLBITS 40 53 | 54 | // scaled inifinity norm for hint 55 | #define RACC_BOO_H ((RACC_BOO + (1l << (RACC_NUW - 1))) >> RACC_NUW) 56 | 57 | // _RACC_PARAM_H_ 58 | #endif 59 | -------------------------------------------------------------------------------- /ref-c/template/racc_serial.h: -------------------------------------------------------------------------------- 1 | // racc_serial.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Serialize/deserialize. 5 | 6 | #ifndef _RACC_SERIAL_H_ 7 | #define _RACC_SERIAL_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "racc_param.h" 14 | 15 | // === Global namespace prefix 16 | 17 | #ifdef RACC_ 18 | #define racc_encode_pk RACC_(encode_pk) 19 | #define racc_decode_pk RACC_(decode_pk) 20 | #define racc_encode_sk RACC_(encode_sk) 21 | #define racc_decode_sk RACC_(decode_sk) 22 | #define racc_encode_sig RACC_(encode_sig) 23 | #define racc_decode_sig RACC_(decode_sig) 24 | #endif 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | // Encode public key "pk" to bytes "b". Return length in bytes. 31 | size_t racc_encode_pk(uint8_t *b, const racc_pk_t *pk); 32 | 33 | // Decode a public key from "b" to "pk". Return length in bytes. 34 | size_t racc_decode_pk(racc_pk_t *pk, const uint8_t *b); 35 | 36 | // Encode secret key "sk" to bytes "b". Return length in bytes. 37 | size_t racc_encode_sk(uint8_t *b, const racc_sk_t *sk); 38 | 39 | // Decode a secret key from "b" to "sk". Return length in bytes. 40 | size_t racc_decode_sk(racc_sk_t *sk, const uint8_t *b); 41 | 42 | // Encode signature "sig" to "*b" of max "b_sz" bytes. Return length in 43 | // bytes or zero in case of overflow. 44 | size_t racc_encode_sig(uint8_t *b, size_t b_sz, const racc_sig_t *sig); 45 | 46 | // decode bytes "b" into signature "sig". Return length in bytes. 47 | size_t racc_decode_sig(racc_sig_t *sig, const uint8_t *b); 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | // _RACC_SERIAL_H_ 54 | #endif 55 | -------------------------------------------------------------------------------- /ref-c/xof_sample.h: -------------------------------------------------------------------------------- 1 | // xof_sample.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Samplers and XOF functions 5 | 6 | #ifndef _XOF_SAMPLE_H_ 7 | #define _XOF_SAMPLE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "racc_param.h" 14 | 15 | // === Global namespace prefix 16 | #ifdef RACC_ 17 | #define xof_sample_q RACC_(xof_sample_q) 18 | #define xof_sample_u RACC_(xof_sample_u) 19 | #define xof_chal_mu RACC_(xof_chal_mu) 20 | #define xof_chal_hash RACC_(xof_chal_hash) 21 | #define xof_chal_poly RACC_(xof_chal_poly) 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | // Compute mu = H(tr, m) where tr = H(pk), "m" is message of "m_sz" bytes. 29 | void xof_chal_mu( uint8_t mu[RACC_MU_SZ], const uint8_t tr[RACC_TR_SZ], 30 | const uint8_t *m, size_t m_sz); 31 | 32 | // Expand "seed" of "seed_sz" bytes to a uniform polynomial (mod q). 33 | // The input seed is assumed to alredy contain domain separation. 34 | void xof_sample_q(int64_t r[RACC_N], const uint8_t *seed, size_t seed_sz); 35 | 36 | // Sample "bits"-wide signed coefficients from "seed[seed_sz]". 37 | // The input seed is assumed to alredy contain domain separation. 38 | void xof_sample_u(int64_t r[RACC_N], int bits, 39 | const uint8_t *seed, size_t seed_sz); 40 | 41 | // Hash "w" vector with "mu" to produce challenge hash "ch". 42 | void xof_chal_hash( uint8_t ch[RACC_CH_SZ], const uint8_t mu[RACC_MU_SZ], 43 | const int64_t w[RACC_K][RACC_N]); 44 | 45 | // Create a challenge polynomial "cp" from a challenge hash "ch". 46 | void xof_chal_poly( int64_t cp[RACC_N], const uint8_t ch[RACC_CH_SZ]); 47 | 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | // _XOF_SAMPLE_H_ 54 | #endif 55 | -------------------------------------------------------------------------------- /ref-py/mask_random.py: -------------------------------------------------------------------------------- 1 | """ 2 | mask_random.py 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | 5 | === This is a dummy (LFSR-127) masking noise generator. 6 | 7 | Equivalent Verilog: 8 | 9 | // state register, 127-bit 10 | reg [126:0] v_r = 127'h0f1e2d3c4b5a69788796a5b4c3d2e1f0; 11 | 12 | // period 2^127-1, primitive polynomial x^127+x^64+1, 64 steps 13 | wire [63:0] x_w = { v_r[126:64], v_r[63] ^ v_r[126] }; 14 | wire [126:0] v_w = { x_w[62:0] ^ v_r[62:0], x_w }; 15 | 16 | always @(posedge clk) begin 17 | v_r <= v_w; 18 | end 19 | """ 20 | 21 | MRG_INIT = 0x0F1E2D3C4B5A69788796A5B4C3D2E1F0 22 | MRG_MASK = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 23 | MRG_QMOD = 549824583172097 24 | MRG_QMSK = 0x1FFFFFFFFFFFF 25 | 26 | class MaskRandom: 27 | 28 | def __init__(self, seed=b''): 29 | self.s = MRG_INIT 30 | for i in range(min(len(seed), 16)): 31 | self.s ^= seed[i] << (i * 8) 32 | 33 | def step64(self): 34 | x = (self.s >> 63) ^ (self.s >> 126); 35 | self.s = (((self.s ^ x) << 64) ^ x) & MRG_MASK 36 | 37 | def uniform_q(self): 38 | """Uniform number [0,q-1].""" 39 | while True: 40 | self.step64() 41 | z = self.s & MRG_QMSK 42 | if z < MRG_QMOD: 43 | return z 44 | 45 | def random_poly(self,n=512): 46 | """A vector of n random numbers in [0,q-1].""" 47 | return [ self.uniform_q() for _ in range(n) ] 48 | 49 | 50 | # print test values matching the verilog testbench 51 | if (__name__ == "__main__"): 52 | 53 | kat = [ 0x05A7896B4D2F1, 0x14BC078F169E6, 0x168B1A47A1FC9, 54 | 0x046E3B916EC5F, 0x05CA43AD9E72D, 0x0348F079E16E5 ] 55 | 56 | mrg = MaskRandom() 57 | 58 | for z in kat: 59 | x = mrg.uniform_q() 60 | print(f'0x{x:013X} 0x{z:013X} {x==z}') 61 | 62 | -------------------------------------------------------------------------------- /ref-c/template/xof_sample.h: -------------------------------------------------------------------------------- 1 | // xof_sample.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Samplers and XOF functions 5 | 6 | #ifndef _XOF_SAMPLE_H_ 7 | #define _XOF_SAMPLE_H_ 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "racc_param.h" 14 | 15 | // === Global namespace prefix 16 | #ifdef RACC_ 17 | #define xof_sample_q RACC_(xof_sample_q) 18 | #define xof_sample_u RACC_(xof_sample_u) 19 | #define xof_chal_mu RACC_(xof_chal_mu) 20 | #define xof_chal_hash RACC_(xof_chal_hash) 21 | #define xof_chal_poly RACC_(xof_chal_poly) 22 | #endif 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | // Compute mu = H(tr, m) where tr = H(pk), "m" is message of "m_sz" bytes. 29 | void xof_chal_mu( uint8_t mu[RACC_MU_SZ], const uint8_t tr[RACC_TR_SZ], 30 | const uint8_t *m, size_t m_sz); 31 | 32 | // Expand "seed" of "seed_sz" bytes to a uniform polynomial (mod q). 33 | // The input seed is assumed to alredy contain domain separation. 34 | void xof_sample_q(int64_t r[RACC_N], const uint8_t *seed, size_t seed_sz); 35 | 36 | // Sample "bits"-wide signed coefficients from "seed[seed_sz]". 37 | // The input seed is assumed to alredy contain domain separation. 38 | void xof_sample_u(int64_t r[RACC_N], int bits, 39 | const uint8_t *seed, size_t seed_sz); 40 | 41 | // Hash "w" vector with "mu" to produce challenge hash "ch". 42 | void xof_chal_hash( uint8_t ch[RACC_CH_SZ], const uint8_t mu[RACC_MU_SZ], 43 | const int64_t w[RACC_K][RACC_N]); 44 | 45 | // Create a challenge polynomial "cp" from a challenge hash "ch". 46 | void xof_chal_poly( int64_t cp[RACC_N], const uint8_t ch[RACC_CH_SZ]); 47 | 48 | 49 | #ifdef __cplusplus 50 | } 51 | #endif 52 | 53 | // _XOF_SAMPLE_H_ 54 | #endif 55 | -------------------------------------------------------------------------------- /ref-c/inc/test_aes1kt.h: -------------------------------------------------------------------------------- 1 | // test_aes1kt.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === AES 128/192/256 block encryption for NIST test vector generation. 5 | 6 | #ifndef _TEST_AES1KT_H_ 7 | #define _TEST_AES1KT_H_ 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #include "plat_local.h" 13 | 14 | // instantiate these if you include this header file 15 | #define aes128_enc_key aes1kt128_enc_key 16 | #define aes192_enc_key aes1kt192_enc_key 17 | #define aes256_enc_key aes1kt256_enc_key 18 | #define aes128_enc_ecb aes1kt128_enc_ecb 19 | #define aes192_enc_ecb aes1kt192_enc_ecb 20 | #define aes256_enc_ecb aes1kt256_enc_ecb 21 | #define aes_enc_rounds aes1kt_enc_rounds 22 | 23 | // number of rounds 24 | #define AES128_ROUNDS 10 25 | #define AES192_ROUNDS 12 26 | #define AES256_ROUNDS 14 27 | 28 | // expanded key size 29 | #define AES128_RK_WORDS (4 * (AES128_ROUNDS + 1)) 30 | #define AES192_RK_WORDS (4 * (AES192_ROUNDS + 1)) 31 | #define AES256_RK_WORDS (4 * (AES256_ROUNDS + 1)) 32 | 33 | // Set encryption key 34 | 35 | void aes1kt128_enc_key(uint32_t rk[AES128_RK_WORDS], const uint8_t key[16]); 36 | 37 | void aes1kt192_enc_key(uint32_t rk[AES192_RK_WORDS], const uint8_t key[24]); 38 | 39 | void aes1kt256_enc_key(uint32_t rk[AES256_RK_WORDS], const uint8_t key[32]); 40 | 41 | // Encrypt a block 42 | 43 | void aes1kt128_enc_ecb(uint8_t ct[16], const uint8_t pt[16], 44 | const uint32_t rk[AES128_RK_WORDS]); 45 | 46 | void aes1kt192_enc_ecb(uint8_t ct[16], const uint8_t pt[16], 47 | const uint32_t rk[AES192_RK_WORDS]); 48 | 49 | void aes1kt256_enc_ecb(uint8_t ct[16], const uint8_t pt[16], 50 | const uint32_t rk[AES256_RK_WORDS]); 51 | 52 | // Sometimes you want to cover all versions with same code 53 | 54 | void aes1kt_enc_rounds(uint8_t ct[16], const uint8_t pt[16], 55 | const uint32_t rk[], int nr); 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif // _TEST_AES1KT_H_ 62 | -------------------------------------------------------------------------------- /ref-c/racc_core.h: -------------------------------------------------------------------------------- 1 | // racc_core.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Core internal API. 5 | 6 | #ifndef _RACC_CORE_H_ 7 | #define _RACC_CORE_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "racc_param.h" 18 | 19 | // === Global namespace prefix 20 | #ifdef RACC_ 21 | #define racc_core_keygen RACC_(core_keygen) 22 | #define racc_core_sign RACC_(core_sign) 23 | #define racc_core_verify RACC_(core_verify) 24 | #endif 25 | 26 | // === Internal structures === 27 | 28 | // raccoon public key 29 | typedef struct { 30 | uint8_t a_seed[RACC_AS_SZ]; // seed for a 31 | int64_t t[RACC_K][RACC_N]; // public key 32 | uint8_t tr[RACC_TR_SZ]; // hash of serialized public key 33 | } racc_pk_t; 34 | 35 | // raccoon secret key 36 | typedef struct { 37 | racc_pk_t pk; // copy of public key 38 | int64_t s[RACC_ELL][RACC_D][RACC_N]; // d-masked secret key 39 | } racc_sk_t; 40 | 41 | // raccoon signature 42 | typedef struct { 43 | uint8_t ch[RACC_CH_SZ]; // challenge hash 44 | int64_t h[RACC_K][RACC_N]; // hint 45 | int64_t z[RACC_ELL][RACC_N]; // signature data 46 | } racc_sig_t; 47 | 48 | // === Core API === 49 | 50 | // Generate a public-secret keypair ("pk", "sk"). 51 | void racc_core_keygen(racc_pk_t *pk, racc_sk_t *sk); 52 | 53 | // Create a detached signature "sig" for digest "mu" using secret key "sk". 54 | void racc_core_sign(racc_sig_t *sig, const uint8_t mu[RACC_MU_SZ], 55 | racc_sk_t *sk); 56 | 57 | // Verify that the signature "sig" is valid for digest "mu". 58 | // Returns true iff signature is valid, false if not valid. 59 | bool racc_core_verify( const racc_sig_t *sig, 60 | const uint8_t mu[RACC_MU_SZ], 61 | const racc_pk_t *pk); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | // _RACC_CORE_H_ 68 | #endif 69 | -------------------------------------------------------------------------------- /ref-c/template/README.txt: -------------------------------------------------------------------------------- 1 | RACCOON -- ANSI C REFERENCE IMPLEMENTATION 2 | 3 | The directories Reference_Implementation/* and Optimized_Implementation/* are 4 | equivalent apart from `param_select.h`, which defines the variant used. 5 | 6 | Inventory: 7 | 8 | api.h NIST API Definitions 9 | build-kat.sh Build a KAT generator executable 10 | clean-kat.sh Cleanup KAT generator 11 | ct_util.c Generic constant time utilities 12 | ct_util.h " 13 | keccakf1600.c Keccak permutation for a "generic 64-bit" target 14 | keccakf1600.h " 15 | LICENSE MIT License 16 | mask_random.c Mask random generator (dummy implementations) 17 | mask_random.h " 18 | mont32.h Portable 32-bit Montgomery arithmetic 19 | mont64.h Portable 64-bit Montgomery arithmetic 20 | nist_random.h Wrapper to rng.h 21 | ntt32.c 32-bit Number Theoretic Transform 22 | ntt64.c 64-bit Number Theoretic Transform 23 | param_list.h All parameter sets 24 | param_select.h Single-line file that selects the parameter set 25 | plat_local.h Local platform helper macros 26 | polyr.c Polynomial arithmetic and ring Zq[x]/(x^n+1) 27 | polyr.h " 28 | PQCgenKAT_sign.c NIST KAT Generator main() 29 | racc_api.c Raccoon signature scheme -- NIST KAT Generator API 30 | racc_core.c Raccoon signature scheme -- Core scheme 31 | racc_core.h Raccoon signature scheme -- Core internal API 32 | racc_param.h Raccoon signature scheme -- Derived parameters 33 | racc_serial.c Raccoon signature scheme -- Serialize/deserialize 34 | racc_serial.h " 35 | README.txt This file 36 | rng.c NIST KAT Generator DRBG 37 | rng.h " 38 | sha3_t.c Common wrappers for SHA3 (FIPS 202) functionality 39 | sha3_t.h " 40 | xof_sample.c Raccoon signature scheme -- Samplers and XOF functions 41 | xof_sample.h " 42 | 43 | -------------------------------------------------------------------------------- /ref-c/template/racc_core.h: -------------------------------------------------------------------------------- 1 | // racc_core.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Core internal API. 5 | 6 | #ifndef _RACC_CORE_H_ 7 | #define _RACC_CORE_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "racc_param.h" 18 | 19 | // === Global namespace prefix 20 | #ifdef RACC_ 21 | #define racc_core_keygen RACC_(core_keygen) 22 | #define racc_core_sign RACC_(core_sign) 23 | #define racc_core_verify RACC_(core_verify) 24 | #endif 25 | 26 | // === Internal structures === 27 | 28 | // raccoon public key 29 | typedef struct { 30 | uint8_t a_seed[RACC_AS_SZ]; // seed for a 31 | int64_t t[RACC_K][RACC_N]; // public key 32 | uint8_t tr[RACC_TR_SZ]; // hash of serialized public key 33 | } racc_pk_t; 34 | 35 | // raccoon secret key 36 | typedef struct { 37 | racc_pk_t pk; // copy of public key 38 | int64_t s[RACC_ELL][RACC_D][RACC_N]; // d-masked secret key 39 | } racc_sk_t; 40 | 41 | // raccoon signature 42 | typedef struct { 43 | uint8_t ch[RACC_CH_SZ]; // challenge hash 44 | int64_t h[RACC_K][RACC_N]; // hint 45 | int64_t z[RACC_ELL][RACC_N]; // signature data 46 | } racc_sig_t; 47 | 48 | // === Core API === 49 | 50 | // Generate a public-secret keypair ("pk", "sk"). 51 | void racc_core_keygen(racc_pk_t *pk, racc_sk_t *sk); 52 | 53 | // Create a detached signature "sig" for digest "mu" using secret key "sk". 54 | void racc_core_sign(racc_sig_t *sig, const uint8_t mu[RACC_MU_SZ], 55 | racc_sk_t *sk); 56 | 57 | // Verify that the signature "sig" is valid for digest "mu". 58 | // Returns true iff signature is valid, false if not valid. 59 | bool racc_core_verify( const racc_sig_t *sig, 60 | const uint8_t mu[RACC_MU_SZ], 61 | const racc_pk_t *pk); 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | 67 | // _RACC_CORE_H_ 68 | #endif 69 | -------------------------------------------------------------------------------- /ref-c/inc/sha3_t.h: -------------------------------------------------------------------------------- 1 | // sha3_t.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === SHA3 (FIPS 202) related prototypes and shared functions. 5 | 6 | #ifndef _PQHM_SHA3_H_ 7 | #define _PQHM_SHA3_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include "plat_local.h" 14 | 15 | #define SHAKE128_RATE 168 16 | #define SHAKE256_RATE 136 17 | #define SHA3_224_RATE 144 18 | #define SHA3_256_RATE 136 19 | #define SHA3_384_RATE 104 20 | #define SHA3_512_RATE 72 21 | 22 | #define SHA3_PAD 0x06 23 | #define SHAKE_PAD 0x1F 24 | 25 | 26 | // === Incremental interface for FIPS 202 functions === 27 | 28 | typedef struct { 29 | uint8_t b[200]; 30 | uint64_t s[25]; 31 | size_t r, i; 32 | } sha3_t; 33 | 34 | // Initialize the Keccak constant for algorithm-specific rate "r". 35 | 36 | void sha3_init(sha3_t* kec, size_t r); 37 | 38 | // Absorb "m_sz" bytes from "m" into the Keccak context "kec". 39 | 40 | void sha3_absorb(sha3_t* kec, const uint8_t* m, size_t m_sz); 41 | 42 | // Move from absorb phase to squeeze phase and add a padding byte "p". 43 | 44 | void sha3_pad(sha3_t* kec, uint8_t p); 45 | 46 | // Squeeze "h_sz" bytes to address "h" from Keccak context "kec". 47 | 48 | void sha3_squeeze(sha3_t* kec, uint8_t* h, size_t h_sz); 49 | 50 | // Clear sensitive information from the Keccak context "kec." 51 | 52 | void sha3_clear(sha3_t* kec); 53 | 54 | // === Single-call SHA3 hash interface === 55 | 56 | void sha3_hash( uint8_t* h, size_t h_sz, const uint8_t* m, size_t m_sz); 57 | 58 | #define sha3_224(h, m, m_sz) sha3_hash(h, 28, m, m_sz) 59 | #define sha3_256(h, m, m_sz) sha3_hash(h, 32, m, m_sz) 60 | #define sha3_384(h, m, m_sz) sha3_hash(h, 48, m, m_sz) 61 | #define sha3_512(h, m, m_sz) sha3_hash(h, 64, m, m_sz) 62 | 63 | // === Single-call SHAKE XOF interface === 64 | 65 | void shake_xof( uint8_t* h, size_t h_sz, 66 | const uint8_t* m, size_t m_sz, size_t r); 67 | 68 | #define shake128(h, h_sz, m, m_sz) shake_xof(h, h_sz, m, m_sz, SHAKE128_RATE) 69 | #define shake256(h, h_sz, m, m_sz) shake_xof(h, h_sz, m, m_sz, SHAKE256_RATE) 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | // _PQHM_SHA3_H_ 76 | #endif 77 | -------------------------------------------------------------------------------- /ref-c/template/sha3_t.h: -------------------------------------------------------------------------------- 1 | // sha3_t.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === SHA3 (FIPS 202) related prototypes and shared functions. 5 | 6 | #ifndef _PQHM_SHA3_H_ 7 | #define _PQHM_SHA3_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include "plat_local.h" 14 | 15 | #define SHAKE128_RATE 168 16 | #define SHAKE256_RATE 136 17 | #define SHA3_224_RATE 144 18 | #define SHA3_256_RATE 136 19 | #define SHA3_384_RATE 104 20 | #define SHA3_512_RATE 72 21 | 22 | #define SHA3_PAD 0x06 23 | #define SHAKE_PAD 0x1F 24 | 25 | 26 | // === Incremental interface for FIPS 202 functions === 27 | 28 | typedef struct { 29 | uint8_t b[200]; 30 | uint64_t s[25]; 31 | size_t r, i; 32 | } sha3_t; 33 | 34 | // Initialize the Keccak constant for algorithm-specific rate "r". 35 | 36 | void sha3_init(sha3_t* kec, size_t r); 37 | 38 | // Absorb "m_sz" bytes from "m" into the Keccak context "kec". 39 | 40 | void sha3_absorb(sha3_t* kec, const uint8_t* m, size_t m_sz); 41 | 42 | // Move from absorb phase to squeeze phase and add a padding byte "p". 43 | 44 | void sha3_pad(sha3_t* kec, uint8_t p); 45 | 46 | // Squeeze "h_sz" bytes to address "h" from Keccak context "kec". 47 | 48 | void sha3_squeeze(sha3_t* kec, uint8_t* h, size_t h_sz); 49 | 50 | // Clear sensitive information from the Keccak context "kec." 51 | 52 | void sha3_clear(sha3_t* kec); 53 | 54 | // === Single-call SHA3 hash interface === 55 | 56 | void sha3_hash( uint8_t* h, size_t h_sz, const uint8_t* m, size_t m_sz); 57 | 58 | #define sha3_224(h, m, m_sz) sha3_hash(h, 28, m, m_sz) 59 | #define sha3_256(h, m, m_sz) sha3_hash(h, 32, m, m_sz) 60 | #define sha3_384(h, m, m_sz) sha3_hash(h, 48, m, m_sz) 61 | #define sha3_512(h, m, m_sz) sha3_hash(h, 64, m, m_sz) 62 | 63 | // === Single-call SHAKE XOF interface === 64 | 65 | void shake_xof( uint8_t* h, size_t h_sz, 66 | const uint8_t* m, size_t m_sz, size_t r); 67 | 68 | #define shake128(h, h_sz, m, m_sz) shake_xof(h, h_sz, m, m_sz, SHAKE128_RATE) 69 | #define shake256(h, h_sz, m, m_sz) shake_xof(h, h_sz, m, m_sz, SHAKE256_RATE) 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | // _PQHM_SHA3_H_ 76 | #endif 77 | -------------------------------------------------------------------------------- /ref-c/nist/api-orig.h: -------------------------------------------------------------------------------- 1 | /* 2 | NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. 3 | 4 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 5 | 6 | You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. 7 | */ 8 | 9 | // This is a sample 'api.h' for use 'sign.c' 10 | 11 | #ifndef api_h 12 | #define api_h 13 | 14 | // Set these three values apropriately for your algorithm 15 | #define CRYPTO_SECRETKEYBYTES 256 16 | #define CRYPTO_PUBLICKEYBYTES 85 17 | #define CRYPTO_BYTES 128 18 | 19 | // Change the algorithm name 20 | #define CRYPTO_ALGNAME "UserDefinedAlgName" 21 | 22 | int 23 | crypto_sign_keypair(unsigned char *pk, unsigned char *sk); 24 | 25 | int 26 | crypto_sign(unsigned char *sm, unsigned long long *smlen, 27 | const unsigned char *m, unsigned long long mlen, 28 | const unsigned char *sk); 29 | 30 | int 31 | crypto_sign_open(unsigned char *m, unsigned long long *mlen, 32 | const unsigned char *sm, unsigned long long smlen, 33 | const unsigned char *pk); 34 | 35 | #endif /* api_h */ 36 | -------------------------------------------------------------------------------- /ref-c/util/nist_random.c: -------------------------------------------------------------------------------- 1 | // nist_random.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Provides randombytes() compatible with AES-based NIST rng. 5 | 6 | #ifndef NIST_KAT 7 | // (only if the original generator is not used) 8 | 9 | #include 10 | #include "nist_random.h" 11 | 12 | // shared random generator 13 | 14 | aes256_ctr_drbg_t aesdrbg_global_ctx = {0}; 15 | 16 | // (not constant time ) 17 | 18 | static inline void aesdrbg_inc_ctr(uint8_t ctr[16]) 19 | { 20 | int i; 21 | uint32_t x; 22 | 23 | x = 1; 24 | 25 | for (i = 15; i >= 0; i--) { 26 | x += (uint32_t)ctr[i]; 27 | ctr[i] = (uint8_t)x; 28 | x >>= 8; 29 | } 30 | } 31 | 32 | static void aesdrbg_update(aes256_ctr_drbg_t *ctx, const uint8_t *input48) 33 | { 34 | size_t i; 35 | uint8_t tmp[48]; 36 | 37 | for (i = 0; i < 48; i += 16) { 38 | aesdrbg_inc_ctr(ctx->ctr); 39 | aes256_enc_ecb(tmp + i, ctx->ctr, ctx->rk); 40 | } 41 | if (input48 != NULL) { 42 | for (i = 0; i < 48; i++) 43 | tmp[i] ^= input48[i]; 44 | } 45 | memcpy(ctx->key, tmp, 32); 46 | memcpy(ctx->ctr, tmp + 32, 16); 47 | aes256_enc_key(ctx->rk, ctx->key); 48 | } 49 | 50 | void aes256ctr_xof_init(aes256_ctr_drbg_t *ctx, const uint8_t *input48) 51 | { 52 | memset(ctx->key, 0x00, 32); 53 | memset(ctx->ctr, 0x00, 16); 54 | aes256_enc_key(ctx->rk, ctx->key); 55 | 56 | aesdrbg_update(ctx, input48); 57 | } 58 | 59 | int aes256ctr_xof(void *ctx, void *buf, size_t len) 60 | { 61 | uint8_t tmp[16]; 62 | aes256_ctr_drbg_t *drbg = ctx; 63 | uint8_t *x = buf; 64 | 65 | while (len > 0) { 66 | // increment ctr 67 | aesdrbg_inc_ctr(drbg->ctr); 68 | aes256_enc_ecb(tmp, drbg->ctr, drbg->rk); 69 | 70 | if (len > 15) { 71 | memcpy(x, tmp, 16); 72 | x += 16; 73 | len -= 16; 74 | } else { 75 | memcpy(x, tmp, len); 76 | len = 0; 77 | } 78 | } 79 | aesdrbg_update(drbg, NULL); 80 | 81 | return 0; 82 | } 83 | 84 | // nist test vector initialize 85 | 86 | void nist_randombytes_init(const uint8_t entropy_input[48], 87 | const uint8_t personalization_string[48], 88 | int security_strength) 89 | { 90 | (void)(security_strength); // not used 91 | uint8_t seed[48]; 92 | 93 | if (personalization_string != NULL) { 94 | for (size_t i = 0; i < 48; i++) { 95 | seed[i] = entropy_input[i] ^ personalization_string[i]; 96 | } 97 | entropy_input = seed; 98 | } 99 | 100 | aes256ctr_xof_init(&aesdrbg_global_ctx, entropy_input); 101 | } 102 | 103 | // nist test vector generator 104 | 105 | int nist_randombytes(uint8_t *x, size_t xlen) 106 | { 107 | return aes256ctr_xof(&aesdrbg_global_ctx, x, xlen); 108 | } 109 | 110 | // NIST_KAT 111 | #endif 112 | -------------------------------------------------------------------------------- /ref-c/nist/rng.h: -------------------------------------------------------------------------------- 1 | /* 2 | NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. 3 | 4 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 5 | 6 | You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. 7 | */ 8 | 9 | #ifndef rng_h 10 | #define rng_h 11 | 12 | #include 13 | 14 | #define RNG_SUCCESS 0 15 | #define RNG_BAD_MAXLEN -1 16 | #define RNG_BAD_OUTBUF -2 17 | #define RNG_BAD_REQ_LEN -3 18 | 19 | typedef struct { 20 | unsigned char buffer[16]; 21 | int buffer_pos; 22 | unsigned long length_remaining; 23 | unsigned char key[32]; 24 | unsigned char ctr[16]; 25 | } AES_XOF_struct; 26 | 27 | typedef struct { 28 | unsigned char Key[32]; 29 | unsigned char V[16]; 30 | int reseed_counter; 31 | } AES256_CTR_DRBG_struct; 32 | 33 | 34 | void 35 | AES256_CTR_DRBG_Update(unsigned char *provided_data, 36 | unsigned char *Key, 37 | unsigned char *V); 38 | 39 | int 40 | seedexpander_init(AES_XOF_struct *ctx, 41 | unsigned char *seed, 42 | unsigned char *diversifier, 43 | unsigned long maxlen); 44 | 45 | int 46 | seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen); 47 | 48 | void 49 | randombytes_init(unsigned char *entropy_input, 50 | unsigned char *personalization_string, 51 | int security_strength); 52 | 53 | int 54 | randombytes(unsigned char *x, unsigned long long xlen); 55 | 56 | #endif /* rng_h */ 57 | -------------------------------------------------------------------------------- /ref-c/template/rng.h: -------------------------------------------------------------------------------- 1 | /* 2 | NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. 3 | 4 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 5 | 6 | You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. 7 | */ 8 | 9 | #ifndef rng_h 10 | #define rng_h 11 | 12 | #include 13 | 14 | #define RNG_SUCCESS 0 15 | #define RNG_BAD_MAXLEN -1 16 | #define RNG_BAD_OUTBUF -2 17 | #define RNG_BAD_REQ_LEN -3 18 | 19 | typedef struct { 20 | unsigned char buffer[16]; 21 | int buffer_pos; 22 | unsigned long length_remaining; 23 | unsigned char key[32]; 24 | unsigned char ctr[16]; 25 | } AES_XOF_struct; 26 | 27 | typedef struct { 28 | unsigned char Key[32]; 29 | unsigned char V[16]; 30 | int reseed_counter; 31 | } AES256_CTR_DRBG_struct; 32 | 33 | 34 | void 35 | AES256_CTR_DRBG_Update(unsigned char *provided_data, 36 | unsigned char *Key, 37 | unsigned char *V); 38 | 39 | int 40 | seedexpander_init(AES_XOF_struct *ctx, 41 | unsigned char *seed, 42 | unsigned char *diversifier, 43 | unsigned long maxlen); 44 | 45 | int 46 | seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen); 47 | 48 | void 49 | randombytes_init(unsigned char *entropy_input, 50 | unsigned char *personalization_string, 51 | int security_strength); 52 | 53 | int 54 | randombytes(unsigned char *x, unsigned long long xlen); 55 | 56 | #endif /* rng_h */ 57 | -------------------------------------------------------------------------------- /ref-c/mont64.h: -------------------------------------------------------------------------------- 1 | // mont64.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Portable 64-bit Montgomery arithmetic 5 | 6 | #ifndef _MONT64_H_ 7 | #define _MONT64_H_ 8 | 9 | #include "plat_local.h" 10 | #include "racc_param.h" 11 | 12 | #if (RACC_N != 512 || RACC_Q != 549824583172097l) 13 | #error "Unrecognized polynomial parameters N, Q" 14 | #endif 15 | 16 | /* 17 | n = 512 18 | q1 = 2^24-2^18+1 19 | q2 = 2^25-2^18+1 20 | q = q1*q2 21 | r = 2^64 % q 22 | rr = r^2 % q 23 | ni = lift(rr * Mod(n,q)^-1) 24 | qi = lift(Mod(-q,2^64)^-1) 25 | */ 26 | 27 | // Montgomery constants. These depend on Q and N 28 | #define MONT_R 129308285697266L 29 | #define MONT_RR 506614974174448L 30 | #define MONT_NI 293083792181611L 31 | #define MONT_QI 2231854466648768511L 32 | 33 | // Addition and subtraction 34 | 35 | static inline int64_t mont64_add(int64_t x, int64_t y) 36 | { 37 | return x + y; 38 | } 39 | 40 | static inline int64_t mont64_sub(int64_t x, int64_t y) 41 | { 42 | return x - y; 43 | } 44 | // Conditionally add m if x is negative 45 | 46 | static inline int64_t mont64_cadd(int64_t x, int64_t m) 47 | { 48 | int64_t t, r; 49 | 50 | XASSUME(x >= -m && x < m); 51 | 52 | t = x >> 63; 53 | r = x + (t & m); 54 | 55 | XASSERT(r >= 0 && r < m); 56 | XASSERT(r == x || r == x + m); 57 | 58 | return r; 59 | } 60 | 61 | // Conditionally subtract m if x >= m 62 | 63 | static inline int64_t mont64_csub(int64_t x, int64_t m) 64 | { 65 | int64_t t, r; 66 | 67 | XASSUME(x >= 0 && x < 2 * m); 68 | XASSUME(m > 0); 69 | 70 | t = x - m; 71 | r = t + ((t >> 63) & m); 72 | 73 | XASSERT(r >= 0 && r < m); 74 | XASSERT(r == x || r == x - m); 75 | 76 | return r; 77 | } 78 | 79 | // Montgomery reduction. Returns r in [-q,q-1] so that r == (x/2^64) mod q. 80 | 81 | static inline int64_t mont64_redc(__int128 x) 82 | { 83 | int64_t r; 84 | 85 | // prove these input bounds 86 | XASSUME(x >= -(((__int128)1) << 111)); 87 | XASSUME(x < (((__int128)1) << 111)); 88 | 89 | r = x * MONT_QI; 90 | r = (x + ((__int128)r) * ((__int128)RACC_Q)) >> 64; 91 | 92 | // prove that only one coditional addition is required 93 | XASSERT(r >= -RACC_Q && r < RACC_Q); 94 | 95 | #ifdef XDEBUG 96 | // this modular reduction correctness proof is too slow for SAT 97 | XASSERT(((((__int128)x) - (((__int128)r) << 64)) % 98 | ((__int128_t)RACC_Q)) == 0); 99 | #endif 100 | return r; 101 | } 102 | 103 | // Montgomery multiplication. r in [-q,q-1] so that r == (a*b)/2^64) mod q. 104 | 105 | static inline int64_t mont64_mulq(int64_t x, int64_t y) 106 | { 107 | int64_t r; 108 | 109 | r = mont64_redc(((__int128)x) * ((__int128)y)); 110 | 111 | return r; 112 | } 113 | 114 | // same with addition 115 | 116 | static inline int64_t mont64_mulqa(int64_t x, int64_t y, int64_t z) 117 | { 118 | int64_t r; 119 | 120 | r = mont64_redc(((__int128)x) * ((__int128)y) + ((__int128)z)); 121 | 122 | return r; 123 | } 124 | 125 | // _MONT64_H_ 126 | #endif 127 | -------------------------------------------------------------------------------- /ref-c/template/mont64.h: -------------------------------------------------------------------------------- 1 | // mont64.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Portable 64-bit Montgomery arithmetic 5 | 6 | #ifndef _MONT64_H_ 7 | #define _MONT64_H_ 8 | 9 | #include "plat_local.h" 10 | #include "racc_param.h" 11 | 12 | #if (RACC_N != 512 || RACC_Q != 549824583172097l) 13 | #error "Unrecognized polynomial parameters N, Q" 14 | #endif 15 | 16 | /* 17 | n = 512 18 | q1 = 2^24-2^18+1 19 | q2 = 2^25-2^18+1 20 | q = q1*q2 21 | r = 2^64 % q 22 | rr = r^2 % q 23 | ni = lift(rr * Mod(n,q)^-1) 24 | qi = lift(Mod(-q,2^64)^-1) 25 | */ 26 | 27 | // Montgomery constants. These depend on Q and N 28 | #define MONT_R 129308285697266L 29 | #define MONT_RR 506614974174448L 30 | #define MONT_NI 293083792181611L 31 | #define MONT_QI 2231854466648768511L 32 | 33 | // Addition and subtraction 34 | 35 | static inline int64_t mont64_add(int64_t x, int64_t y) 36 | { 37 | return x + y; 38 | } 39 | 40 | static inline int64_t mont64_sub(int64_t x, int64_t y) 41 | { 42 | return x - y; 43 | } 44 | // Conditionally add m if x is negative 45 | 46 | static inline int64_t mont64_cadd(int64_t x, int64_t m) 47 | { 48 | int64_t t, r; 49 | 50 | XASSUME(x >= -m && x < m); 51 | 52 | t = x >> 63; 53 | r = x + (t & m); 54 | 55 | XASSERT(r >= 0 && r < m); 56 | XASSERT(r == x || r == x + m); 57 | 58 | return r; 59 | } 60 | 61 | // Conditionally subtract m if x >= m 62 | 63 | static inline int64_t mont64_csub(int64_t x, int64_t m) 64 | { 65 | int64_t t, r; 66 | 67 | XASSUME(x >= 0 && x < 2 * m); 68 | XASSUME(m > 0); 69 | 70 | t = x - m; 71 | r = t + ((t >> 63) & m); 72 | 73 | XASSERT(r >= 0 && r < m); 74 | XASSERT(r == x || r == x - m); 75 | 76 | return r; 77 | } 78 | 79 | // Montgomery reduction. Returns r in [-q,q-1] so that r == (x/2^64) mod q. 80 | 81 | static inline int64_t mont64_redc(__int128 x) 82 | { 83 | int64_t r; 84 | 85 | // prove these input bounds 86 | XASSUME(x >= -(((__int128)1) << 111)); 87 | XASSUME(x < (((__int128)1) << 111)); 88 | 89 | r = x * MONT_QI; 90 | r = (x + ((__int128)r) * ((__int128)RACC_Q)) >> 64; 91 | 92 | // prove that only one coditional addition is required 93 | XASSERT(r >= -RACC_Q && r < RACC_Q); 94 | 95 | #ifdef XDEBUG 96 | // this modular reduction correctness proof is too slow for SAT 97 | XASSERT(((((__int128)x) - (((__int128)r) << 64)) % 98 | ((__int128_t)RACC_Q)) == 0); 99 | #endif 100 | return r; 101 | } 102 | 103 | // Montgomery multiplication. r in [-q,q-1] so that r == (a*b)/2^64) mod q. 104 | 105 | static inline int64_t mont64_mulq(int64_t x, int64_t y) 106 | { 107 | int64_t r; 108 | 109 | r = mont64_redc(((__int128)x) * ((__int128)y)); 110 | 111 | return r; 112 | } 113 | 114 | // same with addition 115 | 116 | static inline int64_t mont64_mulqa(int64_t x, int64_t y, int64_t z) 117 | { 118 | int64_t r; 119 | 120 | r = mont64_redc(((__int128)x) * ((__int128)y) + ((__int128)z)); 121 | 122 | return r; 123 | } 124 | 125 | // _MONT64_H_ 126 | #endif 127 | -------------------------------------------------------------------------------- /ref-c/template/sha3_t.c: -------------------------------------------------------------------------------- 1 | // sha3_t.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Common wrappers for SHA3 (FIPS 202) functionality. 5 | 6 | #include 7 | 8 | #include "sha3_t.h" 9 | #include "keccakf1600.h" 10 | 11 | // Initialize the Keccak context "kec" for algorithm-specific rate "r". 12 | 13 | void sha3_init(sha3_t* kec, size_t r) 14 | { 15 | keccak_clear(kec->s); 16 | kec->i = 0; 17 | kec->r = r; 18 | } 19 | 20 | // Absorb "m_sz" bytes from "m" into the Keccak context "kec". 21 | 22 | void sha3_absorb(sha3_t* kec, const uint8_t* m, size_t m_sz) 23 | { 24 | size_t l; 25 | 26 | l = kec->r - kec->i; 27 | if (m_sz < l) { 28 | memcpy(kec->b + kec->i, m, m_sz); 29 | kec->i += m_sz; 30 | return; 31 | } 32 | if (kec->i > 0) { 33 | memcpy(kec->b + kec->i, m, l); 34 | keccak_xorbytes(kec->s, kec->b, kec->r); 35 | keccak_f1600(kec->s); 36 | m_sz -= l; 37 | m += l; 38 | kec->i = 0; 39 | } 40 | while (m_sz >= kec->r) { 41 | keccak_xorbytes(kec->s, m, kec->r); 42 | keccak_f1600(kec->s); 43 | m_sz -= kec->r; 44 | m += kec->r; 45 | } 46 | memcpy(kec->b, m, m_sz); 47 | kec->i = m_sz; 48 | } 49 | 50 | // Move from absorb phase to squeeze phase and add a padding byte "p". 51 | 52 | void sha3_pad(sha3_t* kec, uint8_t p) 53 | { 54 | kec->b[kec->i++] = p; 55 | memset(kec->b + kec->i, 0, kec->r - kec->i); 56 | kec->b[kec->r - 1] |= 0x80; 57 | keccak_xorbytes(kec->s, kec->b, kec->r); 58 | kec->i = kec->r; 59 | } 60 | 61 | // Squeeze "h_sz" bytes to address "h" from Keccak context "kec". 62 | 63 | void sha3_squeeze(sha3_t* kec, uint8_t* h, size_t h_sz) 64 | { 65 | size_t l; 66 | 67 | while (h_sz > 0) { 68 | if (kec->i >= kec->r) { 69 | keccak_f1600(kec->s); 70 | keccak_extract(kec->s, kec->b, kec->r); 71 | kec->i = 0; 72 | } 73 | l = kec->r - kec->i; 74 | if (h_sz <= l) { 75 | memcpy(h, kec->b + kec->i, h_sz); 76 | kec->i += h_sz; 77 | return; 78 | } 79 | memcpy(h, kec->b + kec->i, l); 80 | h += l; 81 | h_sz -= l; 82 | kec->i += l; 83 | } 84 | } 85 | 86 | // Clear sensitive information from the Keccak context "kec." 87 | 88 | void sha3_clear(sha3_t* kec) 89 | { 90 | memset(kec, 0, sizeof(sha3_t)); 91 | } 92 | 93 | // function for single-call sha3 94 | 95 | void sha3_hash(uint8_t* h, size_t h_sz, const uint8_t* m, size_t m_sz) 96 | { 97 | sha3_t kec; 98 | 99 | sha3_init(&kec, 200 - 2 * h_sz); 100 | sha3_absorb(&kec, m, m_sz); 101 | sha3_pad(&kec, SHA3_PAD); 102 | sha3_squeeze(&kec, h, h_sz); 103 | } 104 | 105 | // function for single-call shake at rate r 106 | 107 | void shake_xof( uint8_t* h, size_t h_sz, 108 | const uint8_t* m, size_t m_sz, size_t r) 109 | { 110 | sha3_t kec; 111 | 112 | sha3_init(&kec, r); 113 | sha3_absorb(&kec, m, m_sz); 114 | sha3_pad(&kec, SHAKE_PAD); 115 | sha3_squeeze(&kec, h, h_sz); 116 | } 117 | -------------------------------------------------------------------------------- /ref-c/util/sha3_t.c: -------------------------------------------------------------------------------- 1 | // sha3_t.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Common wrappers for SHA3 (FIPS 202) functionality. 5 | 6 | #include 7 | 8 | #include "sha3_t.h" 9 | #include "keccakf1600.h" 10 | 11 | // Initialize the Keccak context "kec" for algorithm-specific rate "r". 12 | 13 | void sha3_init(sha3_t* kec, size_t r) 14 | { 15 | keccak_clear(kec->s); 16 | kec->i = 0; 17 | kec->r = r; 18 | } 19 | 20 | // Absorb "m_sz" bytes from "m" into the Keccak context "kec". 21 | 22 | void sha3_absorb(sha3_t* kec, const uint8_t* m, size_t m_sz) 23 | { 24 | size_t l; 25 | 26 | l = kec->r - kec->i; 27 | if (m_sz < l) { 28 | memcpy(kec->b + kec->i, m, m_sz); 29 | kec->i += m_sz; 30 | return; 31 | } 32 | if (kec->i > 0) { 33 | memcpy(kec->b + kec->i, m, l); 34 | keccak_xorbytes(kec->s, kec->b, kec->r); 35 | keccak_f1600(kec->s); 36 | m_sz -= l; 37 | m += l; 38 | kec->i = 0; 39 | } 40 | while (m_sz >= kec->r) { 41 | keccak_xorbytes(kec->s, m, kec->r); 42 | keccak_f1600(kec->s); 43 | m_sz -= kec->r; 44 | m += kec->r; 45 | } 46 | memcpy(kec->b, m, m_sz); 47 | kec->i = m_sz; 48 | } 49 | 50 | // Move from absorb phase to squeeze phase and add a padding byte "p". 51 | 52 | void sha3_pad(sha3_t* kec, uint8_t p) 53 | { 54 | kec->b[kec->i++] = p; 55 | memset(kec->b + kec->i, 0, kec->r - kec->i); 56 | kec->b[kec->r - 1] |= 0x80; 57 | keccak_xorbytes(kec->s, kec->b, kec->r); 58 | kec->i = kec->r; 59 | } 60 | 61 | // Squeeze "h_sz" bytes to address "h" from Keccak context "kec". 62 | 63 | void sha3_squeeze(sha3_t* kec, uint8_t* h, size_t h_sz) 64 | { 65 | size_t l; 66 | 67 | while (h_sz > 0) { 68 | if (kec->i >= kec->r) { 69 | keccak_f1600(kec->s); 70 | keccak_extract(kec->s, kec->b, kec->r); 71 | kec->i = 0; 72 | } 73 | l = kec->r - kec->i; 74 | if (h_sz <= l) { 75 | memcpy(h, kec->b + kec->i, h_sz); 76 | kec->i += h_sz; 77 | return; 78 | } 79 | memcpy(h, kec->b + kec->i, l); 80 | h += l; 81 | h_sz -= l; 82 | kec->i += l; 83 | } 84 | } 85 | 86 | // Clear sensitive information from the Keccak context "kec." 87 | 88 | void sha3_clear(sha3_t* kec) 89 | { 90 | memset(kec, 0, sizeof(sha3_t)); 91 | } 92 | 93 | // function for single-call sha3 94 | 95 | void sha3_hash(uint8_t* h, size_t h_sz, const uint8_t* m, size_t m_sz) 96 | { 97 | sha3_t kec; 98 | 99 | sha3_init(&kec, 200 - 2 * h_sz); 100 | sha3_absorb(&kec, m, m_sz); 101 | sha3_pad(&kec, SHA3_PAD); 102 | sha3_squeeze(&kec, h, h_sz); 103 | } 104 | 105 | // function for single-call shake at rate r 106 | 107 | void shake_xof( uint8_t* h, size_t h_sz, 108 | const uint8_t* m, size_t m_sz, size_t r) 109 | { 110 | sha3_t kec; 111 | 112 | sha3_init(&kec, r); 113 | sha3_absorb(&kec, m, m_sz); 114 | sha3_pad(&kec, SHAKE_PAD); 115 | sha3_squeeze(&kec, h, h_sz); 116 | } 117 | -------------------------------------------------------------------------------- /ref-c/racc_api.c: -------------------------------------------------------------------------------- 1 | // racc_api.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- NIST KAT Generator API. 5 | 6 | #include 7 | 8 | #include "api.h" 9 | #include "racc_core.h" 10 | #include "racc_serial.h" 11 | #include "xof_sample.h" 12 | 13 | // Generates a keypair - pk is the public key and sk is the secret key. 14 | 15 | int 16 | crypto_sign_keypair( unsigned char *pk, unsigned char *sk) 17 | { 18 | racc_pk_t r_pk; // internal-format public key 19 | racc_sk_t r_sk; // internal-format secret key 20 | 21 | racc_core_keygen(&r_pk, &r_sk); // generate keypair 22 | 23 | // serialize 24 | if (CRYPTO_PUBLICKEYBYTES != racc_encode_pk(pk, &r_pk) || 25 | CRYPTO_SECRETKEYBYTES != racc_encode_sk(sk, &r_sk)) 26 | return -1; 27 | 28 | return 0; 29 | } 30 | 31 | // Sign a message: sm is the signed message, m is the original message, 32 | // and sk is the secret key. 33 | 34 | int 35 | crypto_sign(unsigned char *sm, unsigned long long *smlen, 36 | const unsigned char *m, unsigned long long mlen, 37 | const unsigned char *sk) 38 | { 39 | racc_sk_t r_sk; // internal-format secret key 40 | racc_sig_t r_sig; // internal-format signature 41 | uint8_t mu[RACC_MU_SZ]; 42 | size_t sig_sz; 43 | // deserialize secret key 44 | if (CRYPTO_SECRETKEYBYTES != racc_decode_sk(&r_sk, sk)) 45 | return -1; 46 | 47 | xof_chal_mu(mu, r_sk.pk.tr, m, mlen); // compute mu 48 | 49 | // several trials may be needed in case of signature size overflow 50 | do { 51 | racc_core_sign(&r_sig, mu, &r_sk); // create signature 52 | 53 | // The NIST API expects an "envelope" consisting of the message 54 | // together with signature. we put the signature first. 55 | sig_sz = racc_encode_sig(sm, CRYPTO_BYTES, &r_sig); 56 | } while (sig_sz == 0); 57 | 58 | memset(sm + sig_sz, 0, CRYPTO_BYTES - sig_sz); // zero padding 59 | memcpy(sm + CRYPTO_BYTES, m, mlen); // add the message 60 | 61 | *smlen = mlen + CRYPTO_BYTES; 62 | 63 | return 0; 64 | } 65 | 66 | // Verify a message signature: m is the original message, sm is the signed 67 | // message, pk is the public key. 68 | 69 | int 70 | crypto_sign_open(unsigned char *m, unsigned long long *mlen, 71 | const unsigned char *sm, unsigned long long smlen, 72 | const unsigned char *pk) 73 | { 74 | racc_pk_t r_pk; // internal-format public key 75 | racc_sig_t r_sig; // internal-format signature 76 | size_t m_sz; 77 | uint8_t mu[RACC_MU_SZ]; 78 | 79 | // deserialize public key, signature with a consistency check 80 | if (smlen < CRYPTO_BYTES || 81 | CRYPTO_PUBLICKEYBYTES != racc_decode_pk(&r_pk, pk) || 82 | CRYPTO_BYTES != racc_decode_sig(&r_sig, sm)) 83 | return -1; 84 | m_sz = smlen - CRYPTO_BYTES; 85 | 86 | // compute mu 87 | xof_chal_mu(mu, r_pk.tr, sm + CRYPTO_BYTES, m_sz); 88 | 89 | // verification 90 | if (!racc_core_verify(&r_sig, mu, &r_pk)) 91 | return -1; 92 | 93 | // store the length and move the "opened" message 94 | memcpy(m, sm + CRYPTO_BYTES, m_sz); 95 | *mlen = m_sz; 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /ref-c/template/racc_api.c: -------------------------------------------------------------------------------- 1 | // racc_api.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- NIST KAT Generator API. 5 | 6 | #include 7 | 8 | #include "api.h" 9 | #include "racc_core.h" 10 | #include "racc_serial.h" 11 | #include "xof_sample.h" 12 | 13 | // Generates a keypair - pk is the public key and sk is the secret key. 14 | 15 | int 16 | crypto_sign_keypair( unsigned char *pk, unsigned char *sk) 17 | { 18 | racc_pk_t r_pk; // internal-format public key 19 | racc_sk_t r_sk; // internal-format secret key 20 | 21 | racc_core_keygen(&r_pk, &r_sk); // generate keypair 22 | 23 | // serialize 24 | if (CRYPTO_PUBLICKEYBYTES != racc_encode_pk(pk, &r_pk) || 25 | CRYPTO_SECRETKEYBYTES != racc_encode_sk(sk, &r_sk)) 26 | return -1; 27 | 28 | return 0; 29 | } 30 | 31 | // Sign a message: sm is the signed message, m is the original message, 32 | // and sk is the secret key. 33 | 34 | int 35 | crypto_sign(unsigned char *sm, unsigned long long *smlen, 36 | const unsigned char *m, unsigned long long mlen, 37 | const unsigned char *sk) 38 | { 39 | racc_sk_t r_sk; // internal-format secret key 40 | racc_sig_t r_sig; // internal-format signature 41 | uint8_t mu[RACC_MU_SZ]; 42 | size_t sig_sz; 43 | // deserialize secret key 44 | if (CRYPTO_SECRETKEYBYTES != racc_decode_sk(&r_sk, sk)) 45 | return -1; 46 | 47 | xof_chal_mu(mu, r_sk.pk.tr, m, mlen); // compute mu 48 | 49 | // several trials may be needed in case of signature size overflow 50 | do { 51 | racc_core_sign(&r_sig, mu, &r_sk); // create signature 52 | 53 | // The NIST API expects an "envelope" consisting of the message 54 | // together with signature. we put the signature first. 55 | sig_sz = racc_encode_sig(sm, CRYPTO_BYTES, &r_sig); 56 | } while (sig_sz == 0); 57 | 58 | memset(sm + sig_sz, 0, CRYPTO_BYTES - sig_sz); // zero padding 59 | memcpy(sm + CRYPTO_BYTES, m, mlen); // add the message 60 | 61 | *smlen = mlen + CRYPTO_BYTES; 62 | 63 | return 0; 64 | } 65 | 66 | // Verify a message signature: m is the original message, sm is the signed 67 | // message, pk is the public key. 68 | 69 | int 70 | crypto_sign_open(unsigned char *m, unsigned long long *mlen, 71 | const unsigned char *sm, unsigned long long smlen, 72 | const unsigned char *pk) 73 | { 74 | racc_pk_t r_pk; // internal-format public key 75 | racc_sig_t r_sig; // internal-format signature 76 | size_t m_sz; 77 | uint8_t mu[RACC_MU_SZ]; 78 | 79 | // deserialize public key, signature with a consistency check 80 | if (smlen < CRYPTO_BYTES || 81 | CRYPTO_PUBLICKEYBYTES != racc_decode_pk(&r_pk, pk) || 82 | CRYPTO_BYTES != racc_decode_sig(&r_sig, sm)) 83 | return -1; 84 | m_sz = smlen - CRYPTO_BYTES; 85 | 86 | // compute mu 87 | xof_chal_mu(mu, r_pk.tr, sm + CRYPTO_BYTES, m_sz); 88 | 89 | // verification 90 | if (!racc_core_verify(&r_sig, mu, &r_pk)) 91 | return -1; 92 | 93 | // store the length and move the "opened" message 94 | memcpy(m, sm + CRYPTO_BYTES, m_sz); 95 | *mlen = m_sz; 96 | 97 | return 0; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nist-ref 2 | 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | 5 | For information about NIST PQC Signature submission requirements, see the [call for proposals](https://csrc.nist.gov/projects/pqc-dig-sig/standardization/call-for-proposals) and [submission file documentation](https://csrc.nist.gov/Projects/pqc-dig-sig/standardization/example-files). 6 | 7 | # Root level directory structure of this repository: 8 | 9 | * [ref-c](ref-c): Written in the style of a "portable ANSI C reference implementation" for NIST, and supports NIST API and KAT generation. This code has options for 32-bit CRT NTT arithmetic (default: off) and LFSR vs ASCON masking random (default: lfsr), used for various discussions. 10 | * [ref-py](ref-py): Python implementation, also with NIST KAT testbench. 11 | * [doc](doc): Documentation, including [doc/raccoon.pdf](doc/raccoon.pdf), the current specification. 12 | 13 | Currently we are not delivering an AVX2, Cortex M4, or FPGA code to NIST; those aspects will be just discussed in the delivered document. 14 | 15 | 16 | # Generating KATs 17 | 18 | * The C implementation generates the KATs with `./genkats.sh`. 19 | * With the C implementation can also obtain benchmarks with `./bench.sh`. The standard `./xtest` test binary generated by `make` is also useful. 20 | * The Python implementation takes a some minutes with `python3 test_genkat.py` since each KAT file contains a set of 100 test vectors (can be modified). 21 | 22 | Running `sha256sum *.rsp` in the C implementation currently gives the following hashes for 100-vector response files generated by both implementations (albeit with Python one can may want to opt for 10 test vectors). See the directory [ref-data](ref-data) `rsp` hashes for 10 vectors, preliminary benchmarks, and additional data. 23 | ``` 24 | Raccoon-128-1 039383b9d9b29c5a9cda63cb93666771c7c09791afaadc941341e0df670229e0 PQCsignKAT_14800.rsp 25 | Raccoon-128-2 71586c2fd1ae47f17cb5c44c2b5351ab48531344041a76357ffc695098d2506c PQCsignKAT_14816.rsp 26 | Raccoon-128-4 ae6e775feaf9d26eac5d10bec3c742fb7ab8f6716ee96a2ce3cf2c3aa23b8ef0 PQCsignKAT_14848.rsp 27 | Raccoon-128-8 ffbd4df642d15da96624e2b8489b5303a97a7f6a5d60416c72108880746394ea PQCsignKAT_14912.rsp 28 | Raccoon-128-16 579fbaafde26049c4f4993b28568abfb657da76e5cd0c7a83239e37d4cc43325 PQCsignKAT_15040.rsp 29 | Raccoon-128-32 dff454bf03e9c027d70d4443bb394cae3c5af23ed81179889a62bf98a8a916d8 PQCsignKAT_15296.rsp 30 | Raccoon-192-1 bb577467a15ff20d6ac88c3eb7ba3fd6b3a3e7bf8e5bc627890bb027bba8bda5 PQCsignKAT_18840.rsp 31 | Raccoon-192-2 1543992c77e4a3ee08cd93daf1044e2d7816efbb6c572f167e500ee5b6e68d02 PQCsignKAT_18864.rsp 32 | Raccoon-192-4 82f2b834889bacdbcbb48d51f99c15639a235a764714ba858b415fdf546c9dbc PQCsignKAT_18912.rsp 33 | Raccoon-192-8 b21ecba12cafa88a8337a813e9dac131a50f043f860241f7cd36f8b502233971 PQCsignKAT_19008.rsp 34 | Raccoon-192-16 57e3c6d014c7283806f4cd3d9c83737c6d381202a1649042c499c5c354f7606b PQCsignKAT_19200.rsp 35 | Raccoon-192-32 49a552559d6a68175996de373232e0863496834c16b4d2772781f0e01469b621 PQCsignKAT_19584.rsp 36 | Raccoon-256-1 031d4976f4c09b90ecec5c535b5ab3bcb020b9cb4f95e17dfdcedb10de1425fc PQCsignKAT_26016.rsp 37 | Raccoon-256-2 8936afaf3fd6cf5b43716e006977e1c14a2624913bfd23adb850aa141ef2ae91 PQCsignKAT_26048.rsp 38 | Raccoon-256-4 2e3ae8a29435ce8621a98390874fa2193756c87741f02934018650163c57e369 PQCsignKAT_26112.rsp 39 | Raccoon-256-8 893bf614327740610c29781db7973bbfa7069010039bfa9b2ba02a9a675a78ab PQCsignKAT_26240.rsp 40 | Raccoon-256-16 663ce05beb35184b0012e638ed8c918f945b379a9bd35a97e37141798c320acf PQCsignKAT_26496.rsp 41 | Raccoon-256-32 594169ee1ddc6238fbbfae0178d0ed8fab9eb0205066fe382f6ff788c775bd58 PQCsignKAT_27008.rsp 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /ref-py/test_genkat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | test_genkat.py 5 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 6 | 7 | === Generate NIST KAT files compatible with the C reference implementaiton. 8 | """ 9 | 10 | import sys,fnmatch 11 | from nist_kat_drbg import NIST_KAT_DRBG 12 | from racc_api import * 13 | 14 | # This is intended to match the .rsp output from NIST PQCgenKAT_sign.c 15 | 16 | def nist_kat_rsp(iut, katnum=100): 17 | """Create a test vector string matching official NIST KATs.""" 18 | 19 | def _fmt_int(fh, label, n): 20 | fh.write(f"{label} = {n}\n") 21 | 22 | def _fmt_hex(fh, label, data): 23 | fh.write(f"{label} = {data.hex().upper()}\n") 24 | 25 | # kat files are named based on secret key length in the nist suite 26 | fn = f"PQCsignKAT_{iut.sk_sz}.rsp" 27 | with open(fn, "w") as fh: 28 | 29 | # KAT response file (no need for the request file here) 30 | fh.write(f"# {iut.name}\n\n") 31 | 32 | entropy_input = bytes([i for i in range(48)]) 33 | drbg = NIST_KAT_DRBG(entropy_input) 34 | 35 | for count in range(katnum): 36 | 37 | print(f"{iut.name}: {fn} writing {count+1}/{katnum}.") 38 | 39 | _fmt_int(fh, "count", count) 40 | seed = drbg.random_bytes(48) 41 | _fmt_hex(fh, "seed", seed) 42 | mlen = 33 * (count + 1) 43 | _fmt_int(fh, "mlen", mlen) 44 | msg = drbg.random_bytes(mlen) 45 | _fmt_hex(fh, "msg", msg) 46 | 47 | # force deterministic 48 | iut.set_random(NIST_KAT_DRBG(seed).random_bytes) 49 | 50 | pk, sk = iut.byte_keygen() 51 | _fmt_hex(fh, "pk", pk) 52 | _fmt_hex(fh, "sk", sk) 53 | 54 | sm = iut.byte_sign(msg, sk) 55 | _fmt_int(fh, "smlen", len(sm)) 56 | _fmt_hex(fh, "sm", sm) 57 | fh.write('\n') 58 | assert iut.byte_open(sm, pk) == (True, msg) 59 | 60 | def checksums(iut): 61 | """Print quick version-control checksums.""" 62 | 63 | def _chkdata(label, data): 64 | print(f'{label}: ' + 65 | SHAKE256.new(bytes(data)).read(16).hex() + 66 | f' ({len(data)})') 67 | 68 | def _hexdump(data): 69 | s = '' 70 | for i in range(len(data)): 71 | if i % 16 == 0: 72 | print(s) 73 | s = f'{i:08x}' 74 | if i % 8 == 0: 75 | s += ' ' 76 | s += f' {data[i]:02x}' 77 | print(s) 78 | 79 | iut.set_random(NIST_KAT_DRBG(bytes([i for i in range(48)])).random_bytes) 80 | 81 | pk, sk = iut.byte_keygen() 82 | _chkdata(iut.name + ".pk", pk) 83 | _chkdata(iut.name + ".sk", sk) 84 | 85 | msg = b'abc' 86 | sm = iut.byte_sign(msg, sk) 87 | _chkdata(iut.name + ".sm", sm) 88 | assert iut.byte_open(sm, sk) == (True,msg) 89 | 90 | if __name__ == '__main__': 91 | if len(sys.argv) <= 1: 92 | 93 | # no arguments -- just generate all NIST KAT files 94 | for iut in raccoon_all: 95 | nist_kat_rsp(iut) 96 | 97 | else: 98 | # quick checksums 99 | for name in sys.argv[1:]: 100 | match = False 101 | for iut in raccoon_all: 102 | if fnmatch.fnmatch(iut.name, name): 103 | match = True 104 | checksums(iut) 105 | if not match: 106 | print('Not found:', name) 107 | print('Here are the IUT options:') 108 | for iut in raccoon_all: 109 | print(iut.name) 110 | exit(0) 111 | -------------------------------------------------------------------------------- /ref-py/test_ntt.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_ntt.py 3 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 4 | 5 | === Code for re-creating the NTT magic constants. Unit tests for NTT. 6 | """ 7 | 8 | from random import randrange 9 | from polyr import * 10 | 11 | if (__name__ == "__main__"): 12 | 13 | def _modexp(x, e, n): 14 | """(TESTING) Modular exponentiation: Compute x**e (mod n).""" 15 | y = 1 16 | while e > 0: 17 | if e & 1 == 1: 18 | y = (y * x) % n 19 | x = (x * x) % n 20 | e >>= 1 21 | return y 22 | 23 | def _bitrev(x, l): 24 | """(TESTING) Return x with bits 0,1,..(l-1) in reverse order.""" 25 | y = 0 26 | for i in range(l): 27 | y |= ((x >> i) & 1) << (l - i - 1) 28 | return y 29 | 30 | # g=15 is the smallest generator of both prime fields of composite q. 31 | # Reduce to subgroup of order 2*n to obtain "h" in gp-pari; 32 | # g = Mod(15, q) 33 | # h = g^(znorder(g)/(2*n)) 34 | 35 | def _calc_w(): 36 | """(TESTING) Re-generate the NTT "tweak" table.""" 37 | q = RACC_Q 38 | lgn = 9 # log2(n) 39 | n = 2**lgn # length of the transform 40 | h = 358453792785495 # Generates a subgroup of order 2*n 41 | w = [] 42 | for i in range(n): 43 | j = _bitrev(i, lgn) 44 | x = (_modexp(h, j, q)) % q 45 | w.append(x) 46 | return w 47 | 48 | # prettyprint the table 49 | def _print_w(): 50 | w = _calc_w() 51 | for i in range(0, RACC_N, 4): 52 | print(f'\t{w[i]:15}, {w[i+1]:15}, {w[i+2]:15}, {w[i+3]:15},') 53 | 54 | def _rand_poly(n=RACC_N, q=RACC_Q): 55 | """(TESTING) Random polynomial.""" 56 | return [ randrange(q) for _ in range(n) ] 57 | 58 | def _conv_slow(f, g, n=RACC_N,q=RACC_Q): 59 | """(TESTING) Slow negacyclic convolution h = f*g (mod x^n+1).""" 60 | h = [0] * n 61 | for i in range(n): 62 | for j in range(n): 63 | x = (f[i] * g[j]) % q 64 | k = i + j 65 | if k >= n: 66 | k -= n 67 | x = -x # x^n == -1 (mod x^n + 1) 68 | h[k] = (h[k] + x) % q 69 | 70 | return h 71 | 72 | def _conv_fast(f, g, n=RACC_N, q=RACC_Q): 73 | """(TESTING) Fast NTT negacyclic convolution h = f*g (mod x^n+1).""" 74 | ft = ntt(f.copy()) 75 | gt = ntt(g.copy()) 76 | ht = [ ( ft[i] * gt[i] ) % q for i in range(n) ] 77 | return intt(ht) 78 | 79 | """ 80 | q=549824583172097 81 | h=Mod(358453792785495,q) 82 | rev(x)=sum(i=0,8,2^(8-i)*(floor(2^-i * x) % 2)) 83 | """ 84 | 85 | def _slow_ntt(f, n=RACC_N, q=RACC_Q, h=358453792785495): 86 | """(TESTING) Compute NTT via very slow polynomial evaluation.""" 87 | ft = [] 88 | fails = 0 89 | for i in range(n): 90 | # yes, not a modexp! 91 | x = h**(2*_bitrev(i,9)+1) % q 92 | # horner's: y = f(x) 93 | y = 0 94 | for j in reversed(range(n)): 95 | y = (y * x + f[j]) % q 96 | ft += [y] 97 | return ft 98 | 99 | # --------------- 100 | 101 | # check the zeta table 102 | print("_calc_w():", _calc_w() == RACC_W) 103 | 104 | # test convolutions 105 | for _ in range(5): 106 | f = _rand_poly() 107 | g = _rand_poly() 108 | print("_conv_fast():", _conv_slow(f, g) == _conv_fast(f, g)) 109 | ft1 = ntt(f.copy()) 110 | ft2 = _slow_ntt(f.copy()) 111 | print("_slow_ntt():", ft1 == ft2) 112 | 113 | -------------------------------------------------------------------------------- /ref-c/polyr.h: -------------------------------------------------------------------------------- 1 | // polyr.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Polynomial arithmetic related to the ring Zq[x]/(x^n+1). 5 | 6 | #ifndef _POLYR_H_ 7 | #define _POLYR_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | 16 | // Zeroize a polynomial: r = 0. 17 | void polyr_zero(int64_t *r); 18 | 19 | // Copy a polynomial: r = a. 20 | void polyr_copy(int64_t *r, const int64_t *a); 21 | 22 | // Add polynomials: r = a + b. 23 | void polyr_add(int64_t *r, const int64_t *a, const int64_t *b); 24 | 25 | // Subtract polynomials: r = a - b. 26 | void polyr_sub(int64_t *r, const int64_t *a, const int64_t *b); 27 | 28 | // Add polynomials mod q: r = a + b (mod q). 29 | void polyr_addq(int64_t *r, const int64_t *a, const int64_t *b); 30 | void polyr_ntt_addq(int64_t *r, const int64_t *a, const int64_t *b); 31 | 32 | // Subtract polynomials mod q: r = a - b (mod q). 33 | void polyr_subq(int64_t *r, const int64_t *a, const int64_t *b); 34 | void polyr_ntt_subq(int64_t *r, const int64_t *a, const int64_t *b); 35 | 36 | // Add polynomials: r = a + b, conditionally subtract m on overflow 37 | void polyr_addm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m); 38 | 39 | // Subtract polynomials, conditionally add m on underflow. 40 | void polyr_subm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m); 41 | 42 | // Negate a polynomial mod m: r = -a, add m on underflow. 43 | void polyr_negm(int64_t *r, int64_t *a, int64_t m); 44 | 45 | // Left shift: r = a << sh, conditionally subtract m on overflow. 46 | void polyr_shlm(int64_t *r, const int64_t *a, size_t sh, int64_t m); 47 | 48 | // Right shift: r = a >> sh, conditionally subtract m on overflow. 49 | void polyr_shrm(int64_t *r, const int64_t *a, size_t sh, int64_t m); 50 | 51 | // Rounding: r = (a + h) >> sh, conditionally subtract m on overflow. 52 | void polyr_round(int64_t *r, const int64_t *a, size_t sh, int64_t h, int64_t m); 53 | 54 | // Move from range 0 <= x < m to centered range -m/2 <= x < m/2. 55 | void polyr_center(int64_t *r, const int64_t *a, int64_t m); 56 | 57 | // Move from range -m <= x < m to non-negative range 0 <= x < m. 58 | void polyr_nonneg(int64_t *r, const int64_t *a, int64_t m); 59 | 60 | // Scalar multiplication: r = a * c, Montgomery reduction. 61 | #ifdef POLYR_Q32 62 | void polyr_ntt_smul(int64_t *r, const int64_t *a, int32_t c1, int32_t c2); 63 | #else 64 | void polyr_ntt_smul(int64_t *r, const int64_t *a, int64_t c); 65 | #endif 66 | 67 | // Coefficient multiply: r = a * b, Montgomery reduction. 68 | void polyr_ntt_cmul(int64_t *r, const int64_t *a, const int64_t *b); 69 | 70 | // Coefficient multiply and add: r = a * b + c, Montgomery reduction. 71 | void polyr_ntt_mula(int64_t *r, const int64_t *a, const int64_t *b, 72 | const int64_t *c); 73 | 74 | // Forward NTT (negacyclic -- evaluate polynomial at factors of x^n+1). 75 | void polyr_fntt(int64_t *v); 76 | 77 | // Reverse NTT (negacyclic -- x^n+1), normalize by 1/(n*r). 78 | void polyr_intt(int64_t *v); 79 | 80 | #ifdef POLYR_Q32 81 | // 2x32 CRT: Split into two-prime representation (in-place). 82 | void polyr2_split(int64_t *v); 83 | 84 | // 2x32 CRT: Join two-prime into 64-bit integer representation (in-place). 85 | // Use scale factors (s1, s2). Normalizes to 0 <= x < q. 86 | void polyr2_join(int64_t *v, int32_t s1, int32_t s2); 87 | 88 | // 2x32 CRT: Add polynomials: r = a + b. 89 | void polyr2_add(int64_t *r, const int64_t *a, const int64_t *b); 90 | 91 | // 2x32 CRT: Subtract polynomials: r = a - b. 92 | void polyr2_sub(int64_t *r, const int64_t *a, const int64_t *b); 93 | 94 | // POLYR_Q32 95 | #endif 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | // _POLYR_H_ 102 | #endif 103 | -------------------------------------------------------------------------------- /ref-c/template/polyr.h: -------------------------------------------------------------------------------- 1 | // polyr.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Polynomial arithmetic related to the ring Zq[x]/(x^n+1). 5 | 6 | #ifndef _POLYR_H_ 7 | #define _POLYR_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | 16 | // Zeroize a polynomial: r = 0. 17 | void polyr_zero(int64_t *r); 18 | 19 | // Copy a polynomial: r = a. 20 | void polyr_copy(int64_t *r, const int64_t *a); 21 | 22 | // Add polynomials: r = a + b. 23 | void polyr_add(int64_t *r, const int64_t *a, const int64_t *b); 24 | 25 | // Subtract polynomials: r = a - b. 26 | void polyr_sub(int64_t *r, const int64_t *a, const int64_t *b); 27 | 28 | // Add polynomials mod q: r = a + b (mod q). 29 | void polyr_addq(int64_t *r, const int64_t *a, const int64_t *b); 30 | void polyr_ntt_addq(int64_t *r, const int64_t *a, const int64_t *b); 31 | 32 | // Subtract polynomials mod q: r = a - b (mod q). 33 | void polyr_subq(int64_t *r, const int64_t *a, const int64_t *b); 34 | void polyr_ntt_subq(int64_t *r, const int64_t *a, const int64_t *b); 35 | 36 | // Add polynomials: r = a + b, conditionally subtract m on overflow 37 | void polyr_addm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m); 38 | 39 | // Subtract polynomials, conditionally add m on underflow. 40 | void polyr_subm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m); 41 | 42 | // Negate a polynomial mod m: r = -a, add m on underflow. 43 | void polyr_negm(int64_t *r, int64_t *a, int64_t m); 44 | 45 | // Left shift: r = a << sh, conditionally subtract m on overflow. 46 | void polyr_shlm(int64_t *r, const int64_t *a, size_t sh, int64_t m); 47 | 48 | // Right shift: r = a >> sh, conditionally subtract m on overflow. 49 | void polyr_shrm(int64_t *r, const int64_t *a, size_t sh, int64_t m); 50 | 51 | // Rounding: r = (a + h) >> sh, conditionally subtract m on overflow. 52 | void polyr_round(int64_t *r, const int64_t *a, size_t sh, int64_t h, int64_t m); 53 | 54 | // Move from range 0 <= x < m to centered range -m/2 <= x < m/2. 55 | void polyr_center(int64_t *r, const int64_t *a, int64_t m); 56 | 57 | // Move from range -m <= x < m to non-negative range 0 <= x < m. 58 | void polyr_nonneg(int64_t *r, const int64_t *a, int64_t m); 59 | 60 | // Scalar multiplication: r = a * c, Montgomery reduction. 61 | #ifdef POLYR_Q32 62 | void polyr_ntt_smul(int64_t *r, const int64_t *a, int32_t c1, int32_t c2); 63 | #else 64 | void polyr_ntt_smul(int64_t *r, const int64_t *a, int64_t c); 65 | #endif 66 | 67 | // Coefficient multiply: r = a * b, Montgomery reduction. 68 | void polyr_ntt_cmul(int64_t *r, const int64_t *a, const int64_t *b); 69 | 70 | // Coefficient multiply and add: r = a * b + c, Montgomery reduction. 71 | void polyr_ntt_mula(int64_t *r, const int64_t *a, const int64_t *b, 72 | const int64_t *c); 73 | 74 | // Forward NTT (negacyclic -- evaluate polynomial at factors of x^n+1). 75 | void polyr_fntt(int64_t *v); 76 | 77 | // Reverse NTT (negacyclic -- x^n+1), normalize by 1/(n*r). 78 | void polyr_intt(int64_t *v); 79 | 80 | #ifdef POLYR_Q32 81 | // 2x32 CRT: Split into two-prime representation (in-place). 82 | void polyr2_split(int64_t *v); 83 | 84 | // 2x32 CRT: Join two-prime into 64-bit integer representation (in-place). 85 | // Use scale factors (s1, s2). Normalizes to 0 <= x < q. 86 | void polyr2_join(int64_t *v, int32_t s1, int32_t s2); 87 | 88 | // 2x32 CRT: Add polynomials: r = a + b. 89 | void polyr2_add(int64_t *r, const int64_t *a, const int64_t *b); 90 | 91 | // 2x32 CRT: Subtract polynomials: r = a - b. 92 | void polyr2_sub(int64_t *r, const int64_t *a, const int64_t *b); 93 | 94 | // POLYR_Q32 95 | #endif 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | // _POLYR_H_ 102 | #endif 103 | -------------------------------------------------------------------------------- /ref-py/test_histo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | test_histo.py 5 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 6 | 7 | === Create "histograms" and average / std. deviation pairs for signature size. 8 | """ 9 | 10 | import sys,math 11 | from nist_kat_drbg import NIST_KAT_DRBG 12 | from racc_api import * 13 | from polyr import RACC_Q, RACC_N 14 | 15 | # actual length 16 | 17 | def sig_len(iut, sig): 18 | """Count bits in an actual signature.""" 19 | (c_hash, h, z) = sig 20 | b = [] # bit string 21 | for hi in h: # h bit strings 22 | b += iut._bits_enc_h(hi) 23 | for zi in z: # z bit strings 24 | b += iut._bits_enc_z(zi) 25 | return len(c_hash) + (len(b) / 8) 26 | 27 | def stats(iut): 28 | """Print quick version-control checksums.""" 29 | 30 | def _chkdata(label, data): 31 | print(f'{label}: ' + 32 | SHAKE256.new(bytes(data)).read(16).hex() + 33 | f' ({len(data)})') 34 | 35 | #iut.set_random(NIST_KAT_DRBG(bytes([i for i in range(48)])).random_bytes) 36 | 37 | # statistics 38 | h_c = [0] * 100 39 | h_n = 0 40 | z_c = [0] * 100 41 | z_n = 0 42 | 43 | 44 | len_s = 0 45 | len_r = 0 46 | len_n = 0 47 | 48 | for j in range(100): 49 | 50 | if j % 5 == 0: 51 | pk, sk = iut.byte_keygen() 52 | 53 | sm = iut.byte_sign(bytes([j]), sk) 54 | sig = iut.decode_sig(sm) 55 | (ch, h, z) = sig 56 | 57 | # histograms (absolute values) 58 | for hi in h: 59 | h_n += len(hi) 60 | for x in hi: 61 | x = min(abs(x), 99) 62 | h_c[x] += 1 63 | for zi in z: 64 | z_n += len(zi) 65 | for x in zi: 66 | x %= RACC_Q 67 | if x > RACC_Q // 2: 68 | x = RACC_Q - x 69 | x >>= 40 70 | x = min(x, 99) 71 | z_c[x] += 1 72 | 73 | len_x = sig_len(iut, sig) 74 | len_s += len_x 75 | len_r += len_x**2 76 | len_n += 1 77 | x_avg = len_s / len_n 78 | x_sig = (len_r / len_n - x_avg**2)**0.5 79 | 80 | print(f'{iut.name}: {j} x_avg= {x_avg:9.3f} x_sig= {x_sig:9.6f} x= {len_x}') 81 | 82 | h_avg = 0.0 83 | h_var = 0.0 84 | z_avg = 0.0 85 | z_var = 0.0 86 | for i in range(99): 87 | if h_c[i] == 0 and z_c[i] == 0: 88 | continue 89 | 90 | if i == 0: 91 | h_l = 1 92 | else: 93 | h_l = i + 2 94 | z_l = 42 + i 95 | 96 | h_f = h_c[i] / h_n 97 | h_avg += h_f * h_l 98 | h_var += h_f * (h_l**2) 99 | 100 | z_f = z_c[i] / z_n 101 | z_avg += z_f * z_l 102 | z_var += z_f * (z_l**2) 103 | 104 | print(f'#{i} h: {h_f:8.6f} {h_l:2d} z: {z_f:8.6f} {z_l:2d}') 105 | 106 | h_var = (h_var - h_avg**2) 107 | z_var = (z_var - z_avg**2) 108 | 109 | print(f'h_avg= {h_avg:9.6f} h_var= {h_var:9.6f}') 110 | print(f'z_avg= {z_avg:9.6f} z_var= {z_var:9.6f}') 111 | 112 | l_avg = iut.ch_sz + iut.n * (iut.k * h_avg + iut.ell * z_avg) / 8 113 | l_sig = (iut.n * (iut.k * h_var + iut.ell * z_var))**0.5 / 8 114 | print(f'{iut.name}: {j} l_avg= {l_avg:9.3f} l_sig= {l_sig:9.6f}') 115 | 116 | 117 | # Gaussian cumulative density function [-inf,+inf] -> [0,1] 118 | def cdf(x): 119 | return 1 - math.erfc(x/math.sqrt(2))/2 120 | 121 | if __name__ == '__main__': 122 | 123 | for iut in raccoon_all: 124 | if len(sys.argv) <= 1: 125 | print(iut.name) 126 | stats(iut) # check them all 127 | else: 128 | for x in sys.argv[1:]: 129 | if iut.name.lower() == x.lower(): 130 | print(iut.name) 131 | stats(iut) 132 | break 133 | 134 | -------------------------------------------------------------------------------- /ref-c/polyr.c: -------------------------------------------------------------------------------- 1 | // polyr.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Polynomial arithmetic related to the ring Zq[x]/(x^n+1). 5 | 6 | #include 7 | #include 8 | 9 | #include "polyr.h" 10 | #include "mont64.h" 11 | 12 | // === Polynomial API 13 | 14 | // Zeroize a polynomial: r = 0. 15 | 16 | void polyr_zero(int64_t *r) 17 | { 18 | size_t i; 19 | 20 | for (i = 0; i < RACC_N; i++) { 21 | r[i] = 0; 22 | } 23 | } 24 | 25 | // Copy a polynomial: r = a. 26 | 27 | void polyr_copy(int64_t *r, const int64_t *a) 28 | { 29 | size_t i; 30 | 31 | for (i = 0; i < RACC_N; i++) { 32 | r[i] = a[i]; 33 | } 34 | } 35 | 36 | // Add polynomials: r = a + b. 37 | 38 | void polyr_add(int64_t *r, const int64_t *a, const int64_t *b) 39 | { 40 | size_t i; 41 | 42 | for (i = 0; i < RACC_N; i++) { 43 | r[i] = mont64_add(a[i], b[i]); 44 | } 45 | } 46 | 47 | // Subtract polynomials: r = a - b. 48 | 49 | void polyr_sub(int64_t *r, const int64_t *a, const int64_t *b) 50 | { 51 | size_t i; 52 | 53 | for (i = 0; i < RACC_N; i++) { 54 | r[i] = mont64_sub(a[i], b[i]); 55 | } 56 | } 57 | 58 | // Add polynomials mod q: r = a + b (mod q). 59 | 60 | void polyr_addq(int64_t *r, const int64_t *a, const int64_t *b) 61 | { 62 | size_t i; 63 | 64 | for (i = 0; i < RACC_N; i++) { 65 | r[i] = mont64_csub(a[i] + b[i], RACC_Q); 66 | } 67 | } 68 | #ifndef POLYR_Q32 69 | void polyr_ntt_addq(int64_t *r, const int64_t *a, const int64_t *b) 70 | { 71 | polyr_addq(r, a, b); 72 | } 73 | #endif 74 | 75 | // Subtract polynomials mod q: r = a - b (mod q). 76 | 77 | void polyr_subq(int64_t *r, const int64_t *a, const int64_t *b) 78 | { 79 | size_t i; 80 | 81 | for (i = 0; i < RACC_N; i++) { 82 | r[i] = mont64_cadd(a[i] - b[i], RACC_Q); 83 | } 84 | } 85 | 86 | #ifndef POLYR_Q32 87 | void polyr_ntt_subq(int64_t *r, const int64_t *a, const int64_t *b) 88 | { 89 | polyr_subq(r, a, b); 90 | } 91 | #endif 92 | 93 | // Add polynomials: r = a + b, conditionally subtract m on overflow 94 | 95 | void polyr_addm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m) 96 | { 97 | size_t i; 98 | 99 | for (i = 0; i < RACC_N; i++) { 100 | r[i] = mont64_csub(a[i] + b[i], m); 101 | } 102 | } 103 | 104 | // Subtract polynomials: r = a - b, conditionally add m on underflow. 105 | 106 | void polyr_subm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m) 107 | { 108 | size_t i; 109 | 110 | for (i = 0; i < RACC_N; i++) { 111 | r[i] = mont64_cadd(a[i] - b[i], m); 112 | } 113 | } 114 | 115 | // Negate a polynomial mod m: r = -a, add m on underflow. 116 | 117 | void polyr_negm(int64_t *r, int64_t *a, int64_t m) 118 | { 119 | size_t i; 120 | 121 | for (i = 0; i < RACC_N; i++) { 122 | r[i] = mont64_cadd(-a[i], m); 123 | } 124 | } 125 | 126 | // Left shift: r = a << sh, conditionally subtract m on overflow. 127 | 128 | void polyr_shlm(int64_t *r, const int64_t *a, size_t sh, int64_t m) 129 | { 130 | size_t i; 131 | 132 | for (i = 0; i < RACC_N; i++) { 133 | r[i] = mont64_csub(a[i] << sh, m); 134 | } 135 | } 136 | 137 | // Right shift: r = a >> sh, conditionally subtract m on overflow. 138 | 139 | void polyr_shrm(int64_t *r, const int64_t *a, size_t sh, int64_t m) 140 | { 141 | size_t i; 142 | 143 | for (i = 0; i < RACC_N; i++) { 144 | r[i] = mont64_csub(a[i] >> sh, m); 145 | } 146 | } 147 | 148 | // Rounding: r = (a + h) >> sh, conditionally subtract m on overflow. 149 | 150 | void polyr_round(int64_t *r, const int64_t *a, size_t sh, int64_t h, int64_t m) 151 | { 152 | size_t i; 153 | 154 | for (i = 0; i < RACC_N; i++) { 155 | r[i] = mont64_csub((a[i] + h) >> sh, m); 156 | } 157 | } 158 | 159 | // Move from range 0 <= x < m to centered range -m/2 <= x < m/2. 160 | 161 | void polyr_center(int64_t *r, const int64_t *a, int64_t m) 162 | { 163 | size_t i; 164 | int64_t x, c; 165 | 166 | c = m >> 1; 167 | for (i = 0; i < RACC_N; i++) { 168 | x = mont64_add(a[i], c); 169 | x = mont64_csub(x, m); 170 | r[i] = mont64_sub(x, c); 171 | } 172 | } 173 | 174 | // Move from range -m <= x < m to non-negative range 0 <= x < m. 175 | 176 | void polyr_nonneg(int64_t *r, const int64_t *a, int64_t m) 177 | { 178 | size_t i; 179 | 180 | for (i = 0; i < RACC_N; i++) { 181 | r[i] = mont64_cadd(a[i], m); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /ref-c/template/polyr.c: -------------------------------------------------------------------------------- 1 | // polyr.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Polynomial arithmetic related to the ring Zq[x]/(x^n+1). 5 | 6 | #include 7 | #include 8 | 9 | #include "polyr.h" 10 | #include "mont64.h" 11 | 12 | // === Polynomial API 13 | 14 | // Zeroize a polynomial: r = 0. 15 | 16 | void polyr_zero(int64_t *r) 17 | { 18 | size_t i; 19 | 20 | for (i = 0; i < RACC_N; i++) { 21 | r[i] = 0; 22 | } 23 | } 24 | 25 | // Copy a polynomial: r = a. 26 | 27 | void polyr_copy(int64_t *r, const int64_t *a) 28 | { 29 | size_t i; 30 | 31 | for (i = 0; i < RACC_N; i++) { 32 | r[i] = a[i]; 33 | } 34 | } 35 | 36 | // Add polynomials: r = a + b. 37 | 38 | void polyr_add(int64_t *r, const int64_t *a, const int64_t *b) 39 | { 40 | size_t i; 41 | 42 | for (i = 0; i < RACC_N; i++) { 43 | r[i] = mont64_add(a[i], b[i]); 44 | } 45 | } 46 | 47 | // Subtract polynomials: r = a - b. 48 | 49 | void polyr_sub(int64_t *r, const int64_t *a, const int64_t *b) 50 | { 51 | size_t i; 52 | 53 | for (i = 0; i < RACC_N; i++) { 54 | r[i] = mont64_sub(a[i], b[i]); 55 | } 56 | } 57 | 58 | // Add polynomials mod q: r = a + b (mod q). 59 | 60 | void polyr_addq(int64_t *r, const int64_t *a, const int64_t *b) 61 | { 62 | size_t i; 63 | 64 | for (i = 0; i < RACC_N; i++) { 65 | r[i] = mont64_csub(a[i] + b[i], RACC_Q); 66 | } 67 | } 68 | #ifndef POLYR_Q32 69 | void polyr_ntt_addq(int64_t *r, const int64_t *a, const int64_t *b) 70 | { 71 | polyr_addq(r, a, b); 72 | } 73 | #endif 74 | 75 | // Subtract polynomials mod q: r = a - b (mod q). 76 | 77 | void polyr_subq(int64_t *r, const int64_t *a, const int64_t *b) 78 | { 79 | size_t i; 80 | 81 | for (i = 0; i < RACC_N; i++) { 82 | r[i] = mont64_cadd(a[i] - b[i], RACC_Q); 83 | } 84 | } 85 | 86 | #ifndef POLYR_Q32 87 | void polyr_ntt_subq(int64_t *r, const int64_t *a, const int64_t *b) 88 | { 89 | polyr_subq(r, a, b); 90 | } 91 | #endif 92 | 93 | // Add polynomials: r = a + b, conditionally subtract m on overflow 94 | 95 | void polyr_addm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m) 96 | { 97 | size_t i; 98 | 99 | for (i = 0; i < RACC_N; i++) { 100 | r[i] = mont64_csub(a[i] + b[i], m); 101 | } 102 | } 103 | 104 | // Subtract polynomials: r = a - b, conditionally add m on underflow. 105 | 106 | void polyr_subm(int64_t *r, const int64_t *a, const int64_t *b, int64_t m) 107 | { 108 | size_t i; 109 | 110 | for (i = 0; i < RACC_N; i++) { 111 | r[i] = mont64_cadd(a[i] - b[i], m); 112 | } 113 | } 114 | 115 | // Negate a polynomial mod m: r = -a, add m on underflow. 116 | 117 | void polyr_negm(int64_t *r, int64_t *a, int64_t m) 118 | { 119 | size_t i; 120 | 121 | for (i = 0; i < RACC_N; i++) { 122 | r[i] = mont64_cadd(-a[i], m); 123 | } 124 | } 125 | 126 | // Left shift: r = a << sh, conditionally subtract m on overflow. 127 | 128 | void polyr_shlm(int64_t *r, const int64_t *a, size_t sh, int64_t m) 129 | { 130 | size_t i; 131 | 132 | for (i = 0; i < RACC_N; i++) { 133 | r[i] = mont64_csub(a[i] << sh, m); 134 | } 135 | } 136 | 137 | // Right shift: r = a >> sh, conditionally subtract m on overflow. 138 | 139 | void polyr_shrm(int64_t *r, const int64_t *a, size_t sh, int64_t m) 140 | { 141 | size_t i; 142 | 143 | for (i = 0; i < RACC_N; i++) { 144 | r[i] = mont64_csub(a[i] >> sh, m); 145 | } 146 | } 147 | 148 | // Rounding: r = (a + h) >> sh, conditionally subtract m on overflow. 149 | 150 | void polyr_round(int64_t *r, const int64_t *a, size_t sh, int64_t h, int64_t m) 151 | { 152 | size_t i; 153 | 154 | for (i = 0; i < RACC_N; i++) { 155 | r[i] = mont64_csub((a[i] + h) >> sh, m); 156 | } 157 | } 158 | 159 | // Move from range 0 <= x < m to centered range -m/2 <= x < m/2. 160 | 161 | void polyr_center(int64_t *r, const int64_t *a, int64_t m) 162 | { 163 | size_t i; 164 | int64_t x, c; 165 | 166 | c = m >> 1; 167 | for (i = 0; i < RACC_N; i++) { 168 | x = mont64_add(a[i], c); 169 | x = mont64_csub(x, m); 170 | r[i] = mont64_sub(x, c); 171 | } 172 | } 173 | 174 | // Move from range -m <= x < m to non-negative range 0 <= x < m. 175 | 176 | void polyr_nonneg(int64_t *r, const int64_t *a, int64_t m) 177 | { 178 | size_t i; 179 | 180 | for (i = 0; i < RACC_N; i++) { 181 | r[i] = mont64_cadd(a[i], m); 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /ref-c/xof_sample.c: -------------------------------------------------------------------------------- 1 | // xof_sample.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Samplers and XOF functions 5 | 6 | #include 7 | 8 | #include "racc_param.h" 9 | #include "xof_sample.h" 10 | #include "sha3_t.h" 11 | #include "mont64.h" 12 | 13 | // Compute mu = H(tr, m) where tr = H(pk), "m" is message of "m_sz" bytes. 14 | 15 | void xof_chal_mu( uint8_t mu[RACC_MU_SZ], const uint8_t tr[RACC_TR_SZ], 16 | const uint8_t *m, size_t m_sz) 17 | { 18 | sha3_t kec; 19 | 20 | sha3_init(&kec, SHAKE256_RATE); 21 | sha3_absorb(&kec, tr, RACC_TR_SZ); 22 | sha3_absorb(&kec, m, m_sz); 23 | sha3_pad(&kec, SHAKE_PAD); 24 | sha3_squeeze(&kec, mu, RACC_MU_SZ); 25 | } 26 | 27 | // Expand "seed" of "seed_sz" bytes to a uniform polynomial (mod q). 28 | // The input seed is assumed to alredy contain domain separation. 29 | 30 | void xof_sample_q(int64_t r[RACC_N], const uint8_t *seed, size_t seed_sz) 31 | { 32 | size_t i; 33 | int64_t x; 34 | uint8_t buf[8]; 35 | sha3_t kec; 36 | 37 | // sample from squeezed output 38 | sha3_init(&kec, SHAKE256_RATE); 39 | sha3_absorb(&kec, seed, seed_sz); 40 | sha3_pad(&kec, SHAKE_PAD); 41 | 42 | memset(buf, 0, sizeof(buf)); 43 | for (i = 0; i < RACC_N; i++) { 44 | do { 45 | sha3_squeeze(&kec, buf, (RACC_Q_BITS + 7) / 8); 46 | x = get64u_le(buf) & RACC_QMSK; 47 | } while (x >= RACC_Q); 48 | r[i] = x; 49 | } 50 | } 51 | 52 | // Sample "bits"-wide signed coefficients from "seed[seed_sz]". 53 | // The input seed is assumed to alredy contain domain separation. 54 | 55 | void xof_sample_u(int64_t r[RACC_N], int bits, 56 | const uint8_t *seed, size_t seed_sz) 57 | { 58 | size_t i, blen; 59 | int64_t x, mask, mid; 60 | uint8_t buf[8]; 61 | sha3_t kec; 62 | 63 | blen = (bits + 7) / 8; 64 | mask = (1ll << bits) - 1; 65 | mid = 1ll << (bits - 1); 66 | 67 | // absorb seed 68 | sha3_init(&kec, SHAKE256_RATE); 69 | sha3_absorb(&kec, seed, seed_sz); 70 | sha3_pad(&kec, SHAKE_PAD); 71 | 72 | // sample from squeezed outpu 73 | memset(buf, 0, sizeof(buf)); 74 | for (i = 0; i < RACC_N; i++) { 75 | sha3_squeeze(&kec, buf, blen); 76 | x = get64u_le(buf) & mask; 77 | x ^= mid; // two's complement sign bit: 0=pos, 1=neg 78 | r[i] = mont64_cadd(x - mid, RACC_Q); 79 | } 80 | } 81 | 82 | // Hash "w" vector with "mu" to produce challenge hash "ch". 83 | 84 | void xof_chal_hash( uint8_t ch[RACC_CH_SZ], const uint8_t mu[RACC_MU_SZ], 85 | const int64_t w[RACC_K][RACC_N]) 86 | { 87 | size_t i, j; 88 | uint8_t buf[8]; 89 | sha3_t kec; 90 | 91 | sha3_init(&kec, SHAKE256_RATE); 92 | 93 | // hash of: domain separators 'h', mu, and w in bytes 94 | buf[0] = 'h'; 95 | buf[1] = RACC_K; 96 | memset(buf + 2, 0x00, 6); 97 | sha3_absorb(&kec, buf, 8); 98 | 99 | // mu 100 | sha3_absorb(&kec, mu, RACC_MU_SZ); 101 | 102 | // w: ceil(log2(q)/8) bytes per coefficient 103 | for (i = 0; i < RACC_K; i++) { 104 | for (j = 0; j < RACC_N; j++) { 105 | #if ((RACC_LGW + 7) / 8) == 1 106 | buf[0] = w[i][j]; 107 | #else 108 | put64u_le(buf, w[i][j]); 109 | #endif 110 | sha3_absorb(&kec, buf, (RACC_LGW + 7) / 8); 111 | } 112 | } 113 | 114 | sha3_pad(&kec, SHAKE_PAD); 115 | sha3_squeeze(&kec, ch, RACC_CH_SZ); 116 | sha3_clear(&kec); 117 | } 118 | 119 | // Create a challenge polynomial "cp" from a challenge hash "ch". 120 | 121 | void xof_chal_poly( int64_t cp[RACC_N], const uint8_t ch[RACC_CH_SZ]) 122 | { 123 | sha3_t kec; 124 | uint8_t buf[8]; 125 | size_t i, j; 126 | int64_t x; 127 | 128 | sha3_init(&kec, SHAKE256_RATE); // header 129 | buf[0] = 'c'; 130 | buf[1] = RACC_W; 131 | memset(buf + 2, 0x00, 6); 132 | sha3_absorb(&kec, buf, 8); 133 | 134 | sha3_absorb(&kec, ch, RACC_CH_SZ); // add ch 135 | sha3_pad(&kec, SHAKE_PAD); 136 | 137 | for (i = 0; i < RACC_N; i++) { 138 | cp[i] = 0; 139 | } 140 | 141 | j = 0; 142 | while (j < RACC_W) { 143 | sha3_squeeze(&kec, buf, 2); 144 | i = get16u_le(buf); 145 | x = i & 1; 146 | i = (i >> 1) & (RACC_N - 1); 147 | if (cp[i] == 0) { 148 | cp[i] = 2 * x - 1; 149 | j++; 150 | } 151 | } 152 | sha3_clear(&kec); 153 | } 154 | -------------------------------------------------------------------------------- /ref-c/template/xof_sample.c: -------------------------------------------------------------------------------- 1 | // xof_sample.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Raccoon signature scheme -- Samplers and XOF functions 5 | 6 | #include 7 | 8 | #include "racc_param.h" 9 | #include "xof_sample.h" 10 | #include "sha3_t.h" 11 | #include "mont64.h" 12 | 13 | // Compute mu = H(tr, m) where tr = H(pk), "m" is message of "m_sz" bytes. 14 | 15 | void xof_chal_mu( uint8_t mu[RACC_MU_SZ], const uint8_t tr[RACC_TR_SZ], 16 | const uint8_t *m, size_t m_sz) 17 | { 18 | sha3_t kec; 19 | 20 | sha3_init(&kec, SHAKE256_RATE); 21 | sha3_absorb(&kec, tr, RACC_TR_SZ); 22 | sha3_absorb(&kec, m, m_sz); 23 | sha3_pad(&kec, SHAKE_PAD); 24 | sha3_squeeze(&kec, mu, RACC_MU_SZ); 25 | } 26 | 27 | // Expand "seed" of "seed_sz" bytes to a uniform polynomial (mod q). 28 | // The input seed is assumed to alredy contain domain separation. 29 | 30 | void xof_sample_q(int64_t r[RACC_N], const uint8_t *seed, size_t seed_sz) 31 | { 32 | size_t i; 33 | int64_t x; 34 | uint8_t buf[8]; 35 | sha3_t kec; 36 | 37 | // sample from squeezed output 38 | sha3_init(&kec, SHAKE256_RATE); 39 | sha3_absorb(&kec, seed, seed_sz); 40 | sha3_pad(&kec, SHAKE_PAD); 41 | 42 | memset(buf, 0, sizeof(buf)); 43 | for (i = 0; i < RACC_N; i++) { 44 | do { 45 | sha3_squeeze(&kec, buf, (RACC_Q_BITS + 7) / 8); 46 | x = get64u_le(buf) & RACC_QMSK; 47 | } while (x >= RACC_Q); 48 | r[i] = x; 49 | } 50 | } 51 | 52 | // Sample "bits"-wide signed coefficients from "seed[seed_sz]". 53 | // The input seed is assumed to alredy contain domain separation. 54 | 55 | void xof_sample_u(int64_t r[RACC_N], int bits, 56 | const uint8_t *seed, size_t seed_sz) 57 | { 58 | size_t i, blen; 59 | int64_t x, mask, mid; 60 | uint8_t buf[8]; 61 | sha3_t kec; 62 | 63 | blen = (bits + 7) / 8; 64 | mask = (1ll << bits) - 1; 65 | mid = 1ll << (bits - 1); 66 | 67 | // absorb seed 68 | sha3_init(&kec, SHAKE256_RATE); 69 | sha3_absorb(&kec, seed, seed_sz); 70 | sha3_pad(&kec, SHAKE_PAD); 71 | 72 | // sample from squeezed outpu 73 | memset(buf, 0, sizeof(buf)); 74 | for (i = 0; i < RACC_N; i++) { 75 | sha3_squeeze(&kec, buf, blen); 76 | x = get64u_le(buf) & mask; 77 | x ^= mid; // two's complement sign bit: 0=pos, 1=neg 78 | r[i] = mont64_cadd(x - mid, RACC_Q); 79 | } 80 | } 81 | 82 | // Hash "w" vector with "mu" to produce challenge hash "ch". 83 | 84 | void xof_chal_hash( uint8_t ch[RACC_CH_SZ], const uint8_t mu[RACC_MU_SZ], 85 | const int64_t w[RACC_K][RACC_N]) 86 | { 87 | size_t i, j; 88 | uint8_t buf[8]; 89 | sha3_t kec; 90 | 91 | sha3_init(&kec, SHAKE256_RATE); 92 | 93 | // hash of: domain separators 'h', mu, and w in bytes 94 | buf[0] = 'h'; 95 | buf[1] = RACC_K; 96 | memset(buf + 2, 0x00, 6); 97 | sha3_absorb(&kec, buf, 8); 98 | 99 | // mu 100 | sha3_absorb(&kec, mu, RACC_MU_SZ); 101 | 102 | // w: ceil(log2(q)/8) bytes per coefficient 103 | for (i = 0; i < RACC_K; i++) { 104 | for (j = 0; j < RACC_N; j++) { 105 | #if ((RACC_LGW + 7) / 8) == 1 106 | buf[0] = w[i][j]; 107 | #else 108 | put64u_le(buf, w[i][j]); 109 | #endif 110 | sha3_absorb(&kec, buf, (RACC_LGW + 7) / 8); 111 | } 112 | } 113 | 114 | sha3_pad(&kec, SHAKE_PAD); 115 | sha3_squeeze(&kec, ch, RACC_CH_SZ); 116 | sha3_clear(&kec); 117 | } 118 | 119 | // Create a challenge polynomial "cp" from a challenge hash "ch". 120 | 121 | void xof_chal_poly( int64_t cp[RACC_N], const uint8_t ch[RACC_CH_SZ]) 122 | { 123 | sha3_t kec; 124 | uint8_t buf[8]; 125 | size_t i, j; 126 | int64_t x; 127 | 128 | sha3_init(&kec, SHAKE256_RATE); // header 129 | buf[0] = 'c'; 130 | buf[1] = RACC_W; 131 | memset(buf + 2, 0x00, 6); 132 | sha3_absorb(&kec, buf, 8); 133 | 134 | sha3_absorb(&kec, ch, RACC_CH_SZ); // add ch 135 | sha3_pad(&kec, SHAKE_PAD); 136 | 137 | for (i = 0; i < RACC_N; i++) { 138 | cp[i] = 0; 139 | } 140 | 141 | j = 0; 142 | while (j < RACC_W) { 143 | sha3_squeeze(&kec, buf, 2); 144 | i = get16u_le(buf); 145 | x = i & 1; 146 | i = (i >> 1) & (RACC_N - 1); 147 | if (cp[i] == 0) { 148 | cp[i] = 2 * x - 1; 149 | j++; 150 | } 151 | } 152 | sha3_clear(&kec); 153 | } 154 | -------------------------------------------------------------------------------- /ref-c/mont32.h: -------------------------------------------------------------------------------- 1 | // mont32.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Portable 32-bit Montgomery arithmetic 5 | 6 | #ifndef _MONT32_H_ 7 | #define _MONT32_H_ 8 | 9 | #include "plat_local.h" 10 | #include "racc_param.h" 11 | 12 | /* 13 | n = 512 14 | q1 = 2^24-2^18+1 15 | q2 = 2^25-2^18+1 16 | q = q1*q2 17 | */ 18 | 19 | #define RACC_Q1 16515073 20 | #define RACC_Q2 33292289 21 | 22 | #if (RACC_N != 512 || RACC_Q != (RACC_Q1 * RACC_Q2)) 23 | #error "Unrecognized polynomial parameters N, Q" 24 | #endif 25 | 26 | /* 27 | r1 = 2^32 % q1 28 | rr1 = r1^2 % q1 29 | rrr1 = r1^3 % q1 30 | ri1 = lift(Mod(2^32,q1)^-1) 31 | ni1 = lift(rr1 * Mod(n,q1)^-1) 32 | qi1 = lift(Mod(-q1,2^32)^-1) 33 | */ 34 | 35 | #define MONT_R1 1048316 36 | #define MONT_RR1 3933217 37 | #define MONT_RRR1 2096954 38 | #define MONT_RI1 63504 39 | #define MONT_NI1 15458307 40 | #define MONT_QI1 16515071 41 | 42 | /* 43 | r2 = 2^32 % q2 44 | rr2 = r2^2 % q2 45 | rrr2 = r2^3 % q2 46 | ri2 = lift(Mod(2^32,q2)^-1) 47 | ni2 = lift(rr1 * Mod(n,q2)^-1) 48 | qi2 = lift(Mod(-q2, 2^32)^-1) 49 | */ 50 | 51 | #define MONT_R2 262015 52 | #define MONT_RR2 3160307 53 | #define MONT_RRR2 2026597 54 | #define MONT_RI2 258064 55 | #define MONT_NI2 31154179 56 | #define MONT_QI2 33292287 57 | 58 | /* 59 | (c4q1, c4q2) accounts for FFT^-1 (n) and 4 REDC's (2^-32). 60 | c4q1 = lift(Mod(q2*n,q1)^-1 * (2^32)^4) 61 | c4q2 = lift(Mod(q1*n,q2)^-1 * (2^32)^4) 62 | */ 63 | 64 | #define MONT_C4Q1 1048477 65 | #define MONT_C4Q2 15632846 66 | 67 | /* 68 | (d2q1, d2q2) accounts for 2 REDC's (2^-32) -- no FFT^-1 69 | d2q1 = lift(Mod(q2,q1)^-1 * (2^32)^2) 70 | d2q2 = lift(Mod(q1,q2)^-1 * (2^32)^2) 71 | */ 72 | 73 | #define MONT_D2Q1 4127728 74 | #define MONT_D2Q2 32801027 75 | 76 | // Addition and subtraction 77 | 78 | static inline int32_t mont32_add(int32_t x, int32_t y) 79 | { 80 | return x + y; 81 | } 82 | 83 | static inline int32_t mont32_sub(int32_t x, int32_t y) 84 | { 85 | return x - y; 86 | } 87 | // Conditionally add m if x is negative 88 | 89 | static inline int32_t mont32_cadd(int32_t x, int32_t m) 90 | { 91 | int32_t t, r; 92 | 93 | XASSUME(x >= -m && x < m); 94 | 95 | t = x >> 31; 96 | r = x + (t & m); 97 | 98 | XASSERT(r >= 0 && r < m); 99 | XASSERT(r == x || r == x + m); 100 | 101 | return r; 102 | } 103 | 104 | // Conditionally subtract m if x >= m 105 | 106 | static inline int32_t mont32_csub(int32_t x, int32_t m) 107 | { 108 | int32_t t, r; 109 | 110 | XASSUME(x >= 0 && x < 2 * m); 111 | XASSUME(m > 0); 112 | 113 | t = x - m; 114 | r = t + ((t >> 31) & m); 115 | 116 | XASSERT(r >= 0 && r < m); 117 | XASSERT(r == x || r == x - m); 118 | 119 | return r; 120 | } 121 | 122 | // Montgomery reduction. Returns r in [-q,q-1] so that r == (x/2^32) mod q. 123 | 124 | static inline int32_t mont32_redc1(int64_t x) 125 | { 126 | int32_t r; 127 | 128 | // prove these input bounds (55-bit for q1) 129 | XASSUME(x >= -(((int64_t)1) << 54)); 130 | XASSUME(x < (((int64_t)1) << 54)); 131 | 132 | r = x * MONT_QI1; 133 | r = (x + ((int64_t)r) * ((int64_t)RACC_Q1)) >> 32; 134 | 135 | // prove that only one coditional addition is required 136 | XASSERT(r >= -RACC_Q1 && r < RACC_Q1); 137 | 138 | #ifdef XDEBUG 139 | // this modular reduction correctness proof is too slow for SAT 140 | XASSERT(((((int64_t)x) - (((int64_t)r) << 32)) % ((int64_t)RACC_Q1)) == 0); 141 | #endif 142 | return r; 143 | } 144 | 145 | static inline int32_t mont32_redc2(int64_t x) 146 | { 147 | int32_t r; 148 | 149 | // prove these input bounds (56-bit for q2) 150 | XASSUME(x >= -(((int64_t)1) << 55)); 151 | XASSUME(x < (((int64_t)1) << 55)); 152 | 153 | r = x * MONT_QI2; 154 | r = (x + ((int64_t)r) * ((int64_t)RACC_Q2)) >> 32; 155 | 156 | // prove that only one coditional addition is required 157 | XASSERT(r >= -RACC_Q2 && r < RACC_Q2); 158 | 159 | // this modular reduction correctness proof is too slow for SAT 160 | #ifdef XDEBUG 161 | XASSERT(((((int64_t)x) - (((int64_t)r) << 32)) % ((int64_t)RACC_Q2)) == 0); 162 | #endif 163 | return r; 164 | } 165 | 166 | // Montgomery multiplication. r in [-q,q-1] so that r == (a*b)/2^32) mod q. 167 | 168 | static inline int32_t mont32_mulq1(int32_t x, int32_t y) 169 | { 170 | int32_t r; 171 | 172 | r = mont32_redc1(((int64_t)x) * ((int64_t)y)); 173 | 174 | return r; 175 | } 176 | 177 | static inline int32_t mont32_mulq2(int32_t x, int32_t y) 178 | { 179 | int32_t r; 180 | 181 | r = mont32_redc2(((int64_t)x) * ((int64_t)y)); 182 | 183 | return r; 184 | } 185 | 186 | // same with addition 187 | 188 | static inline int32_t mont32_mulqa1(int32_t x, int32_t y, int32_t z) 189 | { 190 | int32_t r; 191 | 192 | r = mont32_redc1(((int64_t)x) * ((int64_t)y) + ((int64_t)z)); 193 | 194 | return r; 195 | } 196 | 197 | static inline int32_t mont32_mulqa2(int32_t x, int32_t y, int32_t z) 198 | { 199 | int32_t r; 200 | 201 | r = mont32_redc2(((int64_t)x) * ((int64_t)y) + ((int64_t)z)); 202 | 203 | return r; 204 | } 205 | 206 | // _MONT32_H_ 207 | #endif 208 | -------------------------------------------------------------------------------- /ref-c/template/mont32.h: -------------------------------------------------------------------------------- 1 | // mont32.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Portable 32-bit Montgomery arithmetic 5 | 6 | #ifndef _MONT32_H_ 7 | #define _MONT32_H_ 8 | 9 | #include "plat_local.h" 10 | #include "racc_param.h" 11 | 12 | /* 13 | n = 512 14 | q1 = 2^24-2^18+1 15 | q2 = 2^25-2^18+1 16 | q = q1*q2 17 | */ 18 | 19 | #define RACC_Q1 16515073 20 | #define RACC_Q2 33292289 21 | 22 | #if (RACC_N != 512 || RACC_Q != (RACC_Q1 * RACC_Q2)) 23 | #error "Unrecognized polynomial parameters N, Q" 24 | #endif 25 | 26 | /* 27 | r1 = 2^32 % q1 28 | rr1 = r1^2 % q1 29 | rrr1 = r1^3 % q1 30 | ri1 = lift(Mod(2^32,q1)^-1) 31 | ni1 = lift(rr1 * Mod(n,q1)^-1) 32 | qi1 = lift(Mod(-q1,2^32)^-1) 33 | */ 34 | 35 | #define MONT_R1 1048316 36 | #define MONT_RR1 3933217 37 | #define MONT_RRR1 2096954 38 | #define MONT_RI1 63504 39 | #define MONT_NI1 15458307 40 | #define MONT_QI1 16515071 41 | 42 | /* 43 | r2 = 2^32 % q2 44 | rr2 = r2^2 % q2 45 | rrr2 = r2^3 % q2 46 | ri2 = lift(Mod(2^32,q2)^-1) 47 | ni2 = lift(rr1 * Mod(n,q2)^-1) 48 | qi2 = lift(Mod(-q2, 2^32)^-1) 49 | */ 50 | 51 | #define MONT_R2 262015 52 | #define MONT_RR2 3160307 53 | #define MONT_RRR2 2026597 54 | #define MONT_RI2 258064 55 | #define MONT_NI2 31154179 56 | #define MONT_QI2 33292287 57 | 58 | /* 59 | (c4q1, c4q2) accounts for FFT^-1 (n) and 4 REDC's (2^-32). 60 | c4q1 = lift(Mod(q2*n,q1)^-1 * (2^32)^4) 61 | c4q2 = lift(Mod(q1*n,q2)^-1 * (2^32)^4) 62 | */ 63 | 64 | #define MONT_C4Q1 1048477 65 | #define MONT_C4Q2 15632846 66 | 67 | /* 68 | (d2q1, d2q2) accounts for 2 REDC's (2^-32) -- no FFT^-1 69 | d2q1 = lift(Mod(q2,q1)^-1 * (2^32)^2) 70 | d2q2 = lift(Mod(q1,q2)^-1 * (2^32)^2) 71 | */ 72 | 73 | #define MONT_D2Q1 4127728 74 | #define MONT_D2Q2 32801027 75 | 76 | // Addition and subtraction 77 | 78 | static inline int32_t mont32_add(int32_t x, int32_t y) 79 | { 80 | return x + y; 81 | } 82 | 83 | static inline int32_t mont32_sub(int32_t x, int32_t y) 84 | { 85 | return x - y; 86 | } 87 | // Conditionally add m if x is negative 88 | 89 | static inline int32_t mont32_cadd(int32_t x, int32_t m) 90 | { 91 | int32_t t, r; 92 | 93 | XASSUME(x >= -m && x < m); 94 | 95 | t = x >> 31; 96 | r = x + (t & m); 97 | 98 | XASSERT(r >= 0 && r < m); 99 | XASSERT(r == x || r == x + m); 100 | 101 | return r; 102 | } 103 | 104 | // Conditionally subtract m if x >= m 105 | 106 | static inline int32_t mont32_csub(int32_t x, int32_t m) 107 | { 108 | int32_t t, r; 109 | 110 | XASSUME(x >= 0 && x < 2 * m); 111 | XASSUME(m > 0); 112 | 113 | t = x - m; 114 | r = t + ((t >> 31) & m); 115 | 116 | XASSERT(r >= 0 && r < m); 117 | XASSERT(r == x || r == x - m); 118 | 119 | return r; 120 | } 121 | 122 | // Montgomery reduction. Returns r in [-q,q-1] so that r == (x/2^32) mod q. 123 | 124 | static inline int32_t mont32_redc1(int64_t x) 125 | { 126 | int32_t r; 127 | 128 | // prove these input bounds (55-bit for q1) 129 | XASSUME(x >= -(((int64_t)1) << 54)); 130 | XASSUME(x < (((int64_t)1) << 54)); 131 | 132 | r = x * MONT_QI1; 133 | r = (x + ((int64_t)r) * ((int64_t)RACC_Q1)) >> 32; 134 | 135 | // prove that only one coditional addition is required 136 | XASSERT(r >= -RACC_Q1 && r < RACC_Q1); 137 | 138 | #ifdef XDEBUG 139 | // this modular reduction correctness proof is too slow for SAT 140 | XASSERT(((((int64_t)x) - (((int64_t)r) << 32)) % ((int64_t)RACC_Q1)) == 0); 141 | #endif 142 | return r; 143 | } 144 | 145 | static inline int32_t mont32_redc2(int64_t x) 146 | { 147 | int32_t r; 148 | 149 | // prove these input bounds (56-bit for q2) 150 | XASSUME(x >= -(((int64_t)1) << 55)); 151 | XASSUME(x < (((int64_t)1) << 55)); 152 | 153 | r = x * MONT_QI2; 154 | r = (x + ((int64_t)r) * ((int64_t)RACC_Q2)) >> 32; 155 | 156 | // prove that only one coditional addition is required 157 | XASSERT(r >= -RACC_Q2 && r < RACC_Q2); 158 | 159 | // this modular reduction correctness proof is too slow for SAT 160 | #ifdef XDEBUG 161 | XASSERT(((((int64_t)x) - (((int64_t)r) << 32)) % ((int64_t)RACC_Q2)) == 0); 162 | #endif 163 | return r; 164 | } 165 | 166 | // Montgomery multiplication. r in [-q,q-1] so that r == (a*b)/2^32) mod q. 167 | 168 | static inline int32_t mont32_mulq1(int32_t x, int32_t y) 169 | { 170 | int32_t r; 171 | 172 | r = mont32_redc1(((int64_t)x) * ((int64_t)y)); 173 | 174 | return r; 175 | } 176 | 177 | static inline int32_t mont32_mulq2(int32_t x, int32_t y) 178 | { 179 | int32_t r; 180 | 181 | r = mont32_redc2(((int64_t)x) * ((int64_t)y)); 182 | 183 | return r; 184 | } 185 | 186 | // same with addition 187 | 188 | static inline int32_t mont32_mulqa1(int32_t x, int32_t y, int32_t z) 189 | { 190 | int32_t r; 191 | 192 | r = mont32_redc1(((int64_t)x) * ((int64_t)y) + ((int64_t)z)); 193 | 194 | return r; 195 | } 196 | 197 | static inline int32_t mont32_mulqa2(int32_t x, int32_t y, int32_t z) 198 | { 199 | int32_t r; 200 | 201 | r = mont32_redc2(((int64_t)x) * ((int64_t)y) + ((int64_t)z)); 202 | 203 | return r; 204 | } 205 | 206 | // _MONT32_H_ 207 | #endif 208 | -------------------------------------------------------------------------------- /ref-c/test_main.c: -------------------------------------------------------------------------------- 1 | // test_main.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === private tests and benchmarks 5 | 6 | #ifndef NIST_KAT 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "plat_local.h" 14 | #include "racc_core.h" 15 | #include "nist_random.h" 16 | #include "mask_random.h" 17 | #include "racc_serial.h" 18 | #include "mont64.h" 19 | #include "polyr.h" 20 | #include "sha3_t.h" 21 | 22 | #include "api.h" 23 | 24 | // [debug] (shake) checksums of data 25 | 26 | void dbg_chk(const char *label, uint8_t *data, size_t data_sz) 27 | { 28 | size_t i; 29 | uint8_t md[16] = {0}; 30 | 31 | shake256(md, sizeof(md), data, data_sz); 32 | printf("%s: ", label); 33 | for (i = 0; i < sizeof(md); i++) { 34 | printf("%02x", md[i]); 35 | } 36 | printf(" (%zu)\n", data_sz); 37 | } 38 | 39 | // [debug] dump a hex string 40 | 41 | void dbg_hex(const char *label, const uint8_t *data, size_t data_sz) 42 | { 43 | size_t i; 44 | printf("%s= ", label); 45 | for (i = 0; i < data_sz; i++) { 46 | printf("%02x", data[i]); 47 | } 48 | printf("\n"); 49 | } 50 | 51 | // standard library process time 52 | 53 | static inline double cpu_clock_secs() 54 | { 55 | return ((double)clock()) / ((double)CLOCKS_PER_SEC); 56 | } 57 | 58 | // maximum message size 59 | #define MAX_MSG 256 60 | 61 | int main() 62 | { 63 | size_t i; 64 | 65 | // message to be signed (used in checksums) 66 | uint8_t msg[MAX_MSG] = "abc"; 67 | size_t mlen = 3; 68 | 69 | // timing 70 | size_t iter = 100; 71 | double ts, to; 72 | uint64_t cc; 73 | 74 | int fail = 0; 75 | 76 | // buffers for serialized 77 | uint8_t pk[CRYPTO_PUBLICKEYBYTES] = {0}; 78 | uint8_t sk[CRYPTO_SECRETKEYBYTES] = {0}; 79 | uint8_t sm[CRYPTO_BYTES + MAX_MSG] = {0}; 80 | uint8_t m2[MAX_MSG] = {0}; 81 | unsigned long long smlen = 0; 82 | unsigned long long mlen2 = 0; 83 | 84 | // masking random 85 | fail += mask_random_selftest(); 86 | if (fail > 0) { 87 | printf("mask_random_selftest() fail= %d\n", fail); 88 | } 89 | 90 | // initialize nist pseudo random 91 | uint8_t seed[48]; 92 | for (i = 0; i < 48; i++) { 93 | seed[i] = i; 94 | } 95 | nist_randombytes_init(seed, NULL, 256); 96 | 97 | // (start) 98 | printf("CRYPTO_ALGNAME\t= %s\n", CRYPTO_ALGNAME); 99 | printf("CRYPTO_PUBLICKEYBYTES\t= %d\n", CRYPTO_PUBLICKEYBYTES); 100 | printf("CRYPTO_SECRETKEYBYTES\t= %d\n", CRYPTO_SECRETKEYBYTES); 101 | printf("CRYPTO_BYTES\t\t= %d\n", CRYPTO_BYTES); 102 | 103 | // === keygen === 104 | crypto_sign_keypair(pk, sk); 105 | dbg_chk(CRYPTO_ALGNAME ".pk", pk, CRYPTO_PUBLICKEYBYTES); 106 | dbg_chk(CRYPTO_ALGNAME ".sk", sk, CRYPTO_SECRETKEYBYTES); 107 | 108 | // === sign === 109 | smlen = 0; 110 | crypto_sign(sm, &smlen, msg, mlen, sk); 111 | dbg_chk(CRYPTO_ALGNAME ".sm", sm, (size_t) smlen); 112 | 113 | // === verify === 114 | mlen2 = 0; 115 | memset(m2, 0, sizeof(m2)); 116 | fail += crypto_sign_open(m2, &mlen2, sm, smlen, pk) == 0 ? 0 : 1; 117 | fail += (mlen == mlen2 && memcmp(msg, m2, mlen) == 0) ? 0 : 1; 118 | 119 | sm[123]++; // corrupt it -- expect fail 120 | fail += crypto_sign_open(m2, &mlen2, sm, smlen, pk) != 0 ? 0 : 1; 121 | 122 | printf("verify fail= %d\n", fail); 123 | 124 | #ifdef BENCH_TIMEOUT 125 | to = BENCH_TIMEOUT; 126 | #else 127 | to = 1.0; // timeout threshold (seconds) 128 | #endif 129 | 130 | printf("=== Bench ===\n"); 131 | 132 | iter = 16; 133 | do { 134 | iter *= 2; 135 | ts = cpu_clock_secs(); 136 | cc = plat_get_cycle(); 137 | 138 | for (i = 0; i < iter; i++) { 139 | crypto_sign_keypair(pk, sk); 140 | } 141 | cc = plat_get_cycle() - cc; 142 | ts = cpu_clock_secs() - ts; 143 | } while (ts < to); 144 | printf("%s\tKeyGen() %5zu:\t%8.3f ms\t%8.3f Mcyc\n", CRYPTO_ALGNAME, iter, 145 | 1000.0 * ts / ((double)iter), 1E-6 * ((double) (cc / iter))); 146 | 147 | iter = 16; 148 | do { 149 | iter *= 2; 150 | crypto_sign_keypair(pk, sk); 151 | ts = cpu_clock_secs(); 152 | cc = plat_get_cycle(); 153 | 154 | for (i = 0; i < iter; i++) { 155 | crypto_sign(sm, &smlen, msg, mlen, sk); 156 | } 157 | cc = plat_get_cycle() - cc; 158 | ts = cpu_clock_secs() - ts; 159 | } while (ts < to); 160 | printf("%s\t Sign() %5zu:\t%8.3f ms\t%8.3f Mcyc\n", CRYPTO_ALGNAME, iter, 161 | 1000.0 * ts / ((double)iter), 1E-6 * ((double) (cc / iter))); 162 | 163 | iter = 16; 164 | do { 165 | iter *= 2; 166 | crypto_sign_keypair(pk, sk); 167 | crypto_sign(sm, &smlen, msg, mlen, sk); 168 | ts = cpu_clock_secs(); 169 | cc = plat_get_cycle(); 170 | 171 | // repeats the same verify.. 172 | for (i = 0; i < iter; i++) { 173 | fail += crypto_sign_open(m2, &mlen2, sm, smlen, pk) == 0 ? 0 : 1; 174 | } 175 | cc = plat_get_cycle() - cc; 176 | ts = cpu_clock_secs() - ts; 177 | } while (ts < to); 178 | printf("%s\tVerify() %5zu:\t%8.3f ms\t%8.3f Mcyc\n", CRYPTO_ALGNAME, iter, 179 | 1000.0 * ts / ((double)iter), 1E-6 * ((double) (cc / iter))); 180 | 181 | return 0; 182 | } 183 | 184 | // NIST_KAT 185 | #endif 186 | -------------------------------------------------------------------------------- /ref-py/test_genlist.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | """ 4 | test_genlist.py 5 | Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 6 | 7 | === Extract and prettyprint parameters for C code and LaTeX. 8 | 9 | Usage: 10 | python3 test_genlist.py c > ../ref-c/param_list.h 11 | python3 test_genlist.py tex > param_table.tex 12 | mv param_table.tex ../../../documents/submissions/nist-pqc-2023/sections/ 13 | """ 14 | 15 | import sys 16 | from racc_api import raccoon_all 17 | 18 | if (__name__ == "__main__"): 19 | 20 | # python3 test_genlist.py c > ../ref-c/param_list.h 21 | if sys.argv[-1] == 'c': 22 | 23 | print('//\tgenerated by', sys.argv[0]) 24 | 25 | for iut in raccoon_all: 26 | print() 27 | macro = iut.name.upper().replace('-','_') 28 | print(f'#if defined({macro})') 29 | print(f'#define RACC_(s) {macro}_##s') 30 | print(f'#define RACC_NAME "{iut.name}"') 31 | print(f'#define RACC_KAPPA {iut.bitsec}') 32 | print(f'#define RACC_Q {iut.q}') 33 | print(f'#define RACC_NUT {iut.nut}') 34 | print(f'#define RACC_NUW {iut.nuw}') 35 | print(f'#define RACC_REP {iut.rep}') 36 | print(f'#define RACC_UT {iut.ut}') 37 | print(f'#define RACC_UW {iut.uw}') 38 | print(f'#define RACC_N {iut.n}') 39 | print(f'#define RACC_K {iut.k}') 40 | print(f'#define RACC_ELL {iut.ell}') 41 | print(f'#define RACC_W {iut.w}') 42 | print(f'#define RACC_D {iut.d}') 43 | print(f'#define RACC_B22 {iut.B22}') 44 | print(f'#define RACC_BOO {iut.Boo}') 45 | print(f'#define RACC_PK_SZ {iut.pk_sz}') 46 | print(f'#define RACC_SK_SZ {iut.sk_sz}') 47 | print(f'#define RACC_SIG_SZ {iut.sig_sz}') 48 | print(f'#endif') 49 | 50 | # python3 test_genlist.py tex > param_table.tex 51 | # mv param_table.tex ../../../documents/submissions/nist-pqc-2023/sections/ 52 | 53 | elif sys.argv[-1] == 'tex': 54 | 55 | print('%\tgenerated by', sys.argv[0]) 56 | 57 | def _find_param(sec,d): 58 | for iut in raccoon_all: 59 | if iut.bitsec == sec and iut.d == d: 60 | return iut 61 | 62 | def _rowstr(l,rep_dash=True): 63 | s = f'& {l[0]}'.ljust(18) 64 | for i in range(1, len(l)): 65 | if rep_dash and l[i] == l[i-1]: 66 | s += '& ='.ljust(8) 67 | else: 68 | s += f'& {l[i]}'.ljust(8) 69 | return s 70 | 71 | # kappa is shared with all parameters 72 | 73 | for sec in [128,192,256]: 74 | 75 | print() 76 | col = [] 77 | for d in [1,2,4,8,16,32]: 78 | col += [_find_param(sec, d)] 79 | 80 | print('\\begin{table}[H]') 81 | print('\\begin{center}') 82 | print('\\caption{Parameters for \\raccoon-' + str(sec) 83 | + ', NIST Post-Quantum security strength category ' 84 | + str((sec-128)//32+1) + '.}') 85 | print('\\label{tab:param-' + str(sec)+'}') 86 | print('\n\\medskip') 87 | print('\\begin{tabular}{c' + ('|c' * len(col)) + '}') 88 | 89 | l = [ f'\\raccoon-{col[0].bitsec}' ] 90 | l += [ f'{t.bitsec}-{t.d}' for t in col[1:] ] 91 | print('Parameter'.ljust(16) + _rowstr(l) + '\\\\') 92 | 93 | print('\\hline') 94 | 95 | l = [ t.bitsec for t in col ] 96 | print('$\\bitsec$'.ljust(16) + _rowstr(l) + '\\\\') 97 | 98 | l = [ '$2^{'+str(t.nsigqs)+'}$' for t in col ] 99 | print('$\\nsigqueries$'.ljust(16) + _rowstr(l) + '\\\\') 100 | 101 | l = [ t.q for t in col ] 102 | print('$q$'.ljust(16) + _rowstr(l) + '\\\\') 103 | 104 | l = [ t.n for t in col ] 105 | print('$n$'.ljust(16) + _rowstr(l) + '\\\\') 106 | 107 | l = [ t.k for t in col ] 108 | print('$k$'.ljust(16) + _rowstr(l) + '\\\\') 109 | 110 | l = [ t.ell for t in col ] 111 | print('$\\ell$'.ljust(16) + _rowstr(l) + '\\\\') 112 | 113 | l = [ t.nut for t in col ] 114 | print('$\\shiftvk$'.ljust(16) + _rowstr(l) + '\\\\') 115 | 116 | l = [ t.nuw for t in col ] 117 | print('$\\shiftcom$'.ljust(16) + _rowstr(l) + '\\\\') 118 | 119 | l = [ t.w for t in col ] 120 | print('$\\chalweight$'.ljust(16) + _rowstr(l) + '\\\\') 121 | 122 | l = [ t.B22 for t in col ] 123 | print('$2^{-64}B_2^2$'.ljust(16) + _rowstr(l) + '\\\\') 124 | 125 | l = [ t.Boo for t in col ] 126 | print('$\Boo$'.ljust(16) + _rowstr(l) + '\\\\') 127 | 128 | l = [ t.sig_sz for t in col ] 129 | print('$|\\sig|$ (bytes)'.ljust(16) + _rowstr(l) + '\\\\') 130 | 131 | l = [ t.pk_sz for t in col ] 132 | print('$|\\vk|$ (bytes)'.ljust(16) + _rowstr(l) + '\\\\') 133 | 134 | print('\\hline') 135 | 136 | l = [ t.d for t in col ] 137 | print('$d$'.ljust(16) + _rowstr(l) + '\\\\') 138 | 139 | l = [ t.rep for t in col ] 140 | print('$\\rep$'.ljust(16) + _rowstr(l) + '\\\\') 141 | 142 | l = [ t.ut for t in col ] 143 | print('$\\ut$'.ljust(16) + _rowstr(l, False) + '\\\\') 144 | 145 | l = [ t.uw for t in col ] 146 | print('$\\uw$'.ljust(16) + _rowstr(l, False) + '\\\\') 147 | 148 | l = [ t.sk_sz for t in col ] 149 | print('$|\\sk|$ (bytes)'.ljust(16) + _rowstr(l) + '\\\\') 150 | 151 | 152 | print('\\end{tabular}') 153 | print('\\end{center}') 154 | print('\\end{table}') 155 | 156 | else: 157 | print("use 'c' or 'tex' parameter to create parameter tables.") 158 | 159 | -------------------------------------------------------------------------------- /ref-c/util/keccakf1600.c: -------------------------------------------------------------------------------- 1 | // keccakf1600.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === FIPS 202 Keccak permutation for a "generic 64-bit" target. 5 | // Derived from free / public-domain dedicated sources. 6 | 7 | #include "keccakf1600.h" 8 | #include "plat_local.h" 9 | 10 | // clear the state 11 | 12 | void keccak_clear(uint64_t vs[25]) 13 | { 14 | size_t i; 15 | 16 | for (i = 0; i < 25; i++) { 17 | vs[i] = 0; 18 | } 19 | } 20 | 21 | // extract "rate" bytes from state 22 | 23 | void keccak_extract(uint64_t* vs, uint8_t* data, size_t rate) 24 | { 25 | size_t i; 26 | 27 | for (i = 0; i < rate / 8; i++) { 28 | put64u_le(data + 8 * i, vs[i]); 29 | } 30 | } 31 | 32 | // absorb "rate" bytes via xor into the state 33 | 34 | void keccak_xorbytes(uint64_t* vs, const uint8_t* data, size_t rate) 35 | { 36 | size_t i; 37 | 38 | for (i = 0; i < rate / 8; i++) { 39 | vs[i] ^= get64u_le(data + 8 * i); 40 | } 41 | } 42 | 43 | // FIPS 202 Keccak f1600 permutation, 24 rounds -- Keccak-p[1600,24](S) 44 | 45 | void keccak_f1600(uint64_t vs[25]) 46 | { 47 | // round constants 48 | const uint64_t rc[24] = { 49 | 0x0000000000000001LL, 0x0000000000008082LL, 0x800000000000808ALL, 50 | 0x8000000080008000LL, 0x000000000000808BLL, 0x0000000080000001LL, 51 | 0x8000000080008081LL, 0x8000000000008009LL, 0x000000000000008ALL, 52 | 0x0000000000000088LL, 0x0000000080008009LL, 0x000000008000000ALL, 53 | 0x000000008000808BLL, 0x800000000000008BLL, 0x8000000000008089LL, 54 | 0x8000000000008003LL, 0x8000000000008002LL, 0x8000000000000080LL, 55 | 0x000000000000800ALL, 0x800000008000000ALL, 0x8000000080008081LL, 56 | 0x8000000000008080LL, 0x0000000080000001LL, 0x8000000080008008LL}; 57 | 58 | int i; 59 | uint64_t t, u, v, w; 60 | uint64_t sa, sb, sc, sd, se, sf, sg, sh, si, sj, sk, sl, sm, sn, so, sp, sq, 61 | sr, ss, st, su, sv, sw, sx, sy; 62 | 63 | // keccak_count++; 64 | 65 | // load state, little endian, aligned 66 | 67 | sa = vs[0]; 68 | sb = vs[1]; 69 | sc = vs[2]; 70 | sd = vs[3]; 71 | se = vs[4]; 72 | sf = vs[5]; 73 | sg = vs[6]; 74 | sh = vs[7]; 75 | si = vs[8]; 76 | sj = vs[9]; 77 | sk = vs[10]; 78 | sl = vs[11]; 79 | sm = vs[12]; 80 | sn = vs[13]; 81 | so = vs[14]; 82 | sp = vs[15]; 83 | sq = vs[16]; 84 | sr = vs[17]; 85 | ss = vs[18]; 86 | st = vs[19]; 87 | su = vs[20]; 88 | sv = vs[21]; 89 | sw = vs[22]; 90 | sx = vs[23]; 91 | sy = vs[24]; 92 | 93 | // iteration 94 | 95 | for (i = 0; i < 24; i++) { 96 | // Theta 97 | 98 | u = sa ^ sf ^ sk ^ sp ^ su; 99 | v = sb ^ sg ^ sl ^ sq ^ sv; 100 | w = se ^ sj ^ so ^ st ^ sy; 101 | t = w ^ ror64(v, 63); 102 | sa = sa ^ t; 103 | sf = sf ^ t; 104 | sk = sk ^ t; 105 | sp = sp ^ t; 106 | su = su ^ t; 107 | 108 | t = sd ^ si ^ sn ^ ss ^ sx; 109 | v = v ^ ror64(t, 63); 110 | t = t ^ ror64(u, 63); 111 | se = se ^ t; 112 | sj = sj ^ t; 113 | so = so ^ t; 114 | st = st ^ t; 115 | sy = sy ^ t; 116 | 117 | t = sc ^ sh ^ sm ^ sr ^ sw; 118 | u = u ^ ror64(t, 63); 119 | t = t ^ ror64(w, 63); 120 | sc = sc ^ v; 121 | sh = sh ^ v; 122 | sm = sm ^ v; 123 | sr = sr ^ v; 124 | sw = sw ^ v; 125 | 126 | sb = sb ^ u; 127 | sg = sg ^ u; 128 | sl = sl ^ u; 129 | sq = sq ^ u; 130 | sv = sv ^ u; 131 | 132 | sd = sd ^ t; 133 | si = si ^ t; 134 | sn = sn ^ t; 135 | ss = ss ^ t; 136 | sx = sx ^ t; 137 | 138 | // Rho Pi 139 | 140 | t = ror64(sb, 63); 141 | sb = ror64(sg, 20); 142 | sg = ror64(sj, 44); 143 | sj = ror64(sw, 3); 144 | sw = ror64(so, 25); 145 | so = ror64(su, 46); 146 | su = ror64(sc, 2); 147 | sc = ror64(sm, 21); 148 | sm = ror64(sn, 39); 149 | sn = ror64(st, 56); 150 | st = ror64(sx, 8); 151 | sx = ror64(sp, 23); 152 | sp = ror64(se, 37); 153 | se = ror64(sy, 50); 154 | sy = ror64(sv, 62); 155 | sv = ror64(si, 9); 156 | si = ror64(sq, 19); 157 | sq = ror64(sf, 28); 158 | sf = ror64(sd, 36); 159 | sd = ror64(ss, 43); 160 | ss = ror64(sr, 49); 161 | sr = ror64(sl, 54); 162 | sl = ror64(sh, 58); 163 | sh = ror64(sk, 61); 164 | sk = t; 165 | 166 | // Chi 167 | 168 | t = andn64(se, sd); 169 | se = se ^ andn64(sb, sa); 170 | sb = sb ^ andn64(sd, sc); 171 | sd = sd ^ andn64(sa, se); 172 | sa = sa ^ andn64(sc, sb); 173 | sc = sc ^ t; 174 | 175 | t = andn64(sj, si); 176 | sj = sj ^ andn64(sg, sf); 177 | sg = sg ^ andn64(si, sh); 178 | si = si ^ andn64(sf, sj); 179 | sf = sf ^ andn64(sh, sg); 180 | sh = sh ^ t; 181 | 182 | t = andn64(so, sn); 183 | so = so ^ andn64(sl, sk); 184 | sl = sl ^ andn64(sn, sm); 185 | sn = sn ^ andn64(sk, so); 186 | sk = sk ^ andn64(sm, sl); 187 | sm = sm ^ t; 188 | 189 | t = andn64(st, ss); 190 | st = st ^ andn64(sq, sp); 191 | sq = sq ^ andn64(ss, sr); 192 | ss = ss ^ andn64(sp, st); 193 | sp = sp ^ andn64(sr, sq); 194 | sr = sr ^ t; 195 | 196 | t = andn64(sy, sx); 197 | sy = sy ^ andn64(sv, su); 198 | sv = sv ^ andn64(sx, sw); 199 | sx = sx ^ andn64(su, sy); 200 | su = su ^ andn64(sw, sv); 201 | sw = sw ^ t; 202 | 203 | // Iota 204 | 205 | sa = sa ^ rc[i]; 206 | } 207 | 208 | // store state 209 | 210 | vs[0] = sa; 211 | vs[1] = sb; 212 | vs[2] = sc; 213 | vs[3] = sd; 214 | vs[4] = se; 215 | vs[5] = sf; 216 | vs[6] = sg; 217 | vs[7] = sh; 218 | vs[8] = si; 219 | vs[9] = sj; 220 | vs[10] = sk; 221 | vs[11] = sl; 222 | vs[12] = sm; 223 | vs[13] = sn; 224 | vs[14] = so; 225 | vs[15] = sp; 226 | vs[16] = sq; 227 | vs[17] = sr; 228 | vs[18] = ss; 229 | vs[19] = st; 230 | vs[20] = su; 231 | vs[21] = sv; 232 | vs[22] = sw; 233 | vs[23] = sx; 234 | vs[24] = sy; 235 | } 236 | -------------------------------------------------------------------------------- /ref-c/template/keccakf1600.c: -------------------------------------------------------------------------------- 1 | // keccakf1600.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === FIPS 202 Keccak permutation for a "generic 64-bit" target. 5 | // Derived from free / public-domain dedicated sources. 6 | 7 | #include "keccakf1600.h" 8 | #include "plat_local.h" 9 | 10 | // clear the state 11 | 12 | void keccak_clear(uint64_t vs[25]) 13 | { 14 | size_t i; 15 | 16 | for (i = 0; i < 25; i++) { 17 | vs[i] = 0; 18 | } 19 | } 20 | 21 | // extract "rate" bytes from state 22 | 23 | void keccak_extract(uint64_t* vs, uint8_t* data, size_t rate) 24 | { 25 | size_t i; 26 | 27 | for (i = 0; i < rate / 8; i++) { 28 | put64u_le(data + 8 * i, vs[i]); 29 | } 30 | } 31 | 32 | // absorb "rate" bytes via xor into the state 33 | 34 | void keccak_xorbytes(uint64_t* vs, const uint8_t* data, size_t rate) 35 | { 36 | size_t i; 37 | 38 | for (i = 0; i < rate / 8; i++) { 39 | vs[i] ^= get64u_le(data + 8 * i); 40 | } 41 | } 42 | 43 | // FIPS 202 Keccak f1600 permutation, 24 rounds -- Keccak-p[1600,24](S) 44 | 45 | void keccak_f1600(uint64_t vs[25]) 46 | { 47 | // round constants 48 | const uint64_t rc[24] = { 49 | 0x0000000000000001LL, 0x0000000000008082LL, 0x800000000000808ALL, 50 | 0x8000000080008000LL, 0x000000000000808BLL, 0x0000000080000001LL, 51 | 0x8000000080008081LL, 0x8000000000008009LL, 0x000000000000008ALL, 52 | 0x0000000000000088LL, 0x0000000080008009LL, 0x000000008000000ALL, 53 | 0x000000008000808BLL, 0x800000000000008BLL, 0x8000000000008089LL, 54 | 0x8000000000008003LL, 0x8000000000008002LL, 0x8000000000000080LL, 55 | 0x000000000000800ALL, 0x800000008000000ALL, 0x8000000080008081LL, 56 | 0x8000000000008080LL, 0x0000000080000001LL, 0x8000000080008008LL}; 57 | 58 | int i; 59 | uint64_t t, u, v, w; 60 | uint64_t sa, sb, sc, sd, se, sf, sg, sh, si, sj, sk, sl, sm, sn, so, sp, sq, 61 | sr, ss, st, su, sv, sw, sx, sy; 62 | 63 | // keccak_count++; 64 | 65 | // load state, little endian, aligned 66 | 67 | sa = vs[0]; 68 | sb = vs[1]; 69 | sc = vs[2]; 70 | sd = vs[3]; 71 | se = vs[4]; 72 | sf = vs[5]; 73 | sg = vs[6]; 74 | sh = vs[7]; 75 | si = vs[8]; 76 | sj = vs[9]; 77 | sk = vs[10]; 78 | sl = vs[11]; 79 | sm = vs[12]; 80 | sn = vs[13]; 81 | so = vs[14]; 82 | sp = vs[15]; 83 | sq = vs[16]; 84 | sr = vs[17]; 85 | ss = vs[18]; 86 | st = vs[19]; 87 | su = vs[20]; 88 | sv = vs[21]; 89 | sw = vs[22]; 90 | sx = vs[23]; 91 | sy = vs[24]; 92 | 93 | // iteration 94 | 95 | for (i = 0; i < 24; i++) { 96 | // Theta 97 | 98 | u = sa ^ sf ^ sk ^ sp ^ su; 99 | v = sb ^ sg ^ sl ^ sq ^ sv; 100 | w = se ^ sj ^ so ^ st ^ sy; 101 | t = w ^ ror64(v, 63); 102 | sa = sa ^ t; 103 | sf = sf ^ t; 104 | sk = sk ^ t; 105 | sp = sp ^ t; 106 | su = su ^ t; 107 | 108 | t = sd ^ si ^ sn ^ ss ^ sx; 109 | v = v ^ ror64(t, 63); 110 | t = t ^ ror64(u, 63); 111 | se = se ^ t; 112 | sj = sj ^ t; 113 | so = so ^ t; 114 | st = st ^ t; 115 | sy = sy ^ t; 116 | 117 | t = sc ^ sh ^ sm ^ sr ^ sw; 118 | u = u ^ ror64(t, 63); 119 | t = t ^ ror64(w, 63); 120 | sc = sc ^ v; 121 | sh = sh ^ v; 122 | sm = sm ^ v; 123 | sr = sr ^ v; 124 | sw = sw ^ v; 125 | 126 | sb = sb ^ u; 127 | sg = sg ^ u; 128 | sl = sl ^ u; 129 | sq = sq ^ u; 130 | sv = sv ^ u; 131 | 132 | sd = sd ^ t; 133 | si = si ^ t; 134 | sn = sn ^ t; 135 | ss = ss ^ t; 136 | sx = sx ^ t; 137 | 138 | // Rho Pi 139 | 140 | t = ror64(sb, 63); 141 | sb = ror64(sg, 20); 142 | sg = ror64(sj, 44); 143 | sj = ror64(sw, 3); 144 | sw = ror64(so, 25); 145 | so = ror64(su, 46); 146 | su = ror64(sc, 2); 147 | sc = ror64(sm, 21); 148 | sm = ror64(sn, 39); 149 | sn = ror64(st, 56); 150 | st = ror64(sx, 8); 151 | sx = ror64(sp, 23); 152 | sp = ror64(se, 37); 153 | se = ror64(sy, 50); 154 | sy = ror64(sv, 62); 155 | sv = ror64(si, 9); 156 | si = ror64(sq, 19); 157 | sq = ror64(sf, 28); 158 | sf = ror64(sd, 36); 159 | sd = ror64(ss, 43); 160 | ss = ror64(sr, 49); 161 | sr = ror64(sl, 54); 162 | sl = ror64(sh, 58); 163 | sh = ror64(sk, 61); 164 | sk = t; 165 | 166 | // Chi 167 | 168 | t = andn64(se, sd); 169 | se = se ^ andn64(sb, sa); 170 | sb = sb ^ andn64(sd, sc); 171 | sd = sd ^ andn64(sa, se); 172 | sa = sa ^ andn64(sc, sb); 173 | sc = sc ^ t; 174 | 175 | t = andn64(sj, si); 176 | sj = sj ^ andn64(sg, sf); 177 | sg = sg ^ andn64(si, sh); 178 | si = si ^ andn64(sf, sj); 179 | sf = sf ^ andn64(sh, sg); 180 | sh = sh ^ t; 181 | 182 | t = andn64(so, sn); 183 | so = so ^ andn64(sl, sk); 184 | sl = sl ^ andn64(sn, sm); 185 | sn = sn ^ andn64(sk, so); 186 | sk = sk ^ andn64(sm, sl); 187 | sm = sm ^ t; 188 | 189 | t = andn64(st, ss); 190 | st = st ^ andn64(sq, sp); 191 | sq = sq ^ andn64(ss, sr); 192 | ss = ss ^ andn64(sp, st); 193 | sp = sp ^ andn64(sr, sq); 194 | sr = sr ^ t; 195 | 196 | t = andn64(sy, sx); 197 | sy = sy ^ andn64(sv, su); 198 | sv = sv ^ andn64(sx, sw); 199 | sx = sx ^ andn64(su, sy); 200 | su = su ^ andn64(sw, sv); 201 | sw = sw ^ t; 202 | 203 | // Iota 204 | 205 | sa = sa ^ rc[i]; 206 | } 207 | 208 | // store state 209 | 210 | vs[0] = sa; 211 | vs[1] = sb; 212 | vs[2] = sc; 213 | vs[3] = sd; 214 | vs[4] = se; 215 | vs[5] = sf; 216 | vs[6] = sg; 217 | vs[7] = sh; 218 | vs[8] = si; 219 | vs[9] = sj; 220 | vs[10] = sk; 221 | vs[11] = sl; 222 | vs[12] = sm; 223 | vs[13] = sn; 224 | vs[14] = so; 225 | vs[15] = sp; 226 | vs[16] = sq; 227 | vs[17] = sr; 228 | vs[18] = ss; 229 | vs[19] = st; 230 | vs[20] = su; 231 | vs[21] = sv; 232 | vs[22] = sw; 233 | vs[23] = sx; 234 | vs[24] = sy; 235 | } 236 | -------------------------------------------------------------------------------- /doc/delivery-readme.txt: -------------------------------------------------------------------------------- 1 | RACCOON File Inventory 2 | ====================== 3 | 2023-05-31 4 | 5 | Algorithm Specification (and Supporting Documentation): 6 | 7 | Supporting_Documentation/raccoon.pdf 8 | 9 | The Cover Sheet and Intellectual Property Statements/Agreements/Disclosures 10 | are provided in directory Supporting_Documentation/Statements/ 11 | 12 | CoverSheet.pdf IP-MouhartemFabrice.pdf 13 | Implementation-SaarinenMJ.pdf IP-PrestThomas.pdf 14 | IP-delPinoRafael.pdf IP-RossiMelissa.pdf 15 | IP-EspitauThomas.pdf IP-SaarinenMJ.pdf 16 | IP-MallerMary.pdf PatentOwner-ElKaafaraniAli.pdf 17 | 18 | 19 | Implementations 20 | --------------- 21 | 22 | The Raccoon implementation comes in 18 variants for three cryptanalytic 23 | security levels and six side-channel security levels. 24 | 25 | Raccoon-128-1 Raccoon-128-2 Raccoon-128-4 26 | Raccoon-128-8 Raccoon-128-16 Raccoon-128-32 27 | Raccoon-192-1 Raccoon-192-2 Raccoon-192-4 28 | Raccoon-192-8 Raccoon-192-16 Raccoon-192-32 29 | Raccoon-256-1 Raccoon-256-2 Raccoon-256-4 30 | Raccoon-256-8 Raccoon-256-16 Raccoon-256-32 31 | 32 | The code subdirectories are organized as: 33 | 34 | Reference_Implementation/Raccoon-*-* ANSI C Reference Implementation 35 | Optimized_Implementation/Raccoon-*-* Exactly same code 36 | 37 | The contents of all of these directories are equivalent apart from 38 | `param_select.h`, which defines the variant used. 39 | 40 | Inventory: 41 | 42 | api.h NIST API Definitions 43 | build-kat.sh Build a KAT generator executable 44 | clean-kat.sh Cleanup KAT generator 45 | ct_util.c Generic constant time utilities 46 | ct_util.h " 47 | keccakf1600.c Keccak permutation for a "generic 64-bit" target 48 | keccakf1600.h " 49 | LICENSE MIT License 50 | mask_random.c Mask random generator (dummy implementations) 51 | mask_random.h " 52 | mont32.h Portable 32-bit Montgomery arithmetic 53 | mont64.h Portable 64-bit Montgomery arithmetic 54 | nist_random.h Wrapper to rng.h 55 | ntt32.c 32-bit Number Theoretic Transform 56 | ntt64.c 64-bit Number Theoretic Transform 57 | param_list.h All parameter sets 58 | param_select.h Single-line file that selects the parameter set 59 | plat_local.h Local platform helper macros 60 | polyr.c Polynomial arithmetic and ring Zq[x]/(x^n+1) 61 | polyr.h " 62 | PQCgenKAT_sign.c NIST KAT Generator main() 63 | racc_api.c Raccoon signature scheme -- NIST KAT Generator API 64 | racc_core.c Raccoon signature scheme -- Core scheme 65 | racc_core.h Raccoon signature scheme -- Core internal API 66 | racc_param.h Raccoon signature scheme -- Derived parameters 67 | racc_serial.c Raccoon signature scheme -- Serialize/deserialize 68 | racc_serial.h " 69 | README.txt This file 70 | rng.c NIST KAT Generator DRBG 71 | rng.h " 72 | sha3_t.c Common wrappers for SHA3 (FIPS 202) functionality 73 | sha3_t.h " 74 | xof_sample.c Raccoon signature scheme -- Samplers and XOF functions 75 | xof_sample.h " 76 | 77 | 78 | An additional reference python implementation is provided in 79 | 80 | Additional_Implementations/Python 81 | 82 | Inventory: 83 | 84 | Makefile Only target: make clean 85 | mask_random.py Dummy Mask Random Generator (LFSR127 MRG) 86 | nist_kat_drbg.py NIST KAT Generator DRBG 87 | polyr.py Polynomial ring arithmetic + NTT code 88 | racc_api.py Serializaton/deserialization, NIST style functions 89 | racc_core.py Raccoon signature scheme -- Core Algorithm. 90 | README.md Brief instructions 91 | requirements.txt Python requirements: pycryptodome 92 | test_genkat.py Generate NIST KAT files (.rsp files) 93 | test_genlist.py Prettyprint parameter lists for C for TeX 94 | test_histo.py Used for signature encoding design 95 | test_ntt.py Basic tests for NTT, also generate tweak tables 96 | 97 | 98 | Known Answer Test values 99 | ------------------------ 100 | 101 | The NIST KAT files (.req and .rsp files) are contained under KAT/Raccoon-*-* 102 | Here are the SHA-256 hashes of the response files: 103 | 104 | KAT/Raccoon-128-1/PQCsignKAT_14800.rsp: 105 | 039383b9d9b29c5a9cda63cb93666771c7c09791afaadc941341e0df670229e0 106 | 107 | KAT/Raccoon-128-2/PQCsignKAT_14816.rsp: 108 | 71586c2fd1ae47f17cb5c44c2b5351ab48531344041a76357ffc695098d2506c 109 | 110 | KAT/Raccoon-128-4/PQCsignKAT_14848.rsp: 111 | ae6e775feaf9d26eac5d10bec3c742fb7ab8f6716ee96a2ce3cf2c3aa23b8ef0 112 | 113 | KAT/Raccoon-128-8/PQCsignKAT_14912.rsp: 114 | ffbd4df642d15da96624e2b8489b5303a97a7f6a5d60416c72108880746394ea 115 | 116 | KAT/Raccoon-128-16/PQCsignKAT_15040.rsp: 117 | 579fbaafde26049c4f4993b28568abfb657da76e5cd0c7a83239e37d4cc43325 118 | 119 | KAT/Raccoon-128-32/PQCsignKAT_15296.rsp: 120 | dff454bf03e9c027d70d4443bb394cae3c5af23ed81179889a62bf98a8a916d8 121 | 122 | KAT/Raccoon-192-1/PQCsignKAT_18840.rsp: 123 | bb577467a15ff20d6ac88c3eb7ba3fd6b3a3e7bf8e5bc627890bb027bba8bda5 124 | 125 | KAT/Raccoon-192-2/PQCsignKAT_18864.rsp: 126 | 1543992c77e4a3ee08cd93daf1044e2d7816efbb6c572f167e500ee5b6e68d02 127 | 128 | KAT/Raccoon-192-4/PQCsignKAT_18912.rsp: 129 | 82f2b834889bacdbcbb48d51f99c15639a235a764714ba858b415fdf546c9dbc 130 | 131 | KAT/Raccoon-192-8/PQCsignKAT_19008.rsp: 132 | b21ecba12cafa88a8337a813e9dac131a50f043f860241f7cd36f8b502233971 133 | 134 | KAT/Raccoon-192-16/PQCsignKAT_19200.rsp: 135 | 57e3c6d014c7283806f4cd3d9c83737c6d381202a1649042c499c5c354f7606b 136 | 137 | KAT/Raccoon-192-32/PQCsignKAT_19584.rsp: 138 | 49a552559d6a68175996de373232e0863496834c16b4d2772781f0e01469b621 139 | 140 | KAT/Raccoon-256-1/PQCsignKAT_26016.rsp: 141 | 031d4976f4c09b90ecec5c535b5ab3bcb020b9cb4f95e17dfdcedb10de1425fc 142 | 143 | KAT/Raccoon-256-2/PQCsignKAT_26048.rsp: 144 | 8936afaf3fd6cf5b43716e006977e1c14a2624913bfd23adb850aa141ef2ae91 145 | 146 | KAT/Raccoon-256-4/PQCsignKAT_26112.rsp: 147 | 2e3ae8a29435ce8621a98390874fa2193756c87741f02934018650163c57e369 148 | 149 | KAT/Raccoon-256-8/PQCsignKAT_26240.rsp: 150 | 893bf614327740610c29781db7973bbfa7069010039bfa9b2ba02a9a675a78ab 151 | 152 | KAT/Raccoon-256-16/PQCsignKAT_26496.rsp: 153 | 663ce05beb35184b0012e638ed8c918f945b379a9bd35a97e37141798c320acf 154 | 155 | KAT/Raccoon-256-32/PQCsignKAT_27008.rsp: 156 | 594169ee1ddc6238fbbfae0178d0ed8fab9eb0205066fe382f6ff788c775bd58 157 | 158 | -------------------------------------------------------------------------------- /ref-c/inc/plat_local.h: -------------------------------------------------------------------------------- 1 | // plat_local.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Localization affecting all implementations can be inserted here. 5 | 6 | #ifndef _PLAT_LOCAL_H_ 7 | #define _PLAT_LOCAL_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #ifndef PLAT_VERS_STR 18 | #define PLAT_VERS_STR "dev version" 19 | #define PLAT_VERS_MAJ 0 20 | #define PLAT_VERS_MIN 0 21 | #endif 22 | 23 | // === platform detection logic 24 | 25 | #ifndef PLAT_XLEN 26 | 27 | #if defined(__riscv) && (__riscv_xlen == 32) 28 | #define PLAT_XLEN 32 29 | #define PLAT_ARCH_STR "PLAT_ARCH_RV32" 30 | #define PLAT_ARCH_RV32 31 | 32 | #elif defined(__riscv) 33 | #define PLAT_XLEN 64 34 | #define PLAT_ARCH_STR "PLAT_ARCH_RV64" 35 | #define PLAT_ARCH_RV64 36 | 37 | #elif defined(__arm__) 38 | #define PLAT_XLEN 32 39 | #define PLAT_ARCH_STR "PLAT_ARCH_ARM32" 40 | #define PLAT_ARCH_ARM32 41 | 42 | #elif defined(__aarch64__) 43 | #define PLAT_XLEN 64 44 | #define PLAT_ARCH_STR "PLAT_ARCH_ARM64" 45 | #define PLAT_ARCH_ARM64 46 | 47 | #elif defined(__i386__) 48 | #define PLAT_XLEN 32 49 | #define PLAT_ARCH_STR "PLAT_ARCH_IA32" 50 | #define PLAT_ARCH_IA32 51 | 52 | #elif defined(__x86_64__) 53 | #define PLAT_XLEN 64 54 | #define PLAT_ARCH_STR "PLAT_ARCH_X64" 55 | #define PLAT_ARCH_X64 56 | 57 | #elif (__WORDSIZE == 32) 58 | #define PLAT_XLEN 32 59 | #define PLAT_ARCH_STR "PLAT_ARCH_GEN32" 60 | #define PLAT_ARCH_GEN32 61 | 62 | #else 63 | // fallback for everything 64 | #define PLAT_XLEN 64 65 | #define PLAT_ARCH_STR "PLAT_ARCH_GEN64" 66 | #define PLAT_ARCH_GEN64 67 | #endif 68 | 69 | // PLAT_XLEN signals that the rest of the macros are defined too 70 | #endif 71 | 72 | // === Assume-Assert checks 73 | 74 | // No-op for production 75 | #ifndef __CPROVER__ 76 | 77 | #ifndef XDEBUG 78 | #define XASSERT(x) 79 | #define XASSUME(x) 80 | #define XTMPVAR(x) 81 | 82 | // Runtime checks in debug build 83 | #else 84 | #include 85 | #define XASSERT(x) assert(x) 86 | #define XASSUME(x) assert(x) 87 | #define XTMPVAR(x) x 88 | // XDEBUG 89 | #endif 90 | 91 | // For CBMC (formal checks) 92 | #else 93 | #include 94 | #include 95 | #define XASSERT(x) assert(x) 96 | #define XASSUME(x) __CPROVER_assume(x) 97 | #define XTMPVAR(x) x 98 | #define XPROOFS 99 | #endif // __CPROVER__ 100 | 101 | // get cycle counts 102 | 103 | static inline uint64_t plat_get_cycle() 104 | { 105 | 106 | #if defined(PLAT_ARCH_RV64) 107 | 108 | uint64_t cnt; 109 | asm volatile ("rdcycle %0" : "=r" (cnt)); 110 | return cnt; 111 | 112 | #elif defined(PLAT_ARCH_RV32) 113 | 114 | uint32_t lo, hi; 115 | asm volatile ("rdcycle %0" : "=r" (lo)); 116 | asm volatile ("rdcycleh %0" : "=r" (hi)); 117 | return (((uint64_t) hi) << 32) | ((uint64_t) lo); 118 | 119 | #elif defined(PLAT_ARCH_IA32) || defined(PLAT_ARCH_X64) 120 | 121 | uint32_t lo, hi; 122 | asm volatile ("rdtsc" : "=a" (lo), "=d" (hi)); 123 | return (((uint64_t) hi) << 32) | ((uint64_t) lo); 124 | 125 | #else 126 | 127 | // ARM cycle counts may not be available in userland 128 | return 0; 129 | #endif 130 | } 131 | 132 | // revert if not big endian 133 | 134 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 135 | // nop 136 | #define rev8_be32(x) (x) 137 | #else 138 | // RISC-V: grev(x, 0x18) or rev8 139 | 140 | static inline uint32_t rev8_be32(uint32_t x) 141 | { 142 | return ((x & 0xFF000000) >> 24) | ((x & 0x00FF0000) >> 8) | 143 | ((x & 0x0000FF00) << 8) | ((x & 0x000000FF) << 24); 144 | } 145 | #endif 146 | 147 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 148 | #define rev8_be64(x) (x) 149 | #else 150 | // RISC-V: grev(x, 0x38) or rev8(x) 151 | static inline uint64_t rev8_be64(uint64_t x) 152 | { 153 | return (x << 56) | ((x & 0x000000000000FF00LL) << 40) | 154 | ((x & 0x0000000000FF0000LL) << 24) | 155 | ((x & 0x00000000FF000000LL) << 8) | 156 | ((x & 0x000000FF00000000LL) >> 8) | 157 | ((x & 0x0000FF0000000000LL) >> 24) | 158 | ((x & 0x00FF000000000000LL) >> 40) | (x >> 56); 159 | } 160 | #endif 161 | 162 | // rotate left (for convenience) 163 | 164 | static inline uint32_t rol32(uint32_t x, uint32_t n) 165 | { 166 | return (x << n) | (x >> (32 - n)); 167 | } 168 | 169 | static inline uint64_t rol64(uint64_t x, uint64_t n) 170 | { 171 | return (x << n) | (x >> (64 - n)); 172 | } 173 | 174 | // rotate right (RISC-V ROR or RORI) 175 | 176 | static inline uint32_t ror32(uint32_t x, uint32_t n) 177 | { 178 | return (x >> n) | (x << (32 - n)); 179 | } 180 | 181 | static inline uint64_t ror64(uint64_t x, uint64_t n) 182 | { 183 | return (x >> n) | (x << (64 - n)); 184 | } 185 | 186 | // and with negate (RISC-V ANDN) 187 | 188 | static inline uint32_t andn32(uint32_t x, uint32_t y) 189 | { 190 | return x & ~y; 191 | } 192 | 193 | static inline uint64_t andn64(uint64_t x, uint64_t y) 194 | { 195 | return x & ~y; 196 | } 197 | 198 | // little-endian loads and stores (unaligned) 199 | 200 | static inline uint16_t get16u_le(const uint8_t* v) 201 | { 202 | return (((uint16_t)v[1]) << 8) | ((uint16_t)v[0]); 203 | } 204 | 205 | static inline void put16u_le(uint8_t* v, uint16_t x) 206 | { 207 | v[0] = x; 208 | v[1] = x >> 8; 209 | } 210 | 211 | static inline uint32_t get32u_le(const uint8_t* v) 212 | { 213 | return ((uint32_t)v[0]) | (((uint32_t)v[1]) << 8) | 214 | (((uint32_t)v[2]) << 16) | (((uint32_t)v[3]) << 24); 215 | } 216 | 217 | static inline void put32u_le(uint8_t* v, uint32_t x) 218 | { 219 | v[0] = x; 220 | v[1] = x >> 8; 221 | v[2] = x >> 16; 222 | v[3] = x >> 24; 223 | } 224 | 225 | static inline uint64_t get64u_le(const uint8_t* v) 226 | { 227 | return ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | 228 | (((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) | 229 | (((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) | 230 | (((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56); 231 | } 232 | 233 | static inline void put64u_le(uint8_t* v, uint64_t x) 234 | { 235 | v[0] = x; 236 | v[1] = x >> 8; 237 | v[2] = x >> 16; 238 | v[3] = x >> 24; 239 | v[4] = x >> 32; 240 | v[5] = x >> 40; 241 | v[6] = x >> 48; 242 | v[7] = x >> 56; 243 | } 244 | 245 | // big-endian loads and stores (unaligned) 246 | 247 | static inline uint16_t get16u_be(const uint8_t* v) 248 | { 249 | return (((uint16_t)v[0]) << 8) | ((uint16_t)v[1]); 250 | } 251 | 252 | static inline void put16u_be(uint8_t* v, uint16_t x) 253 | { 254 | v[0] = x >> 8; 255 | v[1] = x; 256 | } 257 | 258 | static inline uint32_t get32u_be(const uint8_t* v) 259 | { 260 | return (((uint32_t)v[0]) << 24) | (((uint32_t)v[1]) << 16) | 261 | (((uint32_t)v[2]) << 8) | ((uint32_t)v[3]); 262 | } 263 | 264 | static inline void put32u_be(uint8_t* v, uint32_t x) 265 | { 266 | v[0] = x >> 24; 267 | v[1] = x >> 16; 268 | v[2] = x >> 8; 269 | v[3] = x; 270 | } 271 | 272 | static inline uint64_t get64u_be(const uint8_t* v) 273 | { 274 | return (((uint64_t)v[0]) << 56) | (((uint64_t)v[1]) << 48) | 275 | (((uint64_t)v[2]) << 40) | (((uint64_t)v[3]) << 32) | 276 | (((uint64_t)v[4]) << 24) | (((uint64_t)v[5]) << 16) | 277 | (((uint64_t)v[6]) << 8) | ((uint64_t)v[7]); 278 | } 279 | 280 | static inline void put64u_be(uint8_t* v, uint64_t x) 281 | { 282 | v[0] = x >> 56; 283 | v[1] = x >> 48; 284 | v[2] = x >> 40; 285 | v[3] = x >> 32; 286 | v[4] = x >> 24; 287 | v[5] = x >> 16; 288 | v[6] = x >> 8; 289 | v[7] = x; 290 | } 291 | 292 | #ifdef __cplusplus 293 | } 294 | #endif 295 | 296 | // _PLAT_LOCAL_H_ 297 | #endif 298 | 299 | -------------------------------------------------------------------------------- /ref-c/template/plat_local.h: -------------------------------------------------------------------------------- 1 | // plat_local.h 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Localization affecting all implementations can be inserted here. 5 | 6 | #ifndef _PLAT_LOCAL_H_ 7 | #define _PLAT_LOCAL_H_ 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #ifndef PLAT_VERS_STR 18 | #define PLAT_VERS_STR "dev version" 19 | #define PLAT_VERS_MAJ 0 20 | #define PLAT_VERS_MIN 0 21 | #endif 22 | 23 | // === platform detection logic 24 | 25 | #ifndef PLAT_XLEN 26 | 27 | #if defined(__riscv) && (__riscv_xlen == 32) 28 | #define PLAT_XLEN 32 29 | #define PLAT_ARCH_STR "PLAT_ARCH_RV32" 30 | #define PLAT_ARCH_RV32 31 | 32 | #elif defined(__riscv) 33 | #define PLAT_XLEN 64 34 | #define PLAT_ARCH_STR "PLAT_ARCH_RV64" 35 | #define PLAT_ARCH_RV64 36 | 37 | #elif defined(__arm__) 38 | #define PLAT_XLEN 32 39 | #define PLAT_ARCH_STR "PLAT_ARCH_ARM32" 40 | #define PLAT_ARCH_ARM32 41 | 42 | #elif defined(__aarch64__) 43 | #define PLAT_XLEN 64 44 | #define PLAT_ARCH_STR "PLAT_ARCH_ARM64" 45 | #define PLAT_ARCH_ARM64 46 | 47 | #elif defined(__i386__) 48 | #define PLAT_XLEN 32 49 | #define PLAT_ARCH_STR "PLAT_ARCH_IA32" 50 | #define PLAT_ARCH_IA32 51 | 52 | #elif defined(__x86_64__) 53 | #define PLAT_XLEN 64 54 | #define PLAT_ARCH_STR "PLAT_ARCH_X64" 55 | #define PLAT_ARCH_X64 56 | 57 | #elif (__WORDSIZE == 32) 58 | #define PLAT_XLEN 32 59 | #define PLAT_ARCH_STR "PLAT_ARCH_GEN32" 60 | #define PLAT_ARCH_GEN32 61 | 62 | #else 63 | // fallback for everything 64 | #define PLAT_XLEN 64 65 | #define PLAT_ARCH_STR "PLAT_ARCH_GEN64" 66 | #define PLAT_ARCH_GEN64 67 | #endif 68 | 69 | // PLAT_XLEN signals that the rest of the macros are defined too 70 | #endif 71 | 72 | // === Assume-Assert checks 73 | 74 | // No-op for production 75 | #ifndef __CPROVER__ 76 | 77 | #ifndef XDEBUG 78 | #define XASSERT(x) 79 | #define XASSUME(x) 80 | #define XTMPVAR(x) 81 | 82 | // Runtime checks in debug build 83 | #else 84 | #include 85 | #define XASSERT(x) assert(x) 86 | #define XASSUME(x) assert(x) 87 | #define XTMPVAR(x) x 88 | // XDEBUG 89 | #endif 90 | 91 | // For CBMC (formal checks) 92 | #else 93 | #include 94 | #include 95 | #define XASSERT(x) assert(x) 96 | #define XASSUME(x) __CPROVER_assume(x) 97 | #define XTMPVAR(x) x 98 | #define XPROOFS 99 | #endif // __CPROVER__ 100 | 101 | // get cycle counts 102 | 103 | static inline uint64_t plat_get_cycle() 104 | { 105 | 106 | #if defined(PLAT_ARCH_RV64) 107 | 108 | uint64_t cnt; 109 | asm volatile ("rdcycle %0" : "=r" (cnt)); 110 | return cnt; 111 | 112 | #elif defined(PLAT_ARCH_RV32) 113 | 114 | uint32_t lo, hi; 115 | asm volatile ("rdcycle %0" : "=r" (lo)); 116 | asm volatile ("rdcycleh %0" : "=r" (hi)); 117 | return (((uint64_t) hi) << 32) | ((uint64_t) lo); 118 | 119 | #elif defined(PLAT_ARCH_IA32) || defined(PLAT_ARCH_X64) 120 | 121 | uint32_t lo, hi; 122 | asm volatile ("rdtsc" : "=a" (lo), "=d" (hi)); 123 | return (((uint64_t) hi) << 32) | ((uint64_t) lo); 124 | 125 | #else 126 | 127 | // ARM cycle counts may not be available in userland 128 | return 0; 129 | #endif 130 | } 131 | 132 | // revert if not big endian 133 | 134 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 135 | // nop 136 | #define rev8_be32(x) (x) 137 | #else 138 | // RISC-V: grev(x, 0x18) or rev8 139 | 140 | static inline uint32_t rev8_be32(uint32_t x) 141 | { 142 | return ((x & 0xFF000000) >> 24) | ((x & 0x00FF0000) >> 8) | 143 | ((x & 0x0000FF00) << 8) | ((x & 0x000000FF) << 24); 144 | } 145 | #endif 146 | 147 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 148 | #define rev8_be64(x) (x) 149 | #else 150 | // RISC-V: grev(x, 0x38) or rev8(x) 151 | static inline uint64_t rev8_be64(uint64_t x) 152 | { 153 | return (x << 56) | ((x & 0x000000000000FF00LL) << 40) | 154 | ((x & 0x0000000000FF0000LL) << 24) | 155 | ((x & 0x00000000FF000000LL) << 8) | 156 | ((x & 0x000000FF00000000LL) >> 8) | 157 | ((x & 0x0000FF0000000000LL) >> 24) | 158 | ((x & 0x00FF000000000000LL) >> 40) | (x >> 56); 159 | } 160 | #endif 161 | 162 | // rotate left (for convenience) 163 | 164 | static inline uint32_t rol32(uint32_t x, uint32_t n) 165 | { 166 | return (x << n) | (x >> (32 - n)); 167 | } 168 | 169 | static inline uint64_t rol64(uint64_t x, uint64_t n) 170 | { 171 | return (x << n) | (x >> (64 - n)); 172 | } 173 | 174 | // rotate right (RISC-V ROR or RORI) 175 | 176 | static inline uint32_t ror32(uint32_t x, uint32_t n) 177 | { 178 | return (x >> n) | (x << (32 - n)); 179 | } 180 | 181 | static inline uint64_t ror64(uint64_t x, uint64_t n) 182 | { 183 | return (x >> n) | (x << (64 - n)); 184 | } 185 | 186 | // and with negate (RISC-V ANDN) 187 | 188 | static inline uint32_t andn32(uint32_t x, uint32_t y) 189 | { 190 | return x & ~y; 191 | } 192 | 193 | static inline uint64_t andn64(uint64_t x, uint64_t y) 194 | { 195 | return x & ~y; 196 | } 197 | 198 | // little-endian loads and stores (unaligned) 199 | 200 | static inline uint16_t get16u_le(const uint8_t* v) 201 | { 202 | return (((uint16_t)v[1]) << 8) | ((uint16_t)v[0]); 203 | } 204 | 205 | static inline void put16u_le(uint8_t* v, uint16_t x) 206 | { 207 | v[0] = x; 208 | v[1] = x >> 8; 209 | } 210 | 211 | static inline uint32_t get32u_le(const uint8_t* v) 212 | { 213 | return ((uint32_t)v[0]) | (((uint32_t)v[1]) << 8) | 214 | (((uint32_t)v[2]) << 16) | (((uint32_t)v[3]) << 24); 215 | } 216 | 217 | static inline void put32u_le(uint8_t* v, uint32_t x) 218 | { 219 | v[0] = x; 220 | v[1] = x >> 8; 221 | v[2] = x >> 16; 222 | v[3] = x >> 24; 223 | } 224 | 225 | static inline uint64_t get64u_le(const uint8_t* v) 226 | { 227 | return ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | 228 | (((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) | 229 | (((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) | 230 | (((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56); 231 | } 232 | 233 | static inline void put64u_le(uint8_t* v, uint64_t x) 234 | { 235 | v[0] = x; 236 | v[1] = x >> 8; 237 | v[2] = x >> 16; 238 | v[3] = x >> 24; 239 | v[4] = x >> 32; 240 | v[5] = x >> 40; 241 | v[6] = x >> 48; 242 | v[7] = x >> 56; 243 | } 244 | 245 | // big-endian loads and stores (unaligned) 246 | 247 | static inline uint16_t get16u_be(const uint8_t* v) 248 | { 249 | return (((uint16_t)v[0]) << 8) | ((uint16_t)v[1]); 250 | } 251 | 252 | static inline void put16u_be(uint8_t* v, uint16_t x) 253 | { 254 | v[0] = x >> 8; 255 | v[1] = x; 256 | } 257 | 258 | static inline uint32_t get32u_be(const uint8_t* v) 259 | { 260 | return (((uint32_t)v[0]) << 24) | (((uint32_t)v[1]) << 16) | 261 | (((uint32_t)v[2]) << 8) | ((uint32_t)v[3]); 262 | } 263 | 264 | static inline void put32u_be(uint8_t* v, uint32_t x) 265 | { 266 | v[0] = x >> 24; 267 | v[1] = x >> 16; 268 | v[2] = x >> 8; 269 | v[3] = x; 270 | } 271 | 272 | static inline uint64_t get64u_be(const uint8_t* v) 273 | { 274 | return (((uint64_t)v[0]) << 56) | (((uint64_t)v[1]) << 48) | 275 | (((uint64_t)v[2]) << 40) | (((uint64_t)v[3]) << 32) | 276 | (((uint64_t)v[4]) << 24) | (((uint64_t)v[5]) << 16) | 277 | (((uint64_t)v[6]) << 8) | ((uint64_t)v[7]); 278 | } 279 | 280 | static inline void put64u_be(uint8_t* v, uint64_t x) 281 | { 282 | v[0] = x >> 56; 283 | v[1] = x >> 48; 284 | v[2] = x >> 40; 285 | v[3] = x >> 32; 286 | v[4] = x >> 24; 287 | v[5] = x >> 16; 288 | v[6] = x >> 8; 289 | v[7] = x; 290 | } 291 | 292 | #ifdef __cplusplus 293 | } 294 | #endif 295 | 296 | // _PLAT_LOCAL_H_ 297 | #endif 298 | 299 | -------------------------------------------------------------------------------- /ref-c/nist/rng.c: -------------------------------------------------------------------------------- 1 | /* 2 | NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. 3 | 4 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 5 | 6 | You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. 7 | */ 8 | 9 | #include 10 | #include "rng.h" 11 | #include 12 | #include 13 | #include 14 | 15 | AES256_CTR_DRBG_struct DRBG_ctx; 16 | 17 | void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer); 18 | 19 | /* 20 | seedexpander_init() 21 | ctx - stores the current state of an instance of the seed expander 22 | seed - a 32 byte random value 23 | diversifier - an 8 byte diversifier 24 | maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier 25 | */ 26 | int 27 | seedexpander_init(AES_XOF_struct *ctx, 28 | unsigned char *seed, 29 | unsigned char *diversifier, 30 | unsigned long maxlen) 31 | { 32 | if ( maxlen >= 0x100000000 ) 33 | return RNG_BAD_MAXLEN; 34 | 35 | ctx->length_remaining = maxlen; 36 | 37 | memcpy(ctx->key, seed, 32); 38 | 39 | memcpy(ctx->ctr, diversifier, 8); 40 | ctx->ctr[11] = maxlen % 256; 41 | maxlen >>= 8; 42 | ctx->ctr[10] = maxlen % 256; 43 | maxlen >>= 8; 44 | ctx->ctr[9] = maxlen % 256; 45 | maxlen >>= 8; 46 | ctx->ctr[8] = maxlen % 256; 47 | memset(ctx->ctr+12, 0x00, 4); 48 | 49 | ctx->buffer_pos = 16; 50 | memset(ctx->buffer, 0x00, 16); 51 | 52 | return RNG_SUCCESS; 53 | } 54 | 55 | /* 56 | seedexpander() 57 | ctx - stores the current state of an instance of the seed expander 58 | x - returns the XOF data 59 | xlen - number of bytes to return 60 | */ 61 | int 62 | seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen) 63 | { 64 | unsigned long offset; 65 | 66 | if ( x == NULL ) 67 | return RNG_BAD_OUTBUF; 68 | if ( xlen >= ctx->length_remaining ) 69 | return RNG_BAD_REQ_LEN; 70 | 71 | ctx->length_remaining -= xlen; 72 | 73 | offset = 0; 74 | while ( xlen > 0 ) { 75 | if ( xlen <= (unsigned) (16-ctx->buffer_pos) ) { // buffer has what we need 76 | memcpy(x+offset, ctx->buffer+ctx->buffer_pos, xlen); 77 | ctx->buffer_pos += xlen; 78 | 79 | return RNG_SUCCESS; 80 | } 81 | 82 | // take what's in the buffer 83 | memcpy(x+offset, ctx->buffer+ctx->buffer_pos, 16-ctx->buffer_pos); 84 | xlen -= 16-ctx->buffer_pos; 85 | offset += 16-ctx->buffer_pos; 86 | 87 | AES256_ECB(ctx->key, ctx->ctr, ctx->buffer); 88 | ctx->buffer_pos = 0; 89 | 90 | //increment the counter 91 | for (int i=15; i>=12; i--) { 92 | if ( ctx->ctr[i] == 0xff ) 93 | ctx->ctr[i] = 0x00; 94 | else { 95 | ctx->ctr[i]++; 96 | break; 97 | } 98 | } 99 | 100 | } 101 | 102 | return RNG_SUCCESS; 103 | } 104 | 105 | 106 | void handleErrors(void) 107 | { 108 | ERR_print_errors_fp(stderr); 109 | abort(); 110 | } 111 | 112 | // Use whatever AES implementation you have. This uses AES from openSSL library 113 | // key - 256-bit AES key 114 | // ctr - a 128-bit plaintext value 115 | // buffer - a 128-bit ciphertext value 116 | void 117 | AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer) 118 | { 119 | EVP_CIPHER_CTX *ctx; 120 | 121 | int len; 122 | 123 | //int ciphertext_len; 124 | 125 | /* Create and initialise the context */ 126 | if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); 127 | 128 | if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL)) 129 | handleErrors(); 130 | 131 | if(1 != EVP_EncryptUpdate(ctx, buffer, &len, ctr, 16)) 132 | handleErrors(); 133 | //ciphertext_len = len; 134 | 135 | /* Clean up */ 136 | EVP_CIPHER_CTX_free(ctx); 137 | } 138 | 139 | void 140 | randombytes_init(unsigned char *entropy_input, 141 | unsigned char *personalization_string, 142 | int security_strength) 143 | { 144 | unsigned char seed_material[48]; 145 | 146 | (void) security_strength; 147 | 148 | memcpy(seed_material, entropy_input, 48); 149 | if (personalization_string) 150 | for (int i=0; i<48; i++) 151 | seed_material[i] ^= personalization_string[i]; 152 | memset(DRBG_ctx.Key, 0x00, 32); 153 | memset(DRBG_ctx.V, 0x00, 16); 154 | AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V); 155 | DRBG_ctx.reseed_counter = 1; 156 | } 157 | 158 | int 159 | randombytes(unsigned char *x, unsigned long long xlen) 160 | { 161 | unsigned char block[16]; 162 | int i = 0; 163 | 164 | while ( xlen > 0 ) { 165 | //increment V 166 | for (int j=15; j>=0; j--) { 167 | if ( DRBG_ctx.V[j] == 0xff ) 168 | DRBG_ctx.V[j] = 0x00; 169 | else { 170 | DRBG_ctx.V[j]++; 171 | break; 172 | } 173 | } 174 | AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block); 175 | if ( xlen > 15 ) { 176 | memcpy(x+i, block, 16); 177 | i += 16; 178 | xlen -= 16; 179 | } 180 | else { 181 | memcpy(x+i, block, xlen); 182 | xlen = 0; 183 | } 184 | } 185 | AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V); 186 | DRBG_ctx.reseed_counter++; 187 | 188 | return RNG_SUCCESS; 189 | } 190 | 191 | void 192 | AES256_CTR_DRBG_Update(unsigned char *provided_data, 193 | unsigned char *Key, 194 | unsigned char *V) 195 | { 196 | unsigned char temp[48]; 197 | 198 | for (int i=0; i<3; i++) { 199 | //increment V 200 | for (int j=15; j>=0; j--) { 201 | if ( V[j] == 0xff ) 202 | V[j] = 0x00; 203 | else { 204 | V[j]++; 205 | break; 206 | } 207 | } 208 | 209 | AES256_ECB(Key, V, temp+16*i); 210 | } 211 | if ( provided_data != NULL ) 212 | for (int i=0; i<48; i++) 213 | temp[i] ^= provided_data[i]; 214 | memcpy(Key, temp, 32); 215 | memcpy(V, temp+32, 16); 216 | } 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /ref-c/template/rng.c: -------------------------------------------------------------------------------- 1 | /* 2 | NIST-developed software is provided by NIST as a public service. You may use, copy, and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify, and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software. 3 | 4 | NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT, OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. 5 | 6 | You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States. 7 | */ 8 | 9 | #include 10 | #include "rng.h" 11 | #include 12 | #include 13 | #include 14 | 15 | AES256_CTR_DRBG_struct DRBG_ctx; 16 | 17 | void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer); 18 | 19 | /* 20 | seedexpander_init() 21 | ctx - stores the current state of an instance of the seed expander 22 | seed - a 32 byte random value 23 | diversifier - an 8 byte diversifier 24 | maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier 25 | */ 26 | int 27 | seedexpander_init(AES_XOF_struct *ctx, 28 | unsigned char *seed, 29 | unsigned char *diversifier, 30 | unsigned long maxlen) 31 | { 32 | if ( maxlen >= 0x100000000 ) 33 | return RNG_BAD_MAXLEN; 34 | 35 | ctx->length_remaining = maxlen; 36 | 37 | memcpy(ctx->key, seed, 32); 38 | 39 | memcpy(ctx->ctr, diversifier, 8); 40 | ctx->ctr[11] = maxlen % 256; 41 | maxlen >>= 8; 42 | ctx->ctr[10] = maxlen % 256; 43 | maxlen >>= 8; 44 | ctx->ctr[9] = maxlen % 256; 45 | maxlen >>= 8; 46 | ctx->ctr[8] = maxlen % 256; 47 | memset(ctx->ctr+12, 0x00, 4); 48 | 49 | ctx->buffer_pos = 16; 50 | memset(ctx->buffer, 0x00, 16); 51 | 52 | return RNG_SUCCESS; 53 | } 54 | 55 | /* 56 | seedexpander() 57 | ctx - stores the current state of an instance of the seed expander 58 | x - returns the XOF data 59 | xlen - number of bytes to return 60 | */ 61 | int 62 | seedexpander(AES_XOF_struct *ctx, unsigned char *x, unsigned long xlen) 63 | { 64 | unsigned long offset; 65 | 66 | if ( x == NULL ) 67 | return RNG_BAD_OUTBUF; 68 | if ( xlen >= ctx->length_remaining ) 69 | return RNG_BAD_REQ_LEN; 70 | 71 | ctx->length_remaining -= xlen; 72 | 73 | offset = 0; 74 | while ( xlen > 0 ) { 75 | if ( xlen <= (unsigned) (16-ctx->buffer_pos) ) { // buffer has what we need 76 | memcpy(x+offset, ctx->buffer+ctx->buffer_pos, xlen); 77 | ctx->buffer_pos += xlen; 78 | 79 | return RNG_SUCCESS; 80 | } 81 | 82 | // take what's in the buffer 83 | memcpy(x+offset, ctx->buffer+ctx->buffer_pos, 16-ctx->buffer_pos); 84 | xlen -= 16-ctx->buffer_pos; 85 | offset += 16-ctx->buffer_pos; 86 | 87 | AES256_ECB(ctx->key, ctx->ctr, ctx->buffer); 88 | ctx->buffer_pos = 0; 89 | 90 | //increment the counter 91 | for (int i=15; i>=12; i--) { 92 | if ( ctx->ctr[i] == 0xff ) 93 | ctx->ctr[i] = 0x00; 94 | else { 95 | ctx->ctr[i]++; 96 | break; 97 | } 98 | } 99 | 100 | } 101 | 102 | return RNG_SUCCESS; 103 | } 104 | 105 | 106 | void handleErrors(void) 107 | { 108 | ERR_print_errors_fp(stderr); 109 | abort(); 110 | } 111 | 112 | // Use whatever AES implementation you have. This uses AES from openSSL library 113 | // key - 256-bit AES key 114 | // ctr - a 128-bit plaintext value 115 | // buffer - a 128-bit ciphertext value 116 | void 117 | AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *buffer) 118 | { 119 | EVP_CIPHER_CTX *ctx; 120 | 121 | int len; 122 | 123 | //int ciphertext_len; 124 | 125 | /* Create and initialise the context */ 126 | if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); 127 | 128 | if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_ecb(), NULL, key, NULL)) 129 | handleErrors(); 130 | 131 | if(1 != EVP_EncryptUpdate(ctx, buffer, &len, ctr, 16)) 132 | handleErrors(); 133 | //ciphertext_len = len; 134 | 135 | /* Clean up */ 136 | EVP_CIPHER_CTX_free(ctx); 137 | } 138 | 139 | void 140 | randombytes_init(unsigned char *entropy_input, 141 | unsigned char *personalization_string, 142 | int security_strength) 143 | { 144 | unsigned char seed_material[48]; 145 | 146 | (void) security_strength; 147 | 148 | memcpy(seed_material, entropy_input, 48); 149 | if (personalization_string) 150 | for (int i=0; i<48; i++) 151 | seed_material[i] ^= personalization_string[i]; 152 | memset(DRBG_ctx.Key, 0x00, 32); 153 | memset(DRBG_ctx.V, 0x00, 16); 154 | AES256_CTR_DRBG_Update(seed_material, DRBG_ctx.Key, DRBG_ctx.V); 155 | DRBG_ctx.reseed_counter = 1; 156 | } 157 | 158 | int 159 | randombytes(unsigned char *x, unsigned long long xlen) 160 | { 161 | unsigned char block[16]; 162 | int i = 0; 163 | 164 | while ( xlen > 0 ) { 165 | //increment V 166 | for (int j=15; j>=0; j--) { 167 | if ( DRBG_ctx.V[j] == 0xff ) 168 | DRBG_ctx.V[j] = 0x00; 169 | else { 170 | DRBG_ctx.V[j]++; 171 | break; 172 | } 173 | } 174 | AES256_ECB(DRBG_ctx.Key, DRBG_ctx.V, block); 175 | if ( xlen > 15 ) { 176 | memcpy(x+i, block, 16); 177 | i += 16; 178 | xlen -= 16; 179 | } 180 | else { 181 | memcpy(x+i, block, xlen); 182 | xlen = 0; 183 | } 184 | } 185 | AES256_CTR_DRBG_Update(NULL, DRBG_ctx.Key, DRBG_ctx.V); 186 | DRBG_ctx.reseed_counter++; 187 | 188 | return RNG_SUCCESS; 189 | } 190 | 191 | void 192 | AES256_CTR_DRBG_Update(unsigned char *provided_data, 193 | unsigned char *Key, 194 | unsigned char *V) 195 | { 196 | unsigned char temp[48]; 197 | 198 | for (int i=0; i<3; i++) { 199 | //increment V 200 | for (int j=15; j>=0; j--) { 201 | if ( V[j] == 0xff ) 202 | V[j] = 0x00; 203 | else { 204 | V[j]++; 205 | break; 206 | } 207 | } 208 | 209 | AES256_ECB(Key, V, temp+16*i); 210 | } 211 | if ( provided_data != NULL ) 212 | for (int i=0; i<48; i++) 213 | temp[i] ^= provided_data[i]; 214 | memcpy(Key, temp, 32); 215 | memcpy(V, temp+32, 16); 216 | } 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /ref-c/mask_random.c: -------------------------------------------------------------------------------- 1 | // mask_random.c 2 | // Copyright (c) 2023 Raccoon Signature Team. See LICENSE. 3 | 4 | // === Mask random generator (dummy implementations) 5 | 6 | #include 7 | 8 | #include "mask_random.h" 9 | #include "plat_local.h" 10 | #include "racc_param.h" 11 | 12 | #if RACC_D > 1 13 | #ifdef MASK_RANDOM_ASCON 14 | 15 | // === MASK_RANDOM_ASCON is set 16 | 17 | /* 18 | ASCON v1.2 masking noise source simulation. 19 | 20 | This pseudorandom generator simulates a masking noise source based 21 | on Ascon-80pq from the specification of Ascon v1.2 (May 31, 2021). 22 | Note that this particular variant of Ascon is not an XOF; The output 23 | sequence is ciphertext from the AEAD mode with plaintext set as zero. 24 | 25 | The statistical properties of this generator are more than sufficient 26 | as a masking noise source. A similar Ascon-based construction has 27 | been used in hardware implementations for this purpose, continuously 28 | re-seeding from an on-chip entropy source. 29 | 30 | In this instance, the reference code is used mainly to demonstrate 31 | the performance impact of having a "good" random number generator. 32 | */ 33 | 34 | // ASCON v1.2 Permutation 35 | 36 | static inline void ascon_p(uint64_t s[5], int n) 37 | { 38 | uint64_t c = ((3 + (n)) << 4 | (12 - (n))); 39 | uint64_t t; 40 | 41 | for (int i = 0; i < n; i++) { 42 | 43 | s[2] ^= c; // round constant 44 | c -= 0xF; 45 | 46 | // s-box layer 47 | s[0] ^= s[4]; 48 | s[4] ^= s[3]; 49 | s[2] ^= s[1]; 50 | t = andn64(s[0], s[4]); 51 | s[0] ^= andn64(s[2], s[1]); 52 | s[2] ^= andn64(s[4], s[3]); 53 | s[4] ^= andn64(s[1], s[0]); 54 | s[1] ^= andn64(s[3], s[2]); 55 | s[3] ^= t; 56 | s[1] ^= s[0]; 57 | s[3] ^= s[2]; 58 | s[0] ^= s[4]; 59 | 60 | // linear layer 61 | s[0] ^= ror64(s[0], 19) ^ ror64(s[0], 28); 62 | s[1] ^= ror64(s[1], 39) ^ ror64(s[1], 61); 63 | s[2] ^= ror64(s[2], 1) ^ ror64(s[2], 6); 64 | s[3] ^= ror64(s[3], 10) ^ ror64(s[3], 17); 65 | s[4] ^= ror64(s[4], 7) ^ ror64(s[4], 41); 66 | s[2] = ~(s[2]); 67 | } 68 | } 69 | 70 | // From six-round AEAD mode; takes input ("pt"), returns ciphertext. 71 | 72 | static inline uint64_t asconp6_enc(uint64_t s[5], uint64_t pt) 73 | { 74 | pt ^= s[0]; 75 | s[0] = pt; 76 | ascon_p(s, 6); 77 | 78 | return pt; 79 | } 80 | 81 | // initialize. you can set seed=NULL in case just zeroizes 82 | 83 | void mask_random_init(mask_random_t *mrg) 84 | { 85 | // trivial test vector; see mask_random_selftest() 86 | const uint8_t key[20] = { 87 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // KAT Key: 160-bit 88 | 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; 89 | const uint8_t iv[16] = { 90 | 0, 1, 2, 3, 4, 5, 6, 7, // KAT nonce: 128-bit 91 | 8, 9, 10, 11, 12, 13, 14, 15 92 | }; 93 | 94 | size_t i; 95 | uint64_t *s; 96 | 97 | /* 98 | ** +---------------------------------------------------------------+ 99 | ** | Each individual RNG should be independently initialized | 100 | ** | and continuously reseeded using real (physical) entropy. | 101 | ** +---------------------------------------------------------------+ 102 | */ 103 | 104 | for (i = 0; i < RACC_D - 1; i++) { 105 | 106 | s = mrg->s[i]; 107 | 108 | // the "test vector IV" is for Ascon80-PQ 109 | s[0] = 0xA0400C0600000000 | get32u_be(key); 110 | s[1] = get64u_be(key + 4); 111 | s[2] = get64u_be(key + 12); 112 | s[3] = get64u_be(iv); 113 | s[4] = get64u_be(iv + 8); 114 | 115 | // modify nonce with the share # in this dummy implementation 116 | s[3] += i; 117 | 118 | ascon_p(s, 12); 119 | s[2] ^= get32u_be(key); 120 | s[3] ^= get64u_be(key + 4); 121 | s[4] ^= get64u_be(key + 12); 122 | s[4] ^= 1; // Domain separation. 123 | } 124 | } 125 | 126 | // get a 64-bit random number 127 | 128 | uint64_t mask_rand64(mask_random_t *mrg, size_t ri) 129 | { 130 | return asconp6_enc(mrg->s[ri], 0); 131 | } 132 | 133 | // sample a uniform random polynomial 134 | 135 | void mask_random_poly(mask_random_t *mrg, int64_t *r, size_t ri) 136 | { 137 | size_t i; 138 | int64_t z; 139 | uint64_t s[5]; 140 | 141 | // local copy of state allows some additional optimizations 142 | memcpy(s, mrg->s[ri], sizeof(s)); 143 | 144 | for (i = 0; i < RACC_N; i++) { 145 | do { 146 | z = s[0] & RACC_QMSK; 147 | ascon_p(s, 6); 148 | } while (z >= RACC_Q); 149 | r[i] = z; 150 | } 151 | 152 | // copy it back 153 | memcpy(mrg->s[ri], s, sizeof(s)); 154 | } 155 | 156 | // ASCON: simple deterministic self-test, return nonzero on failure 157 | 158 | int mask_random_selftest() 159 | { 160 | // From: Count = 1057, ascon80pqv12/LWC_AEAD_KAT_160_128.txt 161 | // NOTE: The plaintext words are actually big-endian in Ascon. 162 | const uint64_t pt[4] = { 163 | 0x0001020304050607, 0x08090A0B0C0D0E0F, 164 | 0x1011121314151617, 0x18191A1B1C1D1E1F 165 | }; 166 | const uint64_t ct[4] = { 167 | 0x2846418067CE9386, 0xB47F0584BF9EEE3F, 168 | 0x51A62969F011D86D, 0xE54D5B258AF88C21 169 | }; 170 | 171 | int fail = 0; 172 | int i; 173 | uint64_t x; 174 | mask_random_t mrg; 175 | 176 | mask_random_init(&mrg); 177 | 178 | for (i = 0; i < 4; i++) { 179 | x = asconp6_enc(mrg.s[0], pt[i]) ^ ct[i]; 180 | if (x != 0) { 181 | fail++; 182 | } 183 | } 184 | 185 | return fail; 186 | } 187 | 188 | #else 189 | 190 | // === MASK_RANDOM_ASCON *not* set 191 | 192 | /* 193 | LFSR-127: A simple LFSR that outputs 64 bits at a time. 194 | 195 | While not theoretically/cryptographically secure, the output has 196 | reasonable statistical qualities -- sufficient for side-channel 197 | masking noise in many applications. 198 | 199 | Degree 127 is a "classic" -- the multiplicative field size 2^127-1 200 | is a (Mersenne) prime, so a large cycle is guaranteed. The trinomial 201 | x^127+x^64+1 is suitable for stepping 64 times at once while keeping 202 | the circuit depth low (not too many stacked XORs.) 203 | 204 | The state is in two words s[1],s[0], where s[1] is bits 126..64, 205 | and s[0] has bits 63..0. 206 | */ 207 | 208 | // period 2^127-1, primitive polynomial x^127+x^64+1, 64 steps 209 | 210 | static inline uint64_t lfsr127(uint64_t s[2]) 211 | { 212 | uint64_t x; 213 | 214 | x = ((s[1] << 1) | (s[0] >> 63)) ^ (s[1] >> 62); 215 | s[1] = (x ^ s[0]) & 0x7FFFFFFFFFFFFFFF; // high word 216 | s[0] = x; // low word 217 | 218 | return x; // return 64 bits is the low value 219 | } 220 | 221 | // get a 64-bit random number 222 | 223 | uint64_t mask_rand64(mask_random_t *mrg, size_t ri) 224 | { 225 | return lfsr127(mrg->s[ri]); 226 | } 227 | 228 | // sample a uniform random polynomial 229 | 230 | void mask_random_poly(mask_random_t *mrg, int64_t *r, size_t ri) 231 | { 232 | size_t i; 233 | int64_t z; 234 | uint64_t s[2]; 235 | 236 | // local state allows some additional optimizations 237 | memcpy(s, mrg->s[ri], sizeof(s)); 238 | for (i = 0; i < RACC_N; i++) { 239 | do { 240 | z = lfsr127(s) & RACC_QMSK; 241 | } while (z >= RACC_Q); 242 | r[i] = z; 243 | } 244 | memcpy(mrg->s[ri], s, sizeof(s)); 245 | } 246 | 247 | // Initialize the mask random number generator from physical sources. 248 | 249 | void mask_random_init(mask_random_t *mrg) 250 | { 251 | // test vector key is default 252 | const uint8_t key[16] = { 253 | 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, 254 | 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F 255 | }; 256 | 257 | size_t i; 258 | 259 | /* 260 | ** +---------------------------------------------------------------+ 261 | ** | Each individual RNG should be independently initialized | 262 | ** | and continuously reseeded using real (physical) entropy. | 263 | ** +---------------------------------------------------------------+ 264 | */ 265 | 266 | // set the state 267 | for (i = 0; i < RACC_D - 1; i++) { 268 | mrg->s[i][0] = get64u_le(key); 269 | mrg->s[i][1] = get64u_le(key + 8) + (0x0123456789ABCDEF * i); 270 | } 271 | } 272 | 273 | // LFSR127: simple deterministic self-test, return nonzero on failure 274 | 275 | int mask_random_selftest() 276 | { 277 | const uint64_t lfsr127_kat[8] = { 278 | 0x1E3C5A7896B4D2F1, 0x3355FF98AACC6602, 0x5AD34BC078F169E6, 279 | 0xD30D68B1A47A1FC9, 0x13BC46E3B916EC5F, 0x81625CA43AD9E72D, 280 | 0x25BC348F079E16E5, 0x49BCD0567A8FE390 }; 281 | 282 | int i; 283 | mask_random_t mrg; 284 | int fail = 0; 285 | 286 | // the 287 | mask_random_init(&mrg); 288 | 289 | for (i = 0; i < 8; i++) { 290 | if (lfsr127(mrg.s[0]) != lfsr127_kat[i]) { 291 | fail++; 292 | } 293 | } 294 | 295 | return fail; 296 | } 297 | 298 | #endif 299 | // RACC_D 300 | #endif 301 | --------------------------------------------------------------------------------