Merge pull request #96 from PQClean/test_preprocessor

Test for preprocessor conditionals
This commit is contained in:
Joost Rijneveld 2019-04-09 18:02:27 +02:00 committed by GitHub
commit 7540971a8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 56 deletions

View File

@ -6,7 +6,6 @@
#### Manually checked properties
<!-- These checkboxes serve for the maintainers of PQClean to verify your submission. Please do not check them yourself. -->
* [ ] `#if`/`#ifdef`s only for header encapsulation
* [ ] 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).

View File

@ -36,6 +36,7 @@ _The checking of items on this list is still being developed. Checked items shou
* [x] API functions do not write outside provided buffers
* [x] `api.h` cannot include external files
* [x] Compiles with `-Wall -Wextra -Wpedantic -Werror` with `gcc` and `clang`
* [x] `#if`/`#ifdef`s only for header encapsulation
* [x] Consistent test vectors across runs
* [x] Consistent test vectors on big-endian and little-endian machines
* [x] Consistent test vectors on 32-bit and 64-bit machines
@ -66,7 +67,6 @@ _The checking of items on this list is still being developed. Checked items shou
## Requirements on C implementations that are manually checked
* Minimalist Makefiles
* `#if`/`#ifdef`s only for header encapsulation
* No stringification macros
* Output-parameter pointers in functions are on the left
* `const` arguments are labeled as `const`

View File

@ -32,32 +32,6 @@ static uint64_t load_littleendian(const unsigned char *x, int bytes) {
* - const unsigned char *buf: pointer to input byte array
**************************************************/
void PQCLEAN_KYBER768_CLEAN_cbd(poly *r, const unsigned char *buf) {
#if KYBER_ETA == 3
uint32_t t, d, a[4], b[4];
int i, j;
for (i = 0; i < KYBER_N / 4; i++) {
t = (uint32_t)load_littleendian(buf + 3 * i, 3);
d = 0;
for (j = 0; j < 3; j++) {
d += (t >> j) & 0x249249;
}
a[0] = d & 0x7;
b[0] = (d >> 3) & 0x7;
a[1] = (d >> 6) & 0x7;
b[1] = (d >> 9) & 0x7;
a[2] = (d >> 12) & 0x7;
b[2] = (d >> 15) & 0x7;
a[3] = (d >> 18) & 0x7;
b[3] = (d >> 21);
r->coeffs[4 * i + 0] = (uint16_t)(a[0] + KYBER_Q - b[0]);
r->coeffs[4 * i + 1] = (uint16_t)(a[1] + KYBER_Q - b[1]);
r->coeffs[4 * i + 2] = (uint16_t)(a[2] + KYBER_Q - b[2]);
r->coeffs[4 * i + 3] = (uint16_t)(a[3] + KYBER_Q - b[3]);
}
#elif KYBER_ETA == 4
uint32_t t, d, a[4], b[4];
int i, j;
@ -82,32 +56,4 @@ void PQCLEAN_KYBER768_CLEAN_cbd(poly *r, const unsigned char *buf) {
r->coeffs[4 * i + 2] = (uint16_t)(a[2] + KYBER_Q - b[2]);
r->coeffs[4 * i + 3] = (uint16_t)(a[3] + KYBER_Q - b[3]);
}
#elif KYBER_ETA == 5
uint64_t t, d, a[4], b[4];
int i, j;
for (i = 0; i < KYBER_N / 4; i++) {
t = load_littleendian(buf + 5 * i, 5);
d = 0;
for (j = 0; j < 5; j++) {
d += (t >> j) & 0x0842108421UL;
}
a[0] = d & 0x1f;
b[0] = (d >> 5) & 0x1f;
a[1] = (d >> 10) & 0x1f;
b[1] = (d >> 15) & 0x1f;
a[2] = (d >> 20) & 0x1f;
b[2] = (d >> 25) & 0x1f;
a[3] = (d >> 30) & 0x1f;
b[3] = (d >> 35);
r->coeffs[4 * i + 0] = (uint16_t)(a[0] + KYBER_Q - b[0]);
r->coeffs[4 * i + 1] = (uint16_t)(a[1] + KYBER_Q - b[1]);
r->coeffs[4 * i + 2] = (uint16_t)(a[2] + KYBER_Q - b[2]);
r->coeffs[4 * i + 3] = (uint16_t)(a[3] + KYBER_Q - b[3]);
}
#else
#error "poly_getnoise in poly.c only supports eta in {3,4,5}"
#endif
}

37
test/test_preprocessor.py Normal file
View File

@ -0,0 +1,37 @@
import os
from glob import glob
import pqclean
from helpers import run_subprocess, ensure_available
def test_preprocessor():
for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations:
yield check_preprocessor, implementation
def check_preprocessor(implementation: pqclean.Implementation):
cfiles = implementation.cfiles()
hfiles = implementation.hfiles()
errors = []
for file in hfiles + cfiles:
with open(file) as f:
for i, line in enumerate(f):
line = line.strip()
if file in hfiles and i == 0 and line.startswith('#ifndef'):
continue
if line.startswith('#if'):
errors.append("\n at {}:{}".format(file, i+1))
if errors:
raise AssertionError(
"Prohibited use of preprocessor conditional" + "".join(errors)
)
if __name__ == "__main__":
try:
import nose2
nose2.main()
except ImportError:
import nose
nose.runmodule()