Merge pull request #96 from PQClean/test_preprocessor
Test for preprocessor conditionals
This commit is contained in:
commit
7540971a8b
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
@ -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).
|
||||
|
@ -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`
|
||||
|
@ -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
37
test/test_preprocessor.py
Normal 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()
|
Loading…
Reference in New Issue
Block a user