mirror of
https://github.com/henrydcase/pqc.git
synced 2024-11-26 09:21:28 +00:00
commit
8f347af262
@ -10,6 +10,5 @@
|
|||||||
--add-braces
|
--add-braces
|
||||||
--convert-tabs
|
--convert-tabs
|
||||||
--mode=c
|
--mode=c
|
||||||
--lineend=linux
|
|
||||||
# disable backup files
|
# disable backup files
|
||||||
--suffix=none
|
--suffix=none
|
||||||
|
@ -10,7 +10,7 @@ version: 2
|
|||||||
- run:
|
- run:
|
||||||
name: Run the tests in a container
|
name: Run the tests in a container
|
||||||
command: |
|
command: |
|
||||||
docker run --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c "
|
docker run -e CI=true --rm -v `pwd`:`pwd` -w `pwd` "pqclean/ci-container:$ARCH" /bin/bash -c "
|
||||||
uname -a &&
|
uname -a &&
|
||||||
export CC=${CC} &&
|
export CC=${CC} &&
|
||||||
cd test && python3 -m nose --rednose --verbose"
|
cd test && python3 -m nose --rednose --verbose"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
Checks: '*,-llvm-header-guard,-hicpp-*,-readability-function-size'
|
Checks: '*,-llvm-header-guard,-hicpp-*,-readability-function-size,-google-readability-todo'
|
||||||
WarningsAsErrors: '*'
|
WarningsAsErrors: '*'
|
||||||
HeaderFilterRegex: '.*'
|
HeaderFilterRegex: '.*'
|
||||||
AnalyzeTemporaryDtors: false
|
AnalyzeTemporaryDtors: false
|
||||||
|
19
appveyor.yml
19
appveyor.yml
@ -5,8 +5,23 @@ image: Visual Studio 2017
|
|||||||
build:
|
build:
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
|
|
||||||
|
environment:
|
||||||
|
matrix:
|
||||||
|
- BITS: 64
|
||||||
|
- BITS: 32
|
||||||
|
|
||||||
init:
|
init:
|
||||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
|
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars%BITS%.bat"
|
||||||
|
# Download AStyle 3.1: first enable strong crypto in Invoke-WebRequest
|
||||||
|
- ps: Set-ItemProperty -Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319" -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
|
||||||
|
- ps: Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319" -Name "SchUseStrongCrypto" -Value '1' -Type DWord
|
||||||
|
# Add Python to PATH
|
||||||
|
- set PATH="C:\\Python37";"C:\\Python37\Scripts";%PATH%
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- scripts_windows\build_all.bat
|
- python -m pip install -r requirements.txt
|
||||||
|
- cd test
|
||||||
|
# Download Astyle to local folder because putting it in PATH doesn't work
|
||||||
|
- ps: Invoke-WebRequest -OutFile "astyle.exe" "https://rded.nl/pqclean/AStyle.exe"
|
||||||
|
# Run tests
|
||||||
|
- python -m nose -v --rednose
|
||||||
|
@ -33,6 +33,7 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
/* Windows */
|
/* Windows */
|
||||||
|
// NOLINTNEXTLINE(llvm-include-order): Include order required by Windows
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
|
#include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
|
||||||
#endif /* defined(_WIN32) */
|
#endif /* defined(_WIN32) */
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
||||||
# nmake /f Makefile.Microsoft_nmake
|
# nmake /f Makefile.Microsoft_nmake
|
||||||
|
|
||||||
LIB=libkyber768_clean.lib
|
LIBRARY=libkyber768_clean.lib
|
||||||
OBJECTS=cbd.obj indcpa.obj kem.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj
|
OBJECTS=cbd.obj indcpa.obj kem.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj
|
||||||
|
|
||||||
CFLAGS=/I ..\..\..\common /W4 /WX
|
CFLAGS=/nologo /I ..\..\..\common /W4 /WX
|
||||||
|
|
||||||
all: $(LIB)
|
all: $(LIBRARY)
|
||||||
|
|
||||||
$(LIB): $(OBJECTS)
|
# Make sure objects are recompiled if headers change.
|
||||||
LIB.EXE /OUT:$@ $**
|
$(OBJECTS): *.h
|
||||||
|
|
||||||
|
$(LIBRARY): $(OBJECTS)
|
||||||
|
LIB.EXE /NOLOGO /WX /OUT:$@ $**
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
DEL $(OBJECTS)
|
-DEL $(OBJECTS)
|
||||||
DEL $(LIB)
|
-DEL $(LIBRARY)
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
||||||
# nmake /f Makefile.Microsoft_nmake
|
# nmake /f Makefile.Microsoft_nmake
|
||||||
|
|
||||||
LIB=libdilithium-iii_clean.lib
|
LIBRARY=libdilithium-iii_clean.lib
|
||||||
OBJECTS=ntt.obj packing.obj poly.obj polyvec.obj reduce.obj rounding.obj sign.obj
|
OBJECTS=ntt.obj packing.obj poly.obj polyvec.obj reduce.obj rounding.obj sign.obj
|
||||||
|
|
||||||
CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Dilithium right now
|
CFLAGS=/nologo /I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Dilithium right now
|
||||||
|
|
||||||
all: $(LIB)
|
all: $(LIBRARY)
|
||||||
|
|
||||||
$(LIB): $(OBJECTS)
|
# Make sure objects are recompiled if headers change.
|
||||||
LIB.EXE /OUT:$@ $**
|
$(OBJECTS): *.h
|
||||||
|
|
||||||
|
$(LIBRARY): $(OBJECTS)
|
||||||
|
LIB.EXE /NOLOGO /WX /OUT:$@ $**
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
DEL $(OBJECTS)
|
-DEL $(OBJECTS)
|
||||||
DEL $(LIB)
|
-DEL $(LIBRARY)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#ifndef API_H
|
#ifndef API_H
|
||||||
|
#include <stdint.h>
|
||||||
#define API_H
|
#define API_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
@ECHO OFF
|
|
||||||
SETLOCAL EnableDelayedExpansion
|
|
||||||
SET EL=0
|
|
||||||
|
|
||||||
REM CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
|
|
||||||
REM IF ERRORLEVEL 1 SET EL=1
|
|
||||||
|
|
||||||
:: Build the library files for individual implementations
|
|
||||||
FOR /D %%K IN (crypto_kem\* crypto_sign\*) DO (
|
|
||||||
FOR /D %%L IN (%%K\*) DO (
|
|
||||||
CD %%L
|
|
||||||
nmake /f Makefile.Microsoft_nmake clean
|
|
||||||
IF ERRORLEVEL 1 SET EL=2
|
|
||||||
nmake /f Makefile.Microsoft_nmake
|
|
||||||
IF ERRORLEVEL 1 SET EL=3
|
|
||||||
CD ..\..\..
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Build and run the functional tests and test vector programs for each implementation
|
|
||||||
FOR %%T IN (kem sign) DO (
|
|
||||||
CD crypto_%%T
|
|
||||||
FOR /D %%K IN (*) DO (
|
|
||||||
SET schemeuppercase=%%K
|
|
||||||
FOR %%B IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO SET "schemeuppercase=!schemeuppercase:%%B=%%B!"
|
|
||||||
SET "schemeuppercase=!schemeuppercase:-=!"
|
|
||||||
CD %%K
|
|
||||||
FOR /D %%L IN (*) DO (
|
|
||||||
CD ..\..\test
|
|
||||||
nmake /f Makefile.Microsoft_nmake /E TYPE=%%T SCHEME=%%K SCHEME_UPPERCASE=!schemeuppercase! IMPLEMENTATION=%%L clean
|
|
||||||
IF ERRORLEVEL 1 SET EL=4
|
|
||||||
nmake /f Makefile.Microsoft_nmake /E TYPE=%%T SCHEME=%%K SCHEME_UPPERCASE=!schemeuppercase! IMPLEMENTATION=%%L
|
|
||||||
IF ERRORLEVEL 1 SET EL=5
|
|
||||||
CD ..
|
|
||||||
bin\functest_%%K_%%L
|
|
||||||
IF ERRORLEVEL 1 SET EL=6
|
|
||||||
CD crypto_%%T\%%K
|
|
||||||
)
|
|
||||||
CD ..
|
|
||||||
)
|
|
||||||
CD ..
|
|
||||||
)
|
|
||||||
|
|
||||||
EXIT /b %EL%
|
|
@ -1,7 +1,7 @@
|
|||||||
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
||||||
# nmake /f Makefile.Microsoft_nmake
|
# nmake /f Makefile.Microsoft_nmake
|
||||||
|
|
||||||
# override as desired
|
# override as desired, use /E
|
||||||
# vim: set ts=4 sw=4 et:
|
# vim: set ts=4 sw=4 et:
|
||||||
TYPE=kem
|
TYPE=kem
|
||||||
SCHEME=kyber768
|
SCHEME=kyber768
|
||||||
@ -17,7 +17,7 @@ COMMON_OBJECTS_NOPATH=fips202.obj sha2.obj
|
|||||||
|
|
||||||
DEST_DIR=..\bin
|
DEST_DIR=..\bin
|
||||||
|
|
||||||
CFLAGS=/I $(COMMON_DIR) /W4 /WX
|
CFLAGS=/nologo /I $(COMMON_DIR) /W4 /WX
|
||||||
|
|
||||||
all: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).EXE
|
all: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).EXE
|
||||||
|
|
||||||
@ -31,17 +31,23 @@ clean-scheme:
|
|||||||
nmake /f Makefile.Microsoft_nmake clean
|
nmake /f Makefile.Microsoft_nmake clean
|
||||||
cd ..\..\..\test
|
cd ..\..\..\test
|
||||||
|
|
||||||
$(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj
|
functest: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe
|
||||||
|
|
||||||
|
testvectors: $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe
|
||||||
|
|
||||||
|
$(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj
|
||||||
-MKDIR $(DEST_DIR)
|
-MKDIR $(DEST_DIR)
|
||||||
|
-DEL functest.obj
|
||||||
$(CC) /c crypto_$(TYPE)\functest.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE)
|
$(CC) /c crypto_$(TYPE)\functest.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE)
|
||||||
LINK.EXE /OUT:$@ functest.obj $(COMMON_OBJECTS_NOPATH) randombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib Advapi32.lib
|
LINK.EXE /OUT:$@ functest.obj $(COMMON_OBJECTS_NOPATH) randombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib Advapi32.lib
|
||||||
|
|
||||||
$(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).EXE: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\notrandombytes.obj
|
$(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\notrandombytes.obj
|
||||||
-MKDIR $(DEST_DIR)
|
-MKDIR $(DEST_DIR)
|
||||||
|
-DEL testvectors.obj
|
||||||
$(CC) /c crypto_$(TYPE)\testvectors.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE)
|
$(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
|
LINK.EXE /OUT:$@ testvectors.obj $(COMMON_OBJECTS_NOPATH) notrandombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-DEL functest.obj testvectors.obj
|
-DEL functest.obj testvectors.obj
|
||||||
-DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj
|
-DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj
|
||||||
-DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE
|
-DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe
|
||||||
|
@ -98,9 +98,9 @@ static int test_sign(void) {
|
|||||||
// twice
|
// twice
|
||||||
if ((returncode =
|
if ((returncode =
|
||||||
crypto_sign_open(sm + 8, &mlen, sm + 8, smlen, pk + 8)) != 0) {
|
crypto_sign_open(sm + 8, &mlen, sm + 8, smlen, pk + 8)) != 0) {
|
||||||
printf("ERROR Signature did not verify correctly!\n");
|
fprintf(stderr, "ERROR Signature did not verify correctly!\n");
|
||||||
if (returncode > 0) {
|
if (returncode > 0) {
|
||||||
puts("ERROR return code should be < 0 on failure");
|
fprintf(stderr, "ERROR return code should be < 0 on failure");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ static int test_sign(void) {
|
|||||||
check_canary(sk) || check_canary(sk + CRYPTO_SECRETKEYBYTES + 8) ||
|
check_canary(sk) || check_canary(sk + CRYPTO_SECRETKEYBYTES + 8) ||
|
||||||
check_canary(sm) || check_canary(sm + MLEN + CRYPTO_BYTES + 8) ||
|
check_canary(sm) || check_canary(sm + MLEN + CRYPTO_BYTES + 8) ||
|
||||||
check_canary(m) || check_canary(m + MLEN + 8)) {
|
check_canary(m) || check_canary(m + MLEN + 8)) {
|
||||||
printf("ERROR canary overwritten\n");
|
fprintf(stderr, "ERROR canary overwritten\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,9 +143,9 @@ static int test_wrong_pk(void) {
|
|||||||
// twice
|
// twice
|
||||||
returncode = crypto_sign_open(sm, &mlen, sm, smlen, pk2);
|
returncode = crypto_sign_open(sm, &mlen, sm, smlen, pk2);
|
||||||
if (!returncode) {
|
if (!returncode) {
|
||||||
printf("ERROR Signature did verify correctly under wrong public key!\n");
|
fprintf(stderr, "ERROR Signature did verify correctly under wrong public key!\n");
|
||||||
if (returncode > 0) {
|
if (returncode > 0) {
|
||||||
puts("ERROR return code should be < 0");
|
fprintf(stderr, "ERROR return code should be < 0");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ int main(void) {
|
|||||||
|
|
||||||
uint8_t mi[MAXMLEN];
|
uint8_t mi[MAXMLEN];
|
||||||
uint8_t sm[MAXMLEN + CRYPTO_BYTES];
|
uint8_t sm[MAXMLEN + CRYPTO_BYTES];
|
||||||
|
|
||||||
size_t smlen;
|
size_t smlen;
|
||||||
size_t mlen;
|
size_t mlen;
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
import functools
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import unittest
|
||||||
|
import shutil
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
|
def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
|
||||||
@ -15,6 +19,7 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
|
|||||||
# Note we need to capture stdout/stderr from the subprocess,
|
# Note we need to capture stdout/stderr from the subprocess,
|
||||||
# then print it, which nose/unittest will then capture and
|
# then print it, which nose/unittest will then capture and
|
||||||
# buffer appropriately
|
# buffer appropriately
|
||||||
|
print(working_dir + " > " + " ".join(command))
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
command,
|
command,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
@ -22,26 +27,74 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
|
|||||||
cwd=working_dir,
|
cwd=working_dir,
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
print(working_dir + " > " + " ".join(command))
|
|
||||||
print(result.stdout.decode('utf-8'))
|
print(result.stdout.decode('utf-8'))
|
||||||
assert(result.returncode == expected_returncode)
|
assert result.returncode == expected_returncode, \
|
||||||
|
"Got unexpected return code {}".format(result.returncode)
|
||||||
return result.stdout.decode('utf-8')
|
return result.stdout.decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
def make(*args, working_dir='.', env=None, **kwargs):
|
def make(*args, working_dir='.', env=None, expected_returncode=0, **kwargs):
|
||||||
"""
|
"""
|
||||||
Runs a make target in the specified working directory
|
Runs a make target in the specified working directory
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
make('clean', 'targetb', SCHEME='bla')
|
make('clean', 'targetb', SCHEME='bla')
|
||||||
"""
|
"""
|
||||||
make_command = 'make'
|
if os.name == 'nt':
|
||||||
|
make_command = ['nmake', '/f', 'Makefile.Microsoft_nmake',
|
||||||
|
'/NOLOGO', '/E']
|
||||||
|
# we need SCHEME_UPPERCASE and IMPLEMENTATION_UPPERCASE with nmake
|
||||||
|
for envvar in ['IMPLEMENTATION', 'SCHEME']:
|
||||||
|
if envvar in kwargs:
|
||||||
|
kwargs['{}_UPPERCASE'.format(envvar)] = (
|
||||||
|
kwargs[envvar].upper().replace('-', ''))
|
||||||
|
else:
|
||||||
|
make_command = ['make']
|
||||||
|
|
||||||
return run_subprocess(
|
return run_subprocess(
|
||||||
[
|
[
|
||||||
make_command,
|
*make_command,
|
||||||
*args,
|
|
||||||
*['{}={}'.format(k, v) for k, v in kwargs.items()],
|
*['{}={}'.format(k, v) for k, v in kwargs.items()],
|
||||||
|
*args,
|
||||||
],
|
],
|
||||||
working_dir=working_dir,
|
working_dir=working_dir,
|
||||||
env=env,
|
env=env,
|
||||||
|
expected_returncode=expected_returncode,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def skip_windows(message="This test is not supported on Windows"):
|
||||||
|
def wrapper(f):
|
||||||
|
@functools.wraps(f)
|
||||||
|
def skip_windows(*args, **kwargs):
|
||||||
|
raise unittest.SkipTest(message)
|
||||||
|
if os.name == 'nt':
|
||||||
|
return skip_windows
|
||||||
|
else:
|
||||||
|
return f
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_available(executable):
|
||||||
|
"""
|
||||||
|
Checks if a command is available.
|
||||||
|
|
||||||
|
If a command MUST be available, because we are in a CI environment,
|
||||||
|
raises an AssertionError.
|
||||||
|
|
||||||
|
In the docker containers, on Travis and on Windows, CI=true is set.
|
||||||
|
"""
|
||||||
|
path = shutil.which(executable)
|
||||||
|
if path:
|
||||||
|
print("Found", path)
|
||||||
|
return path
|
||||||
|
|
||||||
|
# Installing clang-tidy on LLVM will be too much of a mess.
|
||||||
|
if ((executable == 'clang-tidy' and sys.platform == 'darwin')
|
||||||
|
or 'CI' not in os.environ):
|
||||||
|
raise unittest.SkipTest(
|
||||||
|
"{} is not available on PATH. Install it to run this test.{}"
|
||||||
|
.format(executable, "" if not os.name == 'nt'
|
||||||
|
else "On Windows, make sure to add it to PATH")
|
||||||
|
)
|
||||||
|
raise AssertionError("{} not available on CI".format(executable))
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import glob
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
|
||||||
@ -73,8 +74,20 @@ class Implementation:
|
|||||||
return os.path.join(self.scheme.path(), self.name)
|
return os.path.join(self.scheme.path(), self.name)
|
||||||
|
|
||||||
def libname(self) -> str:
|
def libname(self) -> str:
|
||||||
|
if os.name == 'nt':
|
||||||
|
return "lib{}_{}.lib".format(self.scheme.name, self.name)
|
||||||
return "lib{}_{}.a".format(self.scheme.name, self.name)
|
return "lib{}_{}.a".format(self.scheme.name, self.name)
|
||||||
|
|
||||||
|
def cfiles(self) -> [str]:
|
||||||
|
return glob.glob(os.path.join(self.path(), '*.c'))
|
||||||
|
|
||||||
|
def hfiles(self) -> [str]:
|
||||||
|
return glob.glob(os.path.join(self.path(), '*.h'))
|
||||||
|
|
||||||
|
def ofiles(self) -> [str]:
|
||||||
|
return glob.glob(os.path.join(self.path(),
|
||||||
|
'*.o' if os.name != 'nt' else '*.obj'))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def by_name(scheme_name, implementation_name):
|
def by_name(scheme_name, implementation_name):
|
||||||
scheme = Scheme.by_name(scheme_name)
|
scheme = Scheme.by_name(scheme_name)
|
||||||
|
@ -9,8 +9,6 @@ import unittest
|
|||||||
|
|
||||||
|
|
||||||
def test_dynamic_memory():
|
def test_dynamic_memory():
|
||||||
if sys.platform not in ['linux', 'darwin']:
|
|
||||||
raise unittest.SkipTest()
|
|
||||||
for scheme in pqclean.Scheme.all_schemes():
|
for scheme in pqclean.Scheme.all_schemes():
|
||||||
for implementation in scheme.implementations:
|
for implementation in scheme.implementations:
|
||||||
# Keep this loop outside, to allow multiple assertions
|
# Keep this loop outside, to allow multiple assertions
|
||||||
@ -18,6 +16,7 @@ def test_dynamic_memory():
|
|||||||
yield (check_dynamic_memory, implementation, function)
|
yield (check_dynamic_memory, implementation, function)
|
||||||
|
|
||||||
|
|
||||||
|
@helpers.skip_windows()
|
||||||
def check_dynamic_memory(implementation, function):
|
def check_dynamic_memory(implementation, function):
|
||||||
# 'make' will take care of not rebuilding existing library files
|
# 'make' will take care of not rebuilding existing library files
|
||||||
helpers.make(working_dir=implementation.path())
|
helpers.make(working_dir=implementation.path())
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import os
|
|
||||||
from glob import glob
|
|
||||||
|
|
||||||
import pqclean
|
import pqclean
|
||||||
from helpers import run_subprocess
|
from helpers import run_subprocess, ensure_available
|
||||||
|
|
||||||
|
|
||||||
def test_formatting():
|
def test_formatting():
|
||||||
@ -12,8 +9,9 @@ def test_formatting():
|
|||||||
|
|
||||||
|
|
||||||
def check_format(implementation: pqclean.Implementation):
|
def check_format(implementation: pqclean.Implementation):
|
||||||
cfiles = glob(os.path.join(implementation.path(), '*.c'))
|
ensure_available('astyle')
|
||||||
hfiles = glob(os.path.join(implementation.path(), '*.h'))
|
cfiles = implementation.cfiles()
|
||||||
|
hfiles = implementation.hfiles()
|
||||||
run_subprocess(['astyle',
|
run_subprocess(['astyle',
|
||||||
'--dry-run',
|
'--dry-run',
|
||||||
'--options=../.astylerc',
|
'--options=../.astylerc',
|
||||||
|
@ -24,25 +24,32 @@ def test_functest_sanitizers():
|
|||||||
|
|
||||||
|
|
||||||
def check_functest(implementation):
|
def check_functest(implementation):
|
||||||
helpers.make(TYPE=implementation.scheme.type,
|
helpers.make('functest',
|
||||||
|
TYPE=implementation.scheme.type,
|
||||||
SCHEME=implementation.scheme.name,
|
SCHEME=implementation.scheme.name,
|
||||||
IMPLEMENTATION=implementation.name,
|
IMPLEMENTATION=implementation.name,
|
||||||
working_dir=os.path.join('..', 'test'))
|
working_dir=os.path.join('..', 'test'))
|
||||||
helpers.run_subprocess(
|
helpers.run_subprocess(
|
||||||
['./functest_{}_{}'.format(implementation.scheme.name,
|
[os.path.join('..', 'bin', 'functest_{}_{}{}'.format(
|
||||||
implementation.name)],
|
implementation.scheme.name,
|
||||||
|
implementation.name,
|
||||||
|
'.exe' if os.name == 'nt' else ''
|
||||||
|
))],
|
||||||
os.path.join('..', 'bin'),
|
os.path.join('..', 'bin'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@helpers.skip_windows
|
||||||
def check_functest_sanitizers(implementation):
|
def check_functest_sanitizers(implementation):
|
||||||
env = None
|
env = None
|
||||||
if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang':
|
if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang':
|
||||||
raise unittest.SkipTest()
|
raise unittest.SkipTest("Clang does not support ASAN on ppc")
|
||||||
elif platform.machine() in ['armv7l', 'aarch64']:
|
elif platform.machine() in ['armv7l', 'aarch64']:
|
||||||
env = {'ASAN_OPTIONS': 'detect_leaks=0'}
|
env = {'ASAN_OPTIONS': 'detect_leaks=0'}
|
||||||
else:
|
else:
|
||||||
print("Supported platform: {}".format(platform.machine()))
|
print("Supported platform: {}".format(platform.machine()))
|
||||||
|
|
||||||
|
helpers.ensure_available('valgrind')
|
||||||
helpers.make('clean-scheme', 'functest',
|
helpers.make('clean-scheme', 'functest',
|
||||||
TYPE=implementation.scheme.type,
|
TYPE=implementation.scheme.type,
|
||||||
SCHEME=implementation.scheme.name,
|
SCHEME=implementation.scheme.name,
|
||||||
@ -51,8 +58,11 @@ def check_functest_sanitizers(implementation):
|
|||||||
working_dir=os.path.join('..', 'test'),
|
working_dir=os.path.join('..', 'test'),
|
||||||
env=env)
|
env=env)
|
||||||
helpers.run_subprocess(
|
helpers.run_subprocess(
|
||||||
['./functest_{}_{}'.format(implementation.scheme.name,
|
[os.path.join('..', 'bin', 'functest_{}_{}{}'.format(
|
||||||
implementation.name)],
|
implementation.scheme.name,
|
||||||
|
implementation.name,
|
||||||
|
'.exe' if os.name == 'nt' else ''
|
||||||
|
))],
|
||||||
os.path.join('..', 'bin'),
|
os.path.join('..', 'bin'),
|
||||||
env=env,
|
env=env,
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
from glob import glob
|
from glob import glob
|
||||||
import shutil
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
import pqclean
|
import pqclean
|
||||||
from helpers import run_subprocess
|
from helpers import run_subprocess, ensure_available
|
||||||
|
|
||||||
|
|
||||||
def test_clang_tidy():
|
def test_clang_tidy():
|
||||||
@ -14,8 +12,7 @@ def test_clang_tidy():
|
|||||||
|
|
||||||
|
|
||||||
def check_tidy(implementation: pqclean.Implementation):
|
def check_tidy(implementation: pqclean.Implementation):
|
||||||
if shutil.which('clang-tidy') is None:
|
ensure_available('clang-tidy')
|
||||||
raise unittest.SkipTest("clang-tidy unavailable in PATH")
|
|
||||||
cfiles = glob(os.path.join(implementation.path(), '*.c'))
|
cfiles = glob(os.path.join(implementation.path(), '*.c'))
|
||||||
common_files = glob(os.path.join('..', 'common', '*.c'))
|
common_files = glob(os.path.join('..', 'common', '*.c'))
|
||||||
run_subprocess(['clang-tidy',
|
run_subprocess(['clang-tidy',
|
||||||
|
@ -19,41 +19,51 @@ def test_makefile_dependencies():
|
|||||||
# test case for each candidate file
|
# test case for each candidate file
|
||||||
cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
|
cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
|
||||||
hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
|
hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
|
||||||
for file in cfiles + hfiles:
|
for file in (cfiles + hfiles):
|
||||||
yield (check_makefile_dependencies, implementation, file)
|
yield (check_makefile_dependencies, implementation, file)
|
||||||
|
|
||||||
|
|
||||||
|
def touch(time, *files):
|
||||||
|
for path in files:
|
||||||
|
times = (time.timestamp(), time.timestamp())
|
||||||
|
os.utime(path, times)
|
||||||
|
|
||||||
|
|
||||||
|
def make_check(path, expect_error=False):
|
||||||
|
makeflag = '-q' if os.name != 'nt' else '/Q'
|
||||||
|
expected_returncode = 0
|
||||||
|
if expect_error:
|
||||||
|
expected_returncode = 1 if os.name != 'nt' else 255
|
||||||
|
helpers.make(makeflag, working_dir=path,
|
||||||
|
expected_returncode=expected_returncode)
|
||||||
|
|
||||||
|
|
||||||
def check_makefile_dependencies(implementation, file):
|
def check_makefile_dependencies(implementation, file):
|
||||||
cfiles = glob.glob(os.path.join(implementation.path(), '*.c'))
|
cfiles = implementation.cfiles()
|
||||||
hfiles = glob.glob(os.path.join(implementation.path(), '*.h'))
|
hfiles = implementation.hfiles()
|
||||||
ofiles = glob.glob(os.path.join(implementation.path(), '*.o'))
|
ofiles = implementation.ofiles()
|
||||||
|
|
||||||
libfile = os.path.join(implementation.path(), implementation.libname())
|
libfile = os.path.join(implementation.path(), implementation.libname())
|
||||||
|
|
||||||
# modification time-based calculations is tricky on a sub-second basis
|
# modification time-based calculations is tricky on a sub-second basis
|
||||||
# so we reset all the modification times to a known and "sensible" order
|
# so we reset all the modification times to a known and "sensible" order
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now() - datetime.timedelta(seconds=10)
|
||||||
ago15 = now - datetime.timedelta(seconds=15)
|
ago15 = now - datetime.timedelta(minutes=15)
|
||||||
ago10 = now - datetime.timedelta(seconds=10)
|
ago10 = now - datetime.timedelta(minutes=10)
|
||||||
ago5 = now - datetime.timedelta(seconds=5)
|
ago5 = now - datetime.timedelta(minutes=5)
|
||||||
formatstring = "%Y%m%d%H%M.%S"
|
|
||||||
helpers.run_subprocess(
|
touch(ago15, *cfiles, *hfiles)
|
||||||
['touch', '-t', ago15.strftime(formatstring)] + cfiles + hfiles)
|
touch(ago10, *ofiles)
|
||||||
helpers.run_subprocess(
|
touch(ago5, libfile)
|
||||||
['touch', '-t', ago10.strftime(formatstring)] + ofiles)
|
|
||||||
helpers.run_subprocess(
|
|
||||||
['touch', '-t', ago5.strftime(formatstring), libfile])
|
|
||||||
|
|
||||||
# Sanity check: the scheme is up to date
|
# Sanity check: the scheme is up to date
|
||||||
helpers.run_subprocess(['make', '-q'], implementation.path(),
|
make_check(implementation.path())
|
||||||
expected_returncode=0)
|
|
||||||
|
|
||||||
# touch the candidate .c / .h file
|
# touch the candidate .c / .h file
|
||||||
helpers.run_subprocess(['touch', '-t', now.strftime(formatstring), file])
|
touch(now, file)
|
||||||
|
|
||||||
# check if it needs to be rebuilt using make -q
|
# check if it needs to be rebuilt using make -q
|
||||||
helpers.run_subprocess(['make', '-q'], implementation.path(),
|
make_check(implementation.path(), expect_error=True)
|
||||||
expected_returncode=1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -23,7 +23,7 @@ def check_metadata(scheme):
|
|||||||
specification = itertools.chain(specification,
|
specification = itertools.chain(specification,
|
||||||
SIGNATURE_FIELDS.items())
|
SIGNATURE_FIELDS.items())
|
||||||
else:
|
else:
|
||||||
assert(False)
|
assert False, "Wrong type of metadata"
|
||||||
|
|
||||||
check_spec(copy.deepcopy(metadata), specification)
|
check_spec(copy.deepcopy(metadata), specification)
|
||||||
|
|
||||||
|
@ -10,18 +10,17 @@ import unittest
|
|||||||
|
|
||||||
|
|
||||||
def test_symbol_namespace():
|
def test_symbol_namespace():
|
||||||
if sys.platform not in ['linux', 'darwin']:
|
|
||||||
raise unittest.SkipTest()
|
|
||||||
for scheme in pqclean.Scheme.all_schemes():
|
for scheme in pqclean.Scheme.all_schemes():
|
||||||
for implementation in scheme.implementations:
|
for implementation in scheme.implementations:
|
||||||
yield check_symbol_namespace, implementation
|
yield check_symbol_namespace, implementation
|
||||||
|
|
||||||
|
|
||||||
def check_symbol_namespace(implementation):
|
def check_symbol_namespace(implementation):
|
||||||
|
if sys.platform not in ['linux', 'darwin']:
|
||||||
|
raise unittest.SkipTest("Unsupported platform")
|
||||||
helpers.make(working_dir=implementation.path())
|
helpers.make(working_dir=implementation.path())
|
||||||
out = helpers.run_subprocess(
|
out = helpers.run_subprocess(
|
||||||
['nm', '-g', 'lib{}_{}.a'.format(implementation.scheme.name,
|
['nm', '-g', implementation.libname()],
|
||||||
implementation.name)],
|
|
||||||
implementation.path()
|
implementation.path()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,15 +16,19 @@ def test_testvectors():
|
|||||||
|
|
||||||
|
|
||||||
def check_vectors(implementation):
|
def check_vectors(implementation):
|
||||||
helpers.make(TYPE=implementation.scheme.type,
|
helpers.make('testvectors',
|
||||||
|
TYPE=implementation.scheme.type,
|
||||||
SCHEME=implementation.scheme.name,
|
SCHEME=implementation.scheme.name,
|
||||||
IMPLEMENTATION=implementation.name,
|
IMPLEMENTATION=implementation.name,
|
||||||
working_dir=os.path.join('..', 'test'))
|
working_dir=os.path.join('..', 'test'))
|
||||||
out = helpers.run_subprocess(
|
out = helpers.run_subprocess(
|
||||||
['./testvectors_{}_{}'.format(implementation.scheme.name,
|
[os.path.join('..', 'bin', 'testvectors_{}_{}{}'.format(
|
||||||
implementation.name)],
|
implementation.scheme.name,
|
||||||
|
implementation.name,
|
||||||
|
'.exe' if os.name == 'nt' else ''
|
||||||
|
))],
|
||||||
os.path.join('..', 'bin'),
|
os.path.join('..', 'bin'),
|
||||||
)
|
).replace('\r', '')
|
||||||
assert(implementation.scheme.metadata()['testvectors-sha256'].lower()
|
assert(implementation.scheme.metadata()['testvectors-sha256'].lower()
|
||||||
== hashlib.sha256(out.encode('utf-8')).hexdigest().lower())
|
== hashlib.sha256(out.encode('utf-8')).hexdigest().lower())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user