Browse Source

Merge branch 'master' into reduce-iterations

tags/v0.0.1
Joost Rijneveld 5 years ago
committed by GitHub
parent
commit
e2fcad2823
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 260 additions and 3 deletions
  1. +1
    -1
      .clang-tidy
  2. +18
    -0
      .github/pull_request_template.md
  3. +137
    -0
      CONTRIBUTING.md
  4. +1
    -0
      README.md
  5. +2
    -0
      crypto_kem/frodokem640shake/META.yml
  6. +2
    -0
      crypto_kem/kyber768/META.yml
  7. +1
    -0
      crypto_sign/dilithium-iii/META.yml
  8. +10
    -1
      test/Makefile
  9. +9
    -1
      test/Makefile.Microsoft_nmake
  10. +14
    -0
      test/crypto_kem/printparams.c
  11. +13
    -0
      test/crypto_sign/printparams.c
  12. +2
    -0
      test/test_metadata.py
  13. +50
    -0
      test/test_metadata_sizes.py

+ 1
- 1
.clang-tidy View File

@@ -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


+ 18
- 0
.github/pull_request_template.md View File

@@ -0,0 +1,18 @@
<!-- This template will help you get your code into PQClean. -->

<!-- Type some lines about your submission -->


## Manually checked properties
<!-- These checkboxes serve for the maintainers of PQClean to verify your submission. Please do not check them yourself. -->

* [ ] `#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`
* [ ] 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`

+ 137
- 0
CONTRIBUTING.md View File

@@ -0,0 +1,137 @@
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, 32-bit PowerPC, 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 **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.

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.

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|sign)/yourschemename` following this template:

```yaml
name: Name
type: <kem|signature>
claimed-nist-level: <N>
length-public-key: <N> # KEM and signature
length-secret-key: <N> # KEM and signature
length-ciphertext: <N> # KEM only
length-shared-secret: <N> # KEM only
length-signature: <N> # Signature only
testvectors-sha256: sha256sum of output of testvectors
principal-submitter: Eve
auxiliary-submitters:
- Alice
- Bob
- ...
implementations:
- name: clean
version: <some version indicator>
```

This file needs to be valid [YAML](https://yaml.org/).

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). 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.

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

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);
```

`#define` macros:

* `CRYPTO_SECRETKEYBYTES`
* `CRYPTO_PUBLICKEYBYTES`
* `CRYPTO_CIPHERTEXTBYTES`
* `CRYPTO_BYTES`
* `CRYPTO_ALGNAME`

### Signature schemes

Functions:

```c
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:

* `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.

### 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.

+ 1
- 0
README.md View File

@@ -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



+ 2
- 0
crypto_kem/frodokem640shake/META.yml View File

@@ -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: 8f922de02d41005fcc3c4164b2ab74c4c7b588ed69e34e22607d1ae4ab13d2c5
principal-submitter: Douglas Stebila, University of Waterloo
auxiliary-submitters:


+ 2
- 0
crypto_kem/kyber768/META.yml View File

@@ -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: 2f5cf9937959eb4a3bc910f71e830e9e0de029b28093c6192d2c3e915913016f
principal-submitter: Peter Schwabe
auxiliary-submitters:


+ 1
- 0
crypto_sign/dilithium-iii/META.yml View File

@@ -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: 0d9d7a41b24ab8b250c352fdb50318193f2f66c6c582d7721b785b1a4618b493
principal-submitter: Vadim Lyubashevsky


+ 10
- 1
test/Makefile View File

@@ -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)


+ 9
- 1
test/Makefile.Microsoft_nmake View File

@@ -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

+ 14
- 0
test/crypto_kem/printparams.c View File

@@ -0,0 +1,14 @@
#include <stdio.h>
#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));
}

+ 13
- 0
test/crypto_sign/printparams.c View File

@@ -0,0 +1,13 @@
#include <stdio.h>
#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));
}

+ 2
- 0
test/test_metadata.py View File

@@ -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 = {


+ 50
- 0
test/test_metadata_sizes.py View File

@@ -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()

Loading…
Cancel
Save