From 17fc0da52e48979ea36d39cbe84476975e259a85 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Thu, 4 Apr 2019 13:42:03 +0200 Subject: [PATCH 01/32] Prohibit using char without explicit sign modifier Related to #79 --- .gitmodules | 3 +++ requirements.txt | 1 + test/pycparser | 1 + test/test_char.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 .gitmodules create mode 160000 test/pycparser create mode 100644 test/test_char.py diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..b547037a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/pycparser"] + path = test/pycparser + url = https://github.com/eliben/pycparser.git diff --git a/requirements.txt b/requirements.txt index 01b892fa..b3f4ea5d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ PyYAML nose rednose +pycparser diff --git a/test/pycparser b/test/pycparser new file mode 160000 index 00000000..e1a1d737 --- /dev/null +++ b/test/pycparser @@ -0,0 +1 @@ +Subproject commit e1a1d737be66308b633215fa26ac5ed30e890103 diff --git a/test/test_char.py b/test/test_char.py new file mode 100644 index 00000000..32ad99a0 --- /dev/null +++ b/test/test_char.py @@ -0,0 +1,62 @@ + +""" +Checks that the implementation does not make use of the `char` type. +This is ambiguous; compilers can freely choose `signed` or `unsigned` char. +""" + +import pqclean +import pycparser +import os + + +def test_char(): + for scheme in pqclean.Scheme.all_schemes(): + for implementation in scheme.implementations: + yield check_char, implementation + + +def walk_tree(ast): + if type(ast) is pycparser.c_ast.IdentifierType: + if ast.names == ['char']: + yield ast + + for (_, child) in ast.children(): + yield from walk_tree(child) # recursively yield prohibited nodes + + +def check_char(implementation): + errors = [] + for fname in os.listdir(implementation.path()): + if not fname.endswith(".c"): + continue + tdir, _ = os.path.split(os.path.realpath(__file__)) + ast = pycparser.parse_file( + os.path.join(implementation.path(), fname), + use_cpp=True, + cpp_args=[ + '-nostdinc', # pycparser cannot deal with e.g. __attribute__ + '-I{}'.format(os.path.join(tdir, "../common")), + # necessary to mock e.g. + '-I{}'.format( + os.path.join(tdir, 'pycparser/utils/fake_libc_include')), + ] + ) + for node in walk_tree(ast): + # flatten nodes to a string to easily enforce uniqueness + err = "\n at {c.file}:{c.line}:{c.column}".format(c=node.coord) + if err not in errors: + errors.append(err) + if errors: + raise AssertionError( + "Prohibited use of char without explicit signed/unsigned" + + "".join(errors) + ) + + +if __name__ == '__main__': + try: + import nose2 + nose2.main() + except ImportError: + import nose + nose.runmodule() From 97e428a0b7e925b6ea408ce8fe57f16e5659326e Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Thu, 4 Apr 2019 13:52:40 +0200 Subject: [PATCH 02/32] Skip preprocessing when cpp unavailable --- test/test_char.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test_char.py b/test/test_char.py index 32ad99a0..703e1b17 100644 --- a/test/test_char.py +++ b/test/test_char.py @@ -7,6 +7,8 @@ This is ambiguous; compilers can freely choose `signed` or `unsigned` char. import pqclean import pycparser import os +import unittest +import shutil def test_char(): @@ -25,6 +27,8 @@ def walk_tree(ast): def check_char(implementation): + if not shutil.which('cpp'): + raise unittest.SkipTest("C pre-processor (cpp) was not found.") errors = [] for fname in os.listdir(implementation.path()): if not fname.endswith(".c"): @@ -34,6 +38,7 @@ def check_char(implementation): os.path.join(implementation.path(), fname), use_cpp=True, cpp_args=[ + '-std=c99', '-nostdinc', # pycparser cannot deal with e.g. __attribute__ '-I{}'.format(os.path.join(tdir, "../common")), # necessary to mock e.g. From 8067df4aa98433f8d29cc9d7d9949a059e7ef9d6 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 09:20:50 +0200 Subject: [PATCH 03/32] install pycparser with pip3 --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 17f13e49..09a6e8d2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,6 +24,7 @@ version: 2 name: Run tests command: | export CC=${CC} + pip3 install -r requirements.txt cd test && python3 -m nose --rednose --verbose From 9a6787c87250ca9b3db5712cf557909d58ad6e70 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 09:28:22 +0200 Subject: [PATCH 04/32] Properly set up GCC on OS X --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 66a4893b..1de9ed98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,9 +20,12 @@ matrix: homebrew: packages: - astyle - - gcc@8 + - gcc before_install: - pip3 install -r requirements.txt + - export PATH="/usr/local/bin:$PATH" + - ln -s /usr/local/Cellar/gcc/8.3.0/bin/gcc-8 /usr/local/bin/gcc + - ln -s /usr/local/Cellar/gcc/8.3.0/bin/cpp-8 /usr/local/bin/cpp - gcc --version script: - "cd test && python3 -m nose --rednose --verbose" From bfa8589f968eec5add0b9f8286cf3872773781d8 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 10:31:31 +0200 Subject: [PATCH 05/32] Use cc -E instead of cpp --- test/test_char.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_char.py b/test/test_char.py index 703e1b17..29a0b857 100644 --- a/test/test_char.py +++ b/test/test_char.py @@ -37,7 +37,9 @@ def check_char(implementation): ast = pycparser.parse_file( os.path.join(implementation.path(), fname), use_cpp=True, + cpp_path='cc', cpp_args=[ + '-E', '-std=c99', '-nostdinc', # pycparser cannot deal with e.g. __attribute__ '-I{}'.format(os.path.join(tdir, "../common")), From 4e47a0b513eff75cea9b884289f9fcdfb6a5b086 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 10:39:08 +0200 Subject: [PATCH 06/32] Skip the prohibit-char test on Windows due to lack of cc --- test/helpers.py | 1 - test/test_char.py | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/test/helpers.py b/test/helpers.py index 238e234c..e6c3adc1 100644 --- a/test/helpers.py +++ b/test/helpers.py @@ -86,7 +86,6 @@ def ensure_available(executable): """ path = shutil.which(executable) if path: - print("Found", path) return path # Installing clang-tidy on LLVM will be too much of a mess. diff --git a/test/test_char.py b/test/test_char.py index 29a0b857..8f823241 100644 --- a/test/test_char.py +++ b/test/test_char.py @@ -7,8 +7,7 @@ This is ambiguous; compilers can freely choose `signed` or `unsigned` char. import pqclean import pycparser import os -import unittest -import shutil +import helpers def test_char(): @@ -26,9 +25,8 @@ def walk_tree(ast): yield from walk_tree(child) # recursively yield prohibited nodes +@helpers.skip_windows() def check_char(implementation): - if not shutil.which('cpp'): - raise unittest.SkipTest("C pre-processor (cpp) was not found.") errors = [] for fname in os.listdir(implementation.path()): if not fname.endswith(".c"): From dac0d96904f088d8c256a63d3434d534d13ab801 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 10:40:16 +0200 Subject: [PATCH 07/32] We don't use cpp anymore --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1de9ed98..1f54de06 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,6 @@ matrix: - pip3 install -r requirements.txt - export PATH="/usr/local/bin:$PATH" - ln -s /usr/local/Cellar/gcc/8.3.0/bin/gcc-8 /usr/local/bin/gcc - - ln -s /usr/local/Cellar/gcc/8.3.0/bin/cpp-8 /usr/local/bin/cpp - gcc --version script: - "cd test && python3 -m nose --rednose --verbose" From 347217ba137929f51127ea8e427f11d18c02e81b Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 10:42:14 +0200 Subject: [PATCH 08/32] Mention submodules in README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6936d629..c055e9f4 100644 --- a/README.md +++ b/README.md @@ -139,10 +139,16 @@ To do this, make sure the following is installed: * Python 3.5+ * `nosetests` or `nose2` (either for Python 3) +You will also need to make sure the submodules are initialized by running: + +``` +git submodule update --init +``` + Run the Python-based tests by going into the `test` directory and running `nosetests -v` or `nose2 -B -v`, depending on what you installed. If you have the `rednose` plugin for `nosetests` installed, run `nosetests --rednose` to get colored output. -You may also run `python ` where `` is any of the files starting with `test_` in the `test/` folder. +You may also run `python3 ` where `` is any of the files starting with `test_` in the `test/` folder. [circleci-pqc]: https://circleci.com/gh/PQClean/PQClean/ [travis-pqc]: https://travis-ci.com/PQClean/PQClean/ From 13e84aec00d8edf7f962eafafc2932898bd73457 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 10:45:06 +0200 Subject: [PATCH 09/32] Clone submodules in CircleCI --- .circleci/config.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 09a6e8d2..e51c2ab3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -4,6 +4,11 @@ version: 2 machine: true steps: - checkout + - run: + name: Pull submodules + command: | + git submodule init + git submodule update - run: name: Install the emulation handlers command: docker run --rm --privileged multiarch/qemu-user-static:register --reset @@ -20,6 +25,11 @@ version: 2 - image: pqclean/ci-container:$ARCH steps: - checkout + - run: + name: Pull submodules + command: | + git submodule init + git submodule update - run: name: Run tests command: | From 2ffdc863c932a095aa3b5e7af0677ddb0b3498ed Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 11:51:19 +0200 Subject: [PATCH 10/32] Also install requirements in native versions --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index e51c2ab3..c3dc74ec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,7 @@ version: 2 docker run -e CI=true --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c " uname -a && export CC=${CC} && + pip3 install -r requirements.txt cd test && python3 -m nose --rednose --verbose" .native_job: &nativejob From 3d8faae4836011c5ae513f16de5dda83cb7ebdf0 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 5 Apr 2019 12:51:35 +0200 Subject: [PATCH 11/32] Fix missing && separator in docker command string It seems to have worked in CircleCI without this, though; it is unclear to me why. --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c3dc74ec..7db6185c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ version: 2 docker run -e CI=true --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c " uname -a && export CC=${CC} && - pip3 install -r requirements.txt + pip3 install -r requirements.txt && cd test && python3 -m nose --rednose --verbose" .native_job: &nativejob @@ -35,7 +35,7 @@ version: 2 name: Run tests command: | export CC=${CC} - pip3 install -r requirements.txt + pip3 install -r requirements.txt && cd test && python3 -m nose --rednose --verbose From 41edb79c0a234094d477065228f782c36979b226 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 5 Apr 2019 13:04:32 +0200 Subject: [PATCH 12/32] Clarify cc vs cpp --- test/test_char.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_char.py b/test/test_char.py index 8f823241..85bb47ac 100644 --- a/test/test_char.py +++ b/test/test_char.py @@ -35,7 +35,7 @@ def check_char(implementation): ast = pycparser.parse_file( os.path.join(implementation.path(), fname), use_cpp=True, - cpp_path='cc', + cpp_path='cc', # not all platforms link cpp correctly; cc -E works cpp_args=[ '-E', '-std=c99', From eb08730d277f61e0344c35c9e450fb86fb54503a Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 13:38:02 +0200 Subject: [PATCH 13/32] Use brew link to install gcc in a more predictable place --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1f54de06..6d7d3780 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,11 +20,12 @@ matrix: homebrew: packages: - astyle - - gcc + - gcc@8 before_install: - pip3 install -r requirements.txt + - brew link gcc - export PATH="/usr/local/bin:$PATH" - - ln -s /usr/local/Cellar/gcc/8.3.0/bin/gcc-8 /usr/local/bin/gcc + - ln -s /usr/local/bin/gcc-8 /usr/local/bin/gcc - gcc --version script: - "cd test && python3 -m nose --rednose --verbose" From 67ba4b661c863d0801c3b3c6fa92030b7b0743b6 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 5 Apr 2019 15:30:13 +0200 Subject: [PATCH 14/32] Update README based on discussion on integer sizes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c055e9f4..93bfb5e2 100644 --- a/README.md +++ b/README.md @@ -63,15 +63,15 @@ _The checking of items on this list is still being developed. Checked items shou ## Requirements on C implementations that are manually checked -* Makefiles without explicit rules (rely on implicit, built-in rules) +* Minimalist Makefiles * `#ifdef`s only for header encapsulation * No stringification macros * Output-parameter pointers in functions are on the left * `const` arguments are labeled as `const` * All exported symbols are namespaced in place -* All integer types are of fixed size, using `stdint.h` types (including `uint8_t` instead of `unsigned char`) -* Integers used for indexing are of size `size_t` -* variable declarations at the beginning (except in `for (size_t i=...`) +* Integer types are of fixed size where relevant, using `stdint.h` types +* Integers used for indexing memory are of size `size_t` +* Variable declarations at the beginning (except in `for (size_t i=...`) ## Clean C implementations currently in PQClean From 1938f78bf1a83c51e1a3b99af9d50c06d5bd3288 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Wed, 27 Feb 2019 14:55:06 +0100 Subject: [PATCH 15/32] Pull request template draft [ci skip] --- .github/pull_request_template.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..c828dc66 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ + + + + + +## Manually checked properties + + +* [ ] `#ifdef`s only for header encapsulation +* [ ] `api.h` does not include other files +* [ ] No stringification macros +* [ ] Output-parameter pointers in functions are on the left +* [ ] Negative return values on failure of API functions (within restrictions of FO transform). +* [ ] `const` arguments are labeled as `const` +* [ ] (optional) All integer types are of fixed size, using `stdint.h` types (including `uint8_t` instead of `unsigned char`) +* [ ] Integers used for indexing are of size `size_t` +* [ ] variable declarations at the beginning (except in `for (size_t i=...`) From 764935084a48dc5ffb03f7dd7e6c48ef595411ae Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 16:19:29 +0200 Subject: [PATCH 16/32] Update pull_request_template.md --- .github/pull_request_template.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c828dc66..1f6a93c6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,6 +12,7 @@ * [ ] Output-parameter pointers in functions are on the left * [ ] Negative return values on failure of API functions (within restrictions of FO transform). * [ ] `const` arguments are labeled as `const` -* [ ] (optional) All integer types are of fixed size, using `stdint.h` types (including `uint8_t` instead of `unsigned char`) -* [ ] Integers used for indexing are of size `size_t` * [ ] variable declarations at the beginning (except in `for (size_t i=...`) +* Optional: + * [ ] All integer types are of fixed size, using `stdint.h` types (including `uint8_t` instead of `unsigned char`) + * [ ] Integers used for indexing are of size `size_t` From 928b92364e02ac4dd33bc8e91aa35075c8a2ca44 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Wed, 27 Feb 2019 14:15:29 +0100 Subject: [PATCH 17/32] First draft of CONTRIBUTING --- CONTRIBUTING.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 89 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..5978ae0d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,88 @@ +# Contributing new schemes to PQClean + +## Why contribute to PQClean + +PQClean hopes to provide your scheme to people who want to integrate post-quantum cryptography into their own libraries and applications. +But our extensive testing framework might also help you catch bugs in your implementation, that might have otherwise gone unnoticed. +We run our builds on (emulated) ARMv7, ARMv8, x86 and amd64. +Also, we apply static and dynamic analysis tools. + +## Adding your scheme + +For this text, we will assume that you want to contribute a **kem** to PQClean. +For a signature scheme, these steps are equivalent, but the API is slightly different. +See the section [API][#API] below. + +1. Fork our repository. You will be creating a pull request soon. +**Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. +We set up things so Github and the CI environment will give you + +2. Create the following folder structure: `crypto_kem/yourschemename/clean`. +We follow the SUPERCOP layout, so please create a separate folder for each parameter set. +For now, we only accept **pure, portable C code** + +3. Create a ``META.yml`` file in ``crypto_kem/yourschemename/`` following this template: +```yaml +name: Name +type: +claimed-nist-level: +length-public-key: +length-ciphertext: +testvectors-sha256: sha256sum of output of testvectors +principal-submitter: Eve +auxiliary-submitters: + - Alice + - Bob + - ... +implementations: + - name: clean + version: +``` +This file needs to be valid [YAML](https://yaml.org/). + +4. Put your scheme into ``crypto_kem/yourschemename/clean``. + 1. Make sure all symbols are prefixed with ``PQCLEAN_YOURSCHEME_CLEAN_`` + 2. Include ``api.h`` into your scheme with the symbols specified in the section [API][#API]: +5. Create ``Makefile`` and ``Makefile.Microsoft_nmake`` files to compile your scheme as static library. + * We suggest you take these from ``crypto_kem/kyber768/clean`` and modify them to suit your scheme. +6. Add a ``LICENSE`` file to your implementation folder. +7. Commit everything and push it to your fork +8. Open a pull request on our repository and process the feedback given to you by the CI environment. + The pull request will also set up a checklist for you and us to follow. + +## API + +These items should be available in your ``api.h`` file. +Please make sure your ``api.h`` file does not include any other files. + +### KEMs +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk);`` +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk);`` +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk);`` +* ``define`` macros + * ``CRYPTO_SECRETKEYBYTES`` + * ``CRYPTO_PUBLICKEYBYTES`` + * ``CRYPTO_CIPHERTEXTBYTES`` + * ``CRYPTO_BYTES`` + * ``CRYPTO_ALGNAME`` + +### Signature schemes +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk);`` +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(unsigned char *sm, unsigned long long *smlen, const unsigned char *msg, unsigned long long len, const unsigned char *sk);`` +* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long smlen, const unsigned char *pk);`` +* ``define`` macros + * ``CRYPTO_SECRETKEYBYTES`` + * ``CRYPTO_PUBLICKEYBYTES`` + * ``CRYPTO_BYTES`` + * ``CRYPTO_ALGNAME`` + +#### Return codes +Your schemes should return 0 on success, or a negative value on failure. +Notably, ``crypto_sign_open`` should return ``-1`` if signature verification failed. + +# Contributing to the framework of PQClean + +We also welcome contributions to the testing framework. +Open an issue or pull request on Github and we will review your suggestion. +In general, we are always looking to improve the experience of submitters of schemes and of people consuming the implementations collected by this project. +Please do bear in mind the intentions of this project. diff --git a/README.md b/README.md index 93bfb5e2..9ed821b5 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ What PQClean is **not** aiming for is As a first main target, we are collecting C implementations that fulfill the requirements listed below. +Please also review our [guidelines for contributors](CONTRIBUTING.md) if you are interested in adding a scheme to PQClean. ## Requirements on C implementations that are automatically checked From 7d8b12d6bd095102eb53ea867d13c24025f391ad Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Wed, 27 Feb 2019 14:19:51 +0100 Subject: [PATCH 18/32] Syntax typos --- CONTRIBUTING.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5978ae0d..af5c426a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ Also, we apply static and dynamic analysis tools. For this text, we will assume that you want to contribute a **kem** to PQClean. For a signature scheme, these steps are equivalent, but the API is slightly different. -See the section [API][#API] below. +See the section [API](#API) below. 1. Fork our repository. You will be creating a pull request soon. **Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. @@ -41,12 +41,16 @@ implementations: This file needs to be valid [YAML](https://yaml.org/). 4. Put your scheme into ``crypto_kem/yourschemename/clean``. - 1. Make sure all symbols are prefixed with ``PQCLEAN_YOURSCHEME_CLEAN_`` - 2. Include ``api.h`` into your scheme with the symbols specified in the section [API][#API]: + 1. Make sure all symbols are prefixed with ``PQCLEAN_YOURSCHEME_CLEAN_`` + 2. Include ``api.h`` into your scheme with the symbols specified in the section [API](#API): + 5. Create ``Makefile`` and ``Makefile.Microsoft_nmake`` files to compile your scheme as static library. - * We suggest you take these from ``crypto_kem/kyber768/clean`` and modify them to suit your scheme. + * We suggest you take these from ``crypto_kem/kyber768/clean`` and modify them to suit your scheme. + 6. Add a ``LICENSE`` file to your implementation folder. + 7. Commit everything and push it to your fork + 8. Open a pull request on our repository and process the feedback given to you by the CI environment. The pull request will also set up a checklist for you and us to follow. From 658b4f044791e84b7b66ce5e6d7555f4ef428508 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Wed, 27 Feb 2019 14:21:08 +0100 Subject: [PATCH 19/32] Fix unfinished sentence [ci skip] --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index af5c426a..0e20f019 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,8 +14,8 @@ For a signature scheme, these steps are equivalent, but the API is slightly diff See the section [API](#API) below. 1. Fork our repository. You will be creating a pull request soon. -**Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. -We set up things so Github and the CI environment will give you + * **Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. + We set up things so Github and the CI environment will give you feedback and guidance on the steps to follow. 2. Create the following folder structure: `crypto_kem/yourschemename/clean`. We follow the SUPERCOP layout, so please create a separate folder for each parameter set. From cb4eb97bc466393714c5b029326696e9d2baeeaf Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 27 Feb 2019 22:03:41 -0500 Subject: [PATCH 20/32] Markdown formatting changes --- CONTRIBUTING.md | 151 ++++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 68 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e20f019..f07658a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,92 +1,107 @@ -# Contributing new schemes to PQClean +Contributing new schemes to PQClean +=================================== -## Why contribute to PQClean +Why contribute to PQClean +------------------------- -PQClean hopes to provide your scheme to people who want to integrate post-quantum cryptography into their own libraries and applications. -But our extensive testing framework might also help you catch bugs in your implementation, that might have otherwise gone unnoticed. -We run our builds on (emulated) ARMv7, ARMv8, x86 and amd64. -Also, we apply static and dynamic analysis tools. +PQClean hopes to provide your scheme to people who want to integrate post-quantum cryptography into their own libraries and applications. But our extensive testing framework might also help you catch bugs in your implementation, that might have otherwise gone unnoticed. We run our builds on (emulated) ARMv7, ARMv8, x86 and amd64. Also, we apply static and dynamic analysis tools. -## Adding your scheme +Adding your scheme +------------------ -For this text, we will assume that you want to contribute a **kem** to PQClean. -For a signature scheme, these steps are equivalent, but the API is slightly different. +For this text, we will assume that you want to contribute a **key encapsulation mechanism (KEM)** to PQClean. For a signature scheme, these steps are equivalent, but the API is slightly different. See the section [API](#API) below. 1. Fork our repository. You will be creating a pull request soon. - * **Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. - We set up things so Github and the CI environment will give you feedback and guidance on the steps to follow. + * **Tip:** Do not wait until you think you have gotten everything perfect, before you open the pull request. We set up things so Github and the CI environment will give you feedback and guidance on the steps to follow. -2. Create the following folder structure: `crypto_kem/yourschemename/clean`. -We follow the SUPERCOP layout, so please create a separate folder for each parameter set. -For now, we only accept **pure, portable C code** +2. Create the following folder structure: `crypto_kem/yourschemename/clean`. We follow the SUPERCOP layout, so please create a separate folder under `crypto_kem` for each parameter set. -3. Create a ``META.yml`` file in ``crypto_kem/yourschemename/`` following this template: -```yaml -name: Name -type: -claimed-nist-level: -length-public-key: -length-ciphertext: -testvectors-sha256: sha256sum of output of testvectors -principal-submitter: Eve -auxiliary-submitters: - - Alice - - Bob - - ... -implementations: - - name: clean - version: -``` -This file needs to be valid [YAML](https://yaml.org/). + For now, we only accept **pure, portable C code**. Our coding conventions impose certain constraints on the C code -- C99 code, fixed sized integer types (e.g., `uint64_t` rather than `unsigned long long`), and more. See README.md for more information. -4. Put your scheme into ``crypto_kem/yourschemename/clean``. - 1. Make sure all symbols are prefixed with ``PQCLEAN_YOURSCHEME_CLEAN_`` - 2. Include ``api.h`` into your scheme with the symbols specified in the section [API](#API): +3. Create a `META.yml` file in `crypto_kem/yourschemename` following this template: -5. Create ``Makefile`` and ``Makefile.Microsoft_nmake`` files to compile your scheme as static library. - * We suggest you take these from ``crypto_kem/kyber768/clean`` and modify them to suit your scheme. + ```yaml + name: Name + type: + claimed-nist-level: + length-public-key: + length-ciphertext: + testvectors-sha256: sha256sum of output of testvectors + principal-submitter: Eve + auxiliary-submitters: + - Alice + - Bob + - ... + implementations: + - name: clean + version: + ``` -6. Add a ``LICENSE`` file to your implementation folder. + This file needs to be valid [YAML](https://yaml.org/). -7. Commit everything and push it to your fork +4. Put your scheme's C source code into `crypto_kem/yourschemename/clean`. -8. Open a pull request on our repository and process the feedback given to you by the CI environment. - The pull request will also set up a checklist for you and us to follow. + 1. Make sure all symbols are prefixed with `PQCLEAN_YOURSCHEME_CLEAN_`. + 2. Include `api.h` into your scheme with the symbols specified in the section [API](#API). -## API +5. Create `Makefile` and `Makefile.Microsoft_nmake` files to compile your scheme as static library. + * We suggest you copy these from `crypto_kem/kyber768/clean` and modify them to suit your scheme. -These items should be available in your ``api.h`` file. -Please make sure your ``api.h`` file does not include any other files. +6. Add a `LICENSE` file to your implementation folder. + +7. Commit everything and push it to your fork. + +8. Open a pull request on our Github repository and process the feedback given to you by the CI environment. The pull request will also set up a checklist for you and us to follow. Feel free to ask us questions via the pull request. + +API +--- + +These items should be available in your `api.h` file. ### KEMs -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk);`` -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk);`` -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk);`` -* ``define`` macros - * ``CRYPTO_SECRETKEYBYTES`` - * ``CRYPTO_PUBLICKEYBYTES`` - * ``CRYPTO_CIPHERTEXTBYTES`` - * ``CRYPTO_BYTES`` - * ``CRYPTO_ALGNAME`` + +Functions: + +```c +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk); +``` + +`#define` macros: + +* `CRYPTO_SECRETKEYBYTES` +* `CRYPTO_PUBLICKEYBYTES` +* `CRYPTO_CIPHERTEXTBYTES` +* `CRYPTO_BYTES` +* `CRYPTO_ALGNAME` ### Signature schemes -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk);`` -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(unsigned char *sm, unsigned long long *smlen, const unsigned char *msg, unsigned long long len, const unsigned char *sk);`` -* ``int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long smlen, const unsigned char *pk);`` -* ``define`` macros - * ``CRYPTO_SECRETKEYBYTES`` - * ``CRYPTO_PUBLICKEYBYTES`` - * ``CRYPTO_BYTES`` - * ``CRYPTO_ALGNAME`` -#### Return codes +Functions: + +```c +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(unsigned char *sm, unsigned long long *smlen, const unsigned char *msg, unsigned long long len, const unsigned char *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long smlen, const unsigned char *pk); +``` + +`#define` macros: + +* `CRYPTO_SECRETKEYBYTES` +* `CRYPTO_PUBLICKEYBYTES` +* `CRYPTO_BYTES` +* `CRYPTO_ALGNAME` + +Please make sure your `api.h` file does not include any other files. + +### Return codes + Your schemes should return 0 on success, or a negative value on failure. -Notably, ``crypto_sign_open`` should return ``-1`` if signature verification failed. +Notably, `crypto_sign_open` should return `-1` if signature verification failed. -# Contributing to the framework of PQClean +Contributing to the framework of PQClean +======================================== -We also welcome contributions to the testing framework. -Open an issue or pull request on Github and we will review your suggestion. -In general, we are always looking to improve the experience of submitters of schemes and of people consuming the implementations collected by this project. -Please do bear in mind the intentions of this project. +We also welcome contributions to the testing framework. Open an issue or pull request on Github and we will review your suggestion. In general, we are always looking to improve the experience of submitters of schemes and of people consuming the implementations collected by this project. Please do bear in mind the intentions of this project. From e39dec091932b023877d0005dd61dc2665600756 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Thu, 28 Feb 2019 15:13:13 +0100 Subject: [PATCH 21/32] Add powerpc mention and remove intentions statement --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f07658a5..2cf23fb3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ Contributing new schemes to PQClean Why contribute to PQClean ------------------------- -PQClean hopes to provide your scheme to people who want to integrate post-quantum cryptography into their own libraries and applications. But our extensive testing framework might also help you catch bugs in your implementation, that might have otherwise gone unnoticed. We run our builds on (emulated) ARMv7, ARMv8, x86 and amd64. Also, we apply static and dynamic analysis tools. +PQClean hopes to provide your scheme to people who want to integrate post-quantum cryptography into their own libraries and applications. But our extensive testing framework might also help you catch bugs in your implementation, that might have otherwise gone unnoticed. We run our builds on (emulated) ARMv7, ARMv8, 32-bit PowerPC, x86 and amd64. Also, we apply static and dynamic analysis tools. Adding your scheme ------------------ @@ -104,4 +104,4 @@ Notably, `crypto_sign_open` should return `-1` if signature verification failed. Contributing to the framework of PQClean ======================================== -We also welcome contributions to the testing framework. Open an issue or pull request on Github and we will review your suggestion. In general, we are always looking to improve the experience of submitters of schemes and of people consuming the implementations collected by this project. Please do bear in mind the intentions of this project. +We also welcome contributions to the testing framework. Open an issue or pull request on Github and we will review your suggestion. In general, we are always looking to improve the experience of submitters of schemes and of people consuming the implementations collected by this project. From 98a6f2cf3803fba2af8068140640378896129d1f Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Thu, 28 Feb 2019 17:00:57 +0100 Subject: [PATCH 22/32] Add remark about running astyle to contributing See #60 --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2cf23fb3..265c3ef4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,10 @@ See the section [API](#API) below. 1. Make sure all symbols are prefixed with `PQCLEAN_YOURSCHEME_CLEAN_`. 2. Include `api.h` into your scheme with the symbols specified in the section [API](#API). + 3. We use `astyle` to format code. You may consider running the following command on your submission: + ``` + astyle --project crypto_kem/yourschemename/clean/*.[ch] + ``` 5. Create `Makefile` and `Makefile.Microsoft_nmake` files to compile your scheme as static library. * We suggest you copy these from `crypto_kem/kyber768/clean` and modify them to suit your scheme. From c765e5c3504021ea4096fc3e70fae603f8808f00 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Tue, 5 Mar 2019 13:59:36 +0100 Subject: [PATCH 23/32] Specify crypto API as specified in README This means using uint8_t and adding the detached-signature api functions --- CONTRIBUTING.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 265c3ef4..b8534b3e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,9 +68,9 @@ These items should be available in your `api.h` file. Functions: ```c -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); ``` `#define` macros: @@ -86,9 +86,11 @@ int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned ch Functions: ```c -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(unsigned char *pk, unsigned char *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(unsigned char *sm, unsigned long long *smlen, const unsigned char *msg, unsigned long long len, const unsigned char *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(unsigned char *m, unsigned long long *mlen, const unsigned char *sm, unsigned long long smlen, const unsigned char *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(uint8_t *sm, unsigned long long *smlen, const uint8_t *msg, unsigned long long len, const uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(uint8_t *m, unsigned long long *mlen, const uint8_t *sm, unsigned long long smlen, const uint8_t *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); ``` `#define` macros: From 19d177efb3cea70d9a30fb8e12fb269b15852426 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Fri, 5 Apr 2019 10:22:52 -0400 Subject: [PATCH 24/32] Use 5 iteractions for functional tests and test vectors --- crypto_kem/frodokem640shake/META.yml | 2 +- crypto_kem/kyber768/META.yml | 2 +- test/crypto_kem/functest.c | 2 +- test/crypto_kem/testvectors.c | 2 +- test/crypto_sign/functest.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto_kem/frodokem640shake/META.yml b/crypto_kem/frodokem640shake/META.yml index 87c37449..192b4cbc 100644 --- a/crypto_kem/frodokem640shake/META.yml +++ b/crypto_kem/frodokem640shake/META.yml @@ -3,7 +3,7 @@ type: kem claimed-nist-level: 1 length-public-key: 9616 length-ciphertext: 9720 -testvectors-sha256: 521ff891de20efe74e6584d09612dae989427ac76261a41630c4e4d6a4fc78a4 +testvectors-sha256: 8f922de02d41005fcc3c4164b2ab74c4c7b588ed69e34e22607d1ae4ab13d2c5 principal-submitter: Douglas Stebila, University of Waterloo auxiliary-submitters: - Erdem Alkim diff --git a/crypto_kem/kyber768/META.yml b/crypto_kem/kyber768/META.yml index 62d8903e..6bcf2c2c 100644 --- a/crypto_kem/kyber768/META.yml +++ b/crypto_kem/kyber768/META.yml @@ -3,7 +3,7 @@ type: kem claimed-nist-level: 3 length-public-key: 1088 length-ciphertext: 1152 -testvectors-sha256: 0e002ee528febdab1709f100df79ceb00b31a809e03a4fb84e3a72c39235d372 +testvectors-sha256: 2f5cf9937959eb4a3bc910f71e830e9e0de029b28093c6192d2c3e915913016f principal-submitter: Peter Schwabe auxiliary-submitters: - Roberto Avanzi diff --git a/test/crypto_kem/functest.c b/test/crypto_kem/functest.c index 7f50608b..9e04e4a0 100644 --- a/test/crypto_kem/functest.c +++ b/test/crypto_kem/functest.c @@ -5,7 +5,7 @@ #include "api.h" #include "randombytes.h" -#define NTESTS 10 +#define NTESTS 5 const uint8_t canary[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF diff --git a/test/crypto_kem/testvectors.c b/test/crypto_kem/testvectors.c index 516b5886..fb0a6f7c 100644 --- a/test/crypto_kem/testvectors.c +++ b/test/crypto_kem/testvectors.c @@ -6,7 +6,7 @@ #include "api.h" #include "randombytes.h" -#define NTESTS 100 +#define NTESTS 5 static void printbytes(const uint8_t *x, size_t xlen) { size_t i; diff --git a/test/crypto_sign/functest.c b/test/crypto_sign/functest.c index 9fb3a1b9..d49a77ee 100644 --- a/test/crypto_sign/functest.c +++ b/test/crypto_sign/functest.c @@ -6,7 +6,7 @@ #include "api.h" #include "randombytes.h" -#define NTESTS 15 +#define NTESTS 5 #define MLEN 32 const uint8_t canary[8] = { From 004c82c42ef254f389c6140413de1829be240f0b Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 16:29:21 +0200 Subject: [PATCH 25/32] Namespace constants, clean up C API listings --- CONTRIBUTING.md | 56 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8534b3e..5126659d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,14 +19,17 @@ See the section [API](#API) below. For now, we only accept **pure, portable C code**. Our coding conventions impose certain constraints on the C code -- C99 code, fixed sized integer types (e.g., `uint64_t` rather than `unsigned long long`), and more. See README.md for more information. -3. Create a `META.yml` file in `crypto_kem/yourschemename` following this template: +3. Create a `META.yml` file in `crypto_(kem|sign)/yourschemename` following this template: ```yaml name: Name type: claimed-nist-level: - length-public-key: - length-ciphertext: + length-public-key: # KEM and signature + length-secret-key: # KEM and signature + length-ciphertext: # KEM only + length-sharedsecret: # KEM only + length-signature: # Signature only testvectors-sha256: sha256sum of output of testvectors principal-submitter: Eve auxiliary-submitters: @@ -43,11 +46,12 @@ See the section [API](#API) below. 4. Put your scheme's C source code into `crypto_kem/yourschemename/clean`. 1. Make sure all symbols are prefixed with `PQCLEAN_YOURSCHEME_CLEAN_`. - 2. Include `api.h` into your scheme with the symbols specified in the section [API](#API). + 2. Include `api.h` into your scheme with the symbols specified in the section [API](#API). Make sure it does not include other files. 3. We use `astyle` to format code. You may consider running the following command on your submission: ``` astyle --project crypto_kem/yourschemename/clean/*.[ch] ``` + 4. You may run the tests in the `tests/` folder. See the `README` for how to run the test suite. 5. Create `Makefile` and `Makefile.Microsoft_nmake` files to compile your scheme as static library. * We suggest you copy these from `crypto_kem/kyber768/clean` and modify them to suit your scheme. @@ -68,9 +72,12 @@ These items should be available in your `api.h` file. Functions: ```c -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_keypair( + uint8_t *pk, uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_enc( + uint8_t *ct, uint8_t *ss, const uint8_t *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec( + uint8_t *ss, const uint8_t *ct, const uint8_t *sk); ``` `#define` macros: @@ -86,19 +93,36 @@ int PQCLEAN_YOURSCHEME_CLEAN_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, cons Functions: ```c -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair(uint8_t *pk, uint8_t *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign(uint8_t *sm, unsigned long long *smlen, const uint8_t *msg, unsigned long long len, const uint8_t *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open(uint8_t *m, unsigned long long *mlen, const uint8_t *sm, unsigned long long smlen, const uint8_t *pk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, const uint8_t *sk); -int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_keypair( + uint8_t *pk, uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign( + uint8_t *sm, size_t *smlen, + const uint8_t *msg, size_t len, + const uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_open( + uint8_t *m, size_t *mlen, + const uint8_t *sm, size_t smlen, + const uint8_t *pk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_signature( + uint8_t *sig, size_t *siglen, + const uint8_t *m, size_t mlen, + const uint8_t *sk); +int PQCLEAN_YOURSCHEME_CLEAN_crypto_sign_verify( + const uint8_t *sig, size_t siglen, + const uint8_t *m, size_t mlen, + const uint8_t *pk); ``` `#define` macros: -* `CRYPTO_SECRETKEYBYTES` -* `CRYPTO_PUBLICKEYBYTES` -* `CRYPTO_BYTES` -* `CRYPTO_ALGNAME` +* `PQCLEAN_YOURSCHEME_CLEAN_CRYPTO_SECRETKEYBYTES` +* `PQCLEAN_YOURSCHEME_CLEAN_CRYPTO_PUBLICKEYBYTES` +* `PQCLEAN_YOURSCHEME_CLEAN_CRYPTO_ALGNAME` +* `PQCLEAN_YOURSCHEME_CLEAN_CRYPTO_BYTES` + +for KEMs, additionally define: + +* `PQCLEAN_YOURSCHEME_CLEAN_CRYPTO_CIPHERTEXTBYTES` Please make sure your `api.h` file does not include any other files. From f355e77407826d5e40b412b50b3380f9407959e1 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 5 Apr 2019 16:26:27 +0200 Subject: [PATCH 26/32] Clarify and reduce iterations for sig testvectors This is actually different from signature functests, which only tests mlen=32. Can be fixed later as that does not impact the testvectors. --- crypto_sign/dilithium-iii/META.yml | 2 +- test/crypto_sign/testvectors.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto_sign/dilithium-iii/META.yml b/crypto_sign/dilithium-iii/META.yml index 4f207176..13afcb1a 100644 --- a/crypto_sign/dilithium-iii/META.yml +++ b/crypto_sign/dilithium-iii/META.yml @@ -3,7 +3,7 @@ type: signature claimed-nist-level: 3 length-public-key: 1472 length-signature: 2701 -testvectors-sha256: e1852a975842c44a683c914ed131d95bee9b786c36c41e47bb77d7dd3c0c07be +testvectors-sha256: 0d9d7a41b24ab8b250c352fdb50318193f2f66c6c582d7721b785b1a4618b493 principal-submitter: Vadim Lyubashevsky auxiliary-submitters: - Léo Ducas diff --git a/test/crypto_sign/testvectors.c b/test/crypto_sign/testvectors.c index 7cf87cf3..8d35d426 100644 --- a/test/crypto_sign/testvectors.c +++ b/test/crypto_sign/testvectors.c @@ -6,7 +6,6 @@ #include "api.h" #include "randombytes.h" -#define NTESTS 100 #define MAXMLEN 2048 static void printbytes(const uint8_t *x, size_t xlen) { @@ -43,7 +42,8 @@ int main(void) { int r; size_t i, k; - for (i = 0; i < MAXMLEN; i = (i == 0) ? i + 1 : i << 1) { + /* i = 0, 1, 4, 16, 64, 256, 1024 */ + for (i = 0; i < MAXMLEN; i = (i == 0) ? i + 1 : i << 2) { randombytes(mi, i); crypto_sign_keypair(pk, sk); From d39d7c66dbab4fa3497a2b7b9b65a011f308b121 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 16:38:11 +0200 Subject: [PATCH 27/32] Add missing metadata to META --- crypto_kem/frodokem640shake/META.yml | 2 ++ crypto_kem/kyber768/META.yml | 2 ++ crypto_sign/dilithium-iii/META.yml | 1 + test/test_metadata.py | 2 ++ 4 files changed, 7 insertions(+) diff --git a/crypto_kem/frodokem640shake/META.yml b/crypto_kem/frodokem640shake/META.yml index 87c37449..06763cf2 100644 --- a/crypto_kem/frodokem640shake/META.yml +++ b/crypto_kem/frodokem640shake/META.yml @@ -2,7 +2,9 @@ name: FrodoKEM-640-SHAKE type: kem claimed-nist-level: 1 length-public-key: 9616 +length-secret-key: 19888 length-ciphertext: 9720 +length-shared-secret: 16 testvectors-sha256: 521ff891de20efe74e6584d09612dae989427ac76261a41630c4e4d6a4fc78a4 principal-submitter: Douglas Stebila, University of Waterloo auxiliary-submitters: diff --git a/crypto_kem/kyber768/META.yml b/crypto_kem/kyber768/META.yml index 62d8903e..f10bc439 100644 --- a/crypto_kem/kyber768/META.yml +++ b/crypto_kem/kyber768/META.yml @@ -2,7 +2,9 @@ name: Kyber768 type: kem claimed-nist-level: 3 length-public-key: 1088 +length-secret-key: 2400 length-ciphertext: 1152 +length-shared-secret: 32 testvectors-sha256: 0e002ee528febdab1709f100df79ceb00b31a809e03a4fb84e3a72c39235d372 principal-submitter: Peter Schwabe auxiliary-submitters: diff --git a/crypto_sign/dilithium-iii/META.yml b/crypto_sign/dilithium-iii/META.yml index 4f207176..02634b95 100644 --- a/crypto_sign/dilithium-iii/META.yml +++ b/crypto_sign/dilithium-iii/META.yml @@ -2,6 +2,7 @@ name: Dilithium-III type: signature claimed-nist-level: 3 length-public-key: 1472 +length-secret-key: 3504 length-signature: 2701 testvectors-sha256: e1852a975842c44a683c914ed131d95bee9b786c36c41e47bb77d7dd3c0c07be principal-submitter: Vadim Lyubashevsky diff --git a/test/test_metadata.py b/test/test_metadata.py index 71ca7798..ea2b4131 100644 --- a/test/test_metadata.py +++ b/test/test_metadata.py @@ -42,6 +42,7 @@ EXPECTED_FIELDS = { 'type': {'type': str}, 'claimed-nist-level': {'type': int, 'min': 1, 'max': 5}, 'length-public-key': {'type': int, 'min': 1}, + 'length-secret-key': {'type': int, 'min': 1}, 'testvectors-sha256': {'type': str, 'length': 64}, 'principal-submitter': {'type': str}, 'auxiliary-submitters': {'type': list, 'elements': {'type': str}}, @@ -59,6 +60,7 @@ EXPECTED_FIELDS = { KEM_FIELDS = { 'length-ciphertext': {'type': int, 'min': 1}, + 'length-shared-secret': {'type': int, 'min': 1}, } SIGNATURE_FIELDS = { From 1523a5ce479a708d04ea713f507973266ac6ae7e Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 16:38:42 +0200 Subject: [PATCH 28/32] Fix shared-secret in CONTRIBUTING --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5126659d..a9595c44 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ See the section [API](#API) below. length-public-key: # KEM and signature length-secret-key: # KEM and signature length-ciphertext: # KEM only - length-sharedsecret: # KEM only + length-shared-secret: # KEM only length-signature: # Signature only testvectors-sha256: sha256sum of output of testvectors principal-submitter: Eve From d1fd8aa934e8614e6b072fa6751ce65d216113db Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 17:04:37 +0200 Subject: [PATCH 29/32] Check the specified sizes of the metadata match api.h consts Fixes #88 --- test/Makefile | 11 +++++++- test/crypto_kem/printparams.c | 14 ++++++++++ test/crypto_sign/printparams.c | 13 +++++++++ test/test_metadata_sizes.py | 50 ++++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 test/crypto_kem/printparams.c create mode 100644 test/crypto_sign/printparams.c create mode 100644 test/test_metadata_sizes.py diff --git a/test/Makefile b/test/Makefile index e08bb25b..8b938246 100644 --- a/test/Makefile +++ b/test/Makefile @@ -17,7 +17,9 @@ DEST_DIR=../bin # This -Wall was supported by the European Commission through the ERC Starting Grant 805031 (EPOQUE) CFLAGS=-Wall -Wextra -Wpedantic -Werror -Wundef -std=c99 -I$(COMMON_DIR) $(EXTRAFLAGS) -all: $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION) +all: $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) \ + $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION) \ + $(DEST_DIR)/printparams_$(SCHEME)_$(IMPLEMENTATION) .PHONY: build-scheme build-scheme: @@ -33,6 +35,9 @@ functest: $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) .PHONY: testvectors testvectors: $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION) +.PHONY: printparams +printparams: $(DEST_DIR)/printparams_$(SCHEME)_$(IMPLEMENTATION) + $(DEST_DIR)/test_fips202: common/fips202.c $(COMMON_FILES) mkdir -p $(DEST_DIR) $(CC) $(CFLAGS) $< $(COMMON_FILES) -o $@ @@ -49,6 +54,10 @@ $(DEST_DIR)/testvectors_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE) mkdir -p $(DEST_DIR) $(CC) $(CFLAGS) -DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) -I$(SCHEME_DIR) crypto_$(TYPE)/testvectors.c $(COMMON_FILES) $(COMMON_DIR)/notrandombytes.c -o $@ -L$(SCHEME_DIR) -l$(SCHEME)_$(IMPLEMENTATION) +$(DEST_DIR)/printparams_$(SCHEME)_$(IMPLEMENTATION): build-scheme crypto_$(TYPE)/printparams.c + mkdir -p $(DEST_DIR) + $(CC) $(CFLAGS) -DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) -I$(SCHEME_DIR) crypto_$(TYPE)/printparams.c -o $@ + .PHONY: clean clean: $(RM) $(DEST_DIR)/functest_$(SCHEME)_$(IMPLEMENTATION) diff --git a/test/crypto_kem/printparams.c b/test/crypto_kem/printparams.c new file mode 100644 index 00000000..925b2119 --- /dev/null +++ b/test/crypto_kem/printparams.c @@ -0,0 +1,14 @@ +#include +#include "api.h" + +#define PASTER(x, y) x##_##y +#define EVALUATOR(x, y) PASTER(x, y) +#define NAMESPACE(fun) EVALUATOR(PQCLEAN_NAMESPACE, fun) + +int main() { + printf("{\n"); + printf("\t\"CRYPTO_SECRETKEYBYTES\": %u,\n", NAMESPACE(CRYPTO_SECRETKEYBYTES)); + printf("\t\"CRYPTO_PUBLICKEYBYTES\": %u,\n", NAMESPACE(CRYPTO_PUBLICKEYBYTES)); + printf("\t\"CRYPTO_CIPHERTEXTBYTES\": %u,\n", NAMESPACE(CRYPTO_CIPHERTEXTBYTES)); + printf("\t\"CRYPTO_BYTES\": %u\n}\n", NAMESPACE(CRYPTO_BYTES)); +} diff --git a/test/crypto_sign/printparams.c b/test/crypto_sign/printparams.c new file mode 100644 index 00000000..8c38767c --- /dev/null +++ b/test/crypto_sign/printparams.c @@ -0,0 +1,13 @@ +#include +#include "api.h" + +#define PASTER(x, y) x##_##y +#define EVALUATOR(x, y) PASTER(x, y) +#define NAMESPACE(fun) EVALUATOR(PQCLEAN_NAMESPACE, fun) + +int main() { + printf("{\n"); + printf("\t\"CRYPTO_SECRETKEYBYTES\": %u,\n", NAMESPACE(CRYPTO_SECRETKEYBYTES)); + printf("\t\"CRYPTO_PUBLICKEYBYTES\": %u,\n", NAMESPACE(CRYPTO_PUBLICKEYBYTES)); + printf("\t\"CRYPTO_BYTES\": %u\n}\n", NAMESPACE(CRYPTO_BYTES)); +} diff --git a/test/test_metadata_sizes.py b/test/test_metadata_sizes.py new file mode 100644 index 00000000..dc1dfacb --- /dev/null +++ b/test/test_metadata_sizes.py @@ -0,0 +1,50 @@ +import json +import os + +import pqclean +import helpers + + +def test_metadata_sizes(): + for scheme in pqclean.Scheme.all_schemes(): + for implementation in scheme.implementations: + yield check_metadata_sizes, implementation + + +def check_metadata_sizes(implementation): + metadata = implementation.scheme.metadata() + helpers.make('printparams', + TYPE=implementation.scheme.type, + SCHEME=implementation.scheme.name, + IMPLEMENTATION=implementation.name, + working_dir=os.path.join('..', 'test')) + + out = helpers.run_subprocess( + [os.path.join('..', 'bin', 'printparams_{}_{}{}'.format( + implementation.scheme.name, + implementation.name, + '.exe' if os.name == 'nt' else '' + ))], + os.path.join('..', 'bin'), + ).replace('\r', '') + + parsed = json.loads(out) + + assert parsed['CRYPTO_SECRETKEYBYTES'] == metadata['length-secret-key'] + assert parsed['CRYPTO_PUBLICKEYBYTES'] == metadata['length-public-key'] + + if implementation.scheme.type == 'kem': + assert ( + parsed['CRYPTO_CIPHERTEXTBYTES'] == metadata['length-ciphertext']) + assert parsed['CRYPTO_BYTES'] == metadata['length-shared-secret'] + else: + assert parsed['CRYPTO_BYTES'] == metadata['length-signature'] + + +if __name__ == '__main__': + try: + import nose2 + nose2.main() + except ImportError: + import nose + nose.runmodule() From 1e9defd09076594689092c27b0df4b9d61cd9123 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Fri, 5 Apr 2019 17:21:56 +0200 Subject: [PATCH 30/32] build printparams on Windows --- test/Makefile.Microsoft_nmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/Makefile.Microsoft_nmake b/test/Makefile.Microsoft_nmake index 21afb364..9b3661e4 100644 --- a/test/Makefile.Microsoft_nmake +++ b/test/Makefile.Microsoft_nmake @@ -35,6 +35,8 @@ functest: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe testvectors: $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe +printparams: $(DEST_DIR)\printparams_$(SCHEME)_$(IMPLEMENTATION).exe + $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj -MKDIR $(DEST_DIR) -DEL functest.obj @@ -47,7 +49,13 @@ $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_O $(CC) /c crypto_$(TYPE)\testvectors.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) LINK.EXE /OUT:$@ testvectors.obj $(COMMON_OBJECTS_NOPATH) notrandombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib +$(DEST_DIR)\printparams_$(SCHEME)_$(IMPLEMENTATION).exe: crypto_$(TYPE)\printparams.c $(SCHEME_DIR)\api.h + -MKDIR $(DEST_DIR) + -DEL printparams.obj + $(CC) /c crypto_$(TYPE)\printparams.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) + LINK.EXE /OUT:$@ printparams.obj + clean: - -DEL functest.obj testvectors.obj + -DEL functest.obj testvectors.obj printparams.obj -DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj -DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe From 73f40e4147f78dba3390305ea4ce1c25467bb09d Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 5 Apr 2019 17:53:30 +0200 Subject: [PATCH 31/32] Allow TODO without username / bug numbers --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 11453622..d141fd9f 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,5 +1,5 @@ --- -Checks: '*,-llvm-header-guard,-hicpp-*,-readability-function-size,-google-readability-todo-,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-readability-isolate-declaration' +Checks: '*,-llvm-header-guard,-hicpp-*,-readability-function-size,-google-readability-todo,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-readability-isolate-declaration' WarningsAsErrors: '*' HeaderFilterRegex: '.*' AnalyzeTemporaryDtors: false From d113b45cf0014d48bbe35de009ca0c1c25496abb Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Sat, 6 Apr 2019 14:45:05 +0200 Subject: [PATCH 32/32] Fix font size of pull request template header The previous header size was a bit excessive, overshadowing actual comments. --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 1f6a93c6..70f289f1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -3,7 +3,7 @@ -## Manually checked properties +#### Manually checked properties * [ ] `#ifdef`s only for header encapsulation