mirror of
https://github.com/henrydcase/pqc.git
synced 2024-11-22 15:39:07 +00:00
Merge branch 'master' into make-dilithium
This commit is contained in:
commit
f1f0c1d332
39
.travis.yml
39
.travis.yml
@ -4,47 +4,58 @@ dist: xenial
|
|||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- name: "Linux + GCC + Linting + Metadata"
|
||||||
|
os: linux
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
env:
|
env:
|
||||||
- MAKETARGET="test-all tidy-all check-format check-metadata check-license-files"
|
- MAKETARGET="test-all tidy-all check-format check-metadata check-license-files"
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- valgrind
|
|
||||||
- python3
|
- python3
|
||||||
- python3-setuptools
|
- python3-yaml
|
||||||
- python3-pip
|
- valgrind
|
||||||
- os: linux
|
- name: "Linux + Clang"
|
||||||
|
os: linux
|
||||||
compiler: clang
|
compiler: clang
|
||||||
env:
|
env:
|
||||||
- MAKETARGET=test-all
|
- MAKETARGET=test-all
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- valgrind
|
|
||||||
- python3
|
- python3
|
||||||
- python3-setuptools
|
- python3-yaml
|
||||||
- python3-pip
|
- valgrind
|
||||||
- os: osx
|
- name: "Run tests on qemu-ppc"
|
||||||
|
os: linux
|
||||||
|
services: docker
|
||||||
|
env:
|
||||||
|
- MAKETARGET="run-functest-all run-testvectors-all run-sanitizer-all run-symbol-namespace-all"
|
||||||
|
script: # TODO: should we do this in a Dockerfile instead?
|
||||||
|
- docker run --rm --privileged multiarch/qemu-user-static:register --reset
|
||||||
|
- docker run --rm -v `pwd`:`pwd` -w `pwd` "twiggers/debian-sid-powerpc" /bin/bash -c "uname -a &&
|
||||||
|
make ${MAKETARGET}"
|
||||||
|
- name: "MacOS + Clang"
|
||||||
|
os: osx
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.1
|
||||||
compiler: clang
|
compiler: clang
|
||||||
|
before_install:
|
||||||
|
- pip3 install -r requirements.txt
|
||||||
env:
|
env:
|
||||||
- MAKETARGET=test-all
|
- MAKETARGET=test-all
|
||||||
- os: osx
|
- name: "MacOS + GCC8"
|
||||||
|
os: osx
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.1
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
addons:
|
addons:
|
||||||
homebrew:
|
homebrew:
|
||||||
packages:
|
packages:
|
||||||
- gcc@8
|
- gcc@8
|
||||||
|
before_install:
|
||||||
|
- pip3 install -r requirements.txt
|
||||||
env:
|
env:
|
||||||
- MAKETARGET=test-all
|
- MAKETARGET=test-all
|
||||||
|
|
||||||
before_install:
|
|
||||||
- python3 --version
|
|
||||||
- pip3 install -r requirements.txt
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- make ${MAKETARGET}
|
- make ${MAKETARGET}
|
||||||
|
|
||||||
|
11
Makefile
11
Makefile
@ -2,6 +2,8 @@
|
|||||||
CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -g $(EXTRAFLAGS)
|
CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -g $(EXTRAFLAGS)
|
||||||
|
|
||||||
ALL_SCHEMES=$(filter-out crypto_%.c, $(wildcard crypto_*/*))
|
ALL_SCHEMES=$(filter-out crypto_%.c, $(wildcard crypto_*/*))
|
||||||
|
COMMON_FILES = common/fips202.c common/sha2.c
|
||||||
|
RANDOM_IMPL = common/randombytes.c
|
||||||
|
|
||||||
default: help
|
default: help
|
||||||
|
|
||||||
@ -19,8 +21,9 @@ bin/functest_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))functest.c $(wildcard
|
|||||||
-iquote "./common/" \
|
-iquote "./common/" \
|
||||||
-iquote "$(SCHEME)/clean/" \
|
-iquote "$(SCHEME)/clean/" \
|
||||||
-o bin/functest_$(subst /,_,$(SCHEME)) \
|
-o bin/functest_$(subst /,_,$(SCHEME)) \
|
||||||
common/*.c \
|
|
||||||
$(SCHEME)/clean/*.c \
|
$(SCHEME)/clean/*.c \
|
||||||
|
$(COMMON_FILES) \
|
||||||
|
$(RANDOM_IMPL) \
|
||||||
$<
|
$<
|
||||||
|
|
||||||
.PHONY: functest
|
.PHONY: functest
|
||||||
@ -45,7 +48,8 @@ bin/sanitizer_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))functest.c $(wildcard
|
|||||||
-iquote "./common/" \
|
-iquote "./common/" \
|
||||||
-iquote "$(SCHEME)/clean/" \
|
-iquote "$(SCHEME)/clean/" \
|
||||||
-o bin/sanitizer_$(subst /,_,$(SCHEME)) \
|
-o bin/sanitizer_$(subst /,_,$(SCHEME)) \
|
||||||
common/*.c \
|
$(COMMON_FILES) \
|
||||||
|
$(RANDOM_IMPL) \
|
||||||
$(SCHEME)/clean/*.c \
|
$(SCHEME)/clean/*.c \
|
||||||
$<
|
$<
|
||||||
|
|
||||||
@ -59,7 +63,8 @@ bin/testvectors_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))testvectors.c $(wil
|
|||||||
-iquote "./common/" \
|
-iquote "./common/" \
|
||||||
-iquote "$(SCHEME)/clean/" \
|
-iquote "$(SCHEME)/clean/" \
|
||||||
-o bin/testvectors_$(subst /,_,$(SCHEME)) \
|
-o bin/testvectors_$(subst /,_,$(SCHEME)) \
|
||||||
common/*.c \
|
$(COMMON_FILES) \
|
||||||
|
common/notrandombytes.c \
|
||||||
$(SCHEME)/clean/*.c \
|
$(SCHEME)/clean/*.c \
|
||||||
$<
|
$<
|
||||||
|
|
||||||
|
12
README.md
12
README.md
@ -4,9 +4,9 @@
|
|||||||
[![Build status](https://ci.appveyor.com/api/projects/status/186ky7yb9mlqj3io?svg=true)](https://ci.appveyor.com/project/PQClean/pqclean)
|
[![Build status](https://ci.appveyor.com/api/projects/status/186ky7yb9mlqj3io?svg=true)](https://ci.appveyor.com/project/PQClean/pqclean)
|
||||||
|
|
||||||
**PQClean**, in short, is an effort to collect **clean** implementations of the post-quantum
|
**PQClean**, in short, is an effort to collect **clean** implementations of the post-quantum
|
||||||
schemes that are in the
|
schemes that are in the
|
||||||
[NIST post-quantum project](https://csrc.nist.gov/projects/post-quantum-cryptography).
|
[NIST post-quantum project](https://csrc.nist.gov/projects/post-quantum-cryptography).
|
||||||
The goal of PQClean is to provide *standalone implementations* that
|
The goal of PQClean is to provide *standalone implementations* that
|
||||||
|
|
||||||
* can easily be integrated into libraries such as [liboqs](https://openquantumsafe.org/#liboqs) or [libpqcrypto](https://libpqcrypto.org/);
|
* can easily be integrated into libraries such as [liboqs](https://openquantumsafe.org/#liboqs) or [libpqcrypto](https://libpqcrypto.org/);
|
||||||
* can efficiently upstream into higher-level protocol integration efforts such as [Open Quantum Safe](https://openquantumsafe.org/#integrations);
|
* can efficiently upstream into higher-level protocol integration efforts such as [Open Quantum Safe](https://openquantumsafe.org/#integrations);
|
||||||
@ -23,7 +23,7 @@ What PQClean is **not** aiming for is
|
|||||||
* including integration into higher-level applications or protocols.
|
* including integration into higher-level applications or protocols.
|
||||||
|
|
||||||
As a first main target, we are collecting C implementations that fulfill the requirements
|
As a first main target, we are collecting C implementations that fulfill the requirements
|
||||||
listed below.
|
listed below.
|
||||||
|
|
||||||
## Requirements on C implementations that are automatically checked
|
## Requirements on C implementations that are automatically checked
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ _The checking of items on this list is still being developed. Checked items shou
|
|||||||
|
|
||||||
## Clean C implementations currently in PQClean
|
## Clean C implementations currently in PQClean
|
||||||
|
|
||||||
Currently, the continuous-integration and testing environment of PQClean is still work in progress
|
Currently, the continuous-integration and testing environment of PQClean is still work in progress
|
||||||
and as a consequence PQClean does not yet have many implementations.
|
and as a consequence PQClean does not yet have many implementations.
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@ -94,7 +94,7 @@ and as a consequence PQClean does not yet have many implementations.
|
|||||||
|
|
||||||
## API used by PQClean
|
## API used by PQClean
|
||||||
|
|
||||||
PQClean is essentially using the same API as required for the NIST reference implementations,
|
PQClean is essentially using the same API as required for the NIST reference implementations,
|
||||||
which is also used by SUPERCOP and by libpqcrypto. The only two differences to that API are
|
which is also used by SUPERCOP and by libpqcrypto. The only two differences to that API are
|
||||||
the following:
|
the following:
|
||||||
* All lengths are passed as type `size_t` instead of `unsigned long long`; and
|
* All lengths are passed as type `size_t` instead of `unsigned long long`; and
|
||||||
@ -121,7 +121,7 @@ Each implementation directory in PQClean (e.g., crypto\_kem/kyber768\clean) can
|
|||||||
|
|
||||||
Regarding #2, adding the files to your project's build system, each implementation in PQClean is accompanied by example two makefiles that show how one could build the files for that implementation:
|
Regarding #2, adding the files to your project's build system, each implementation in PQClean is accompanied by example two makefiles that show how one could build the files for that implementation:
|
||||||
|
|
||||||
- The file `GNUmakefile` which can be used with GNU Make.
|
- The file `Makefile` which can be used with GNU Make, BSD Make, and possibly others.
|
||||||
- The file `Makefile.Microsoft_nmake` which can be used with Visual Studio's nmake.
|
- The file `Makefile.Microsoft_nmake` which can be used with Visual Studio's nmake.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
@ -56,7 +56,7 @@ static void surf(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void randombytes(uint8_t *x, uint64_t xlen) {
|
int randombytes(uint8_t *buf, size_t xlen) {
|
||||||
while (xlen > 0) {
|
while (xlen > 0) {
|
||||||
if (!outleft) {
|
if (!outleft) {
|
||||||
if (!++in[0]) {
|
if (!++in[0]) {
|
||||||
@ -69,8 +69,9 @@ void randombytes(uint8_t *x, uint64_t xlen) {
|
|||||||
surf();
|
surf();
|
||||||
outleft = 8;
|
outleft = 8;
|
||||||
}
|
}
|
||||||
*x = out[--outleft];
|
*buf = out[--outleft];
|
||||||
++x;
|
++buf;
|
||||||
--xlen;
|
--xlen;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
323
common/randombytes.c
Normal file
323
common/randombytes.c
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017 Daan Sprenkels <hello@dsprenkels.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// In the case that are compiling on linux, we need to define _GNU_SOURCE
|
||||||
|
// *before* randombytes.h is included. Otherwise SYS_getrandom will not be
|
||||||
|
// declared.
|
||||||
|
#if defined(__linux__)
|
||||||
|
# define _GNU_SOURCE
|
||||||
|
#endif /* defined(__linux__) */
|
||||||
|
|
||||||
|
#include "randombytes.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
/* Windows */
|
||||||
|
# include <windows.h>
|
||||||
|
# include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
|
||||||
|
#endif /* defined(_WIN32) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
/* Linux */
|
||||||
|
// We would need to include <linux/random.h>, but not every target has access
|
||||||
|
// to the linux headers. We only need RNDGETENTCNT, so we instead inline it.
|
||||||
|
// RNDGETENTCNT is originally defined in `include/uapi/linux/random.h` in the
|
||||||
|
// linux repo.
|
||||||
|
# define RNDGETENTCNT 0x80045200
|
||||||
|
|
||||||
|
# include <assert.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <fcntl.h>
|
||||||
|
# include <poll.h>
|
||||||
|
# include <stdint.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# include <sys/syscall.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
|
||||||
|
// We need SSIZE_MAX as the maximum read len from /dev/urandom
|
||||||
|
# if !defined(SSIZE_MAX)
|
||||||
|
# define SSIZE_MAX (SIZE_MAX / 2 - 1)
|
||||||
|
# endif /* defined(SSIZE_MAX) */
|
||||||
|
|
||||||
|
#endif /* defined(__linux__) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||||
|
/* Dragonfly, FreeBSD, NetBSD, OpenBSD (has arc4random) */
|
||||||
|
# include <sys/param.h>
|
||||||
|
# if defined(BSD)
|
||||||
|
# include <stdlib.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
# include <assert.h>
|
||||||
|
# include <emscripten.h>
|
||||||
|
# include <errno.h>
|
||||||
|
# include <stdbool.h>
|
||||||
|
#endif /* defined(__EMSCRIPTEN__) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static int randombytes_win32_randombytes(void* buf, const size_t n)
|
||||||
|
{
|
||||||
|
HCRYPTPROV ctx;
|
||||||
|
BOOL tmp;
|
||||||
|
|
||||||
|
tmp = CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL,
|
||||||
|
CRYPT_VERIFYCONTEXT);
|
||||||
|
if (tmp == FALSE) return -1;
|
||||||
|
|
||||||
|
tmp = CryptGenRandom(ctx, n, (BYTE*) buf);
|
||||||
|
if (tmp == FALSE) return -1;
|
||||||
|
|
||||||
|
tmp = CryptReleaseContext(ctx, 0);
|
||||||
|
if (tmp == FALSE) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(_WIN32) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__linux__) && defined(SYS_getrandom)
|
||||||
|
static int randombytes_linux_randombytes_getrandom(void *buf, size_t n)
|
||||||
|
{
|
||||||
|
/* I have thought about using a separate PRF, seeded by getrandom, but
|
||||||
|
* it turns out that the performance of getrandom is good enough
|
||||||
|
* (250 MB/s on my laptop).
|
||||||
|
*/
|
||||||
|
size_t offset = 0, chunk;
|
||||||
|
int ret;
|
||||||
|
while (n > 0) {
|
||||||
|
/* getrandom does not allow chunks larger than 33554431 */
|
||||||
|
chunk = n <= 33554431 ? n : 33554431;
|
||||||
|
do {
|
||||||
|
ret = syscall(SYS_getrandom, (char *)buf + offset, chunk, 0);
|
||||||
|
} while (ret == -1 && errno == EINTR);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
offset += ret;
|
||||||
|
n -= ret;
|
||||||
|
}
|
||||||
|
assert(n == 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(__linux__) && defined(SYS_getrandom) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__linux__) && !defined(SYS_getrandom)
|
||||||
|
static int randombytes_linux_read_entropy_ioctl(int device, int *entropy)
|
||||||
|
{
|
||||||
|
return ioctl(device, RNDGETENTCNT, entropy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int randombytes_linux_read_entropy_proc(FILE *stream, int *entropy)
|
||||||
|
{
|
||||||
|
int retcode;
|
||||||
|
do {
|
||||||
|
rewind(stream);
|
||||||
|
retcode = fscanf(stream, "%d", entropy);
|
||||||
|
} while (retcode != 1 && errno == EINTR);
|
||||||
|
if (retcode != 1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int randombytes_linux_wait_for_entropy(int device)
|
||||||
|
{
|
||||||
|
/* We will block on /dev/random, because any increase in the OS' entropy
|
||||||
|
* level will unblock the request. I use poll here (as does libsodium),
|
||||||
|
* because we don't *actually* want to read from the device. */
|
||||||
|
enum { IOCTL, PROC } strategy = IOCTL;
|
||||||
|
const int bits = 128;
|
||||||
|
struct pollfd pfd;
|
||||||
|
int fd;
|
||||||
|
FILE *proc_file;
|
||||||
|
int retcode, retcode_error = 0; // Used as return codes throughout this function
|
||||||
|
int entropy = 0;
|
||||||
|
|
||||||
|
/* If the device has enough entropy already, we will want to return early */
|
||||||
|
retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
|
||||||
|
if (retcode != 0 && errno == ENOTTY) {
|
||||||
|
/* The ioctl call on /dev/urandom has failed due to a ENOTTY (i.e.
|
||||||
|
* unsupported action). We will fall back to reading from
|
||||||
|
* `/proc/sys/kernel/random/entropy_avail`. This is obviously less
|
||||||
|
* ideal, but at this point it seems we have no better option. */
|
||||||
|
strategy = PROC;
|
||||||
|
// Open the entropy count file
|
||||||
|
proc_file = fopen("/proc/sys/kernel/random/entropy_avail", "r");
|
||||||
|
} else if (retcode != 0) {
|
||||||
|
// Unrecoverable ioctl error
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (entropy >= bits) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
fd = open("/dev/random", O_RDONLY);
|
||||||
|
} while (fd == -1 && errno == EINTR); /* EAGAIN will not occur */
|
||||||
|
if (fd == -1) {
|
||||||
|
/* Unrecoverable IO error */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pfd.fd = fd;
|
||||||
|
pfd.events = POLLIN;
|
||||||
|
for (;;) {
|
||||||
|
retcode = poll(&pfd, 1, -1);
|
||||||
|
if (retcode == -1 && (errno == EINTR || errno == EAGAIN)) {
|
||||||
|
continue;
|
||||||
|
} else if (retcode == 1) {
|
||||||
|
if (strategy == IOCTL) {
|
||||||
|
retcode = randombytes_linux_read_entropy_ioctl(device, &entropy);
|
||||||
|
} else if (strategy == PROC) {
|
||||||
|
retcode = randombytes_linux_read_entropy_proc(proc_file, &entropy);
|
||||||
|
} else {
|
||||||
|
return -1; // Unreachable
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retcode != 0) {
|
||||||
|
// Unrecoverable I/O error
|
||||||
|
retcode_error = retcode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (entropy >= bits) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unreachable: poll() should only return -1 or 1
|
||||||
|
retcode_error = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
retcode = close(fd);
|
||||||
|
} while (retcode == -1 && errno == EINTR);
|
||||||
|
if (strategy == PROC) {
|
||||||
|
do {
|
||||||
|
retcode = fclose(proc_file);
|
||||||
|
} while (retcode == -1 && errno == EINTR);
|
||||||
|
}
|
||||||
|
if (retcode_error != 0) {
|
||||||
|
return retcode_error;
|
||||||
|
}
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int randombytes_linux_randombytes_urandom(void *buf, size_t n)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
size_t offset = 0, count;
|
||||||
|
ssize_t tmp;
|
||||||
|
do {
|
||||||
|
fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
} while (fd == -1 && errno == EINTR);
|
||||||
|
if (fd == -1) return -1;
|
||||||
|
if (randombytes_linux_wait_for_entropy(fd) == -1) return -1;
|
||||||
|
|
||||||
|
while (n > 0) {
|
||||||
|
count = n <= SSIZE_MAX ? n : SSIZE_MAX;
|
||||||
|
tmp = read(fd, (char *)buf + offset, count);
|
||||||
|
if (tmp == -1 && (errno == EAGAIN || errno == EINTR)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tmp == -1) return -1; /* Unrecoverable IO error */
|
||||||
|
offset += tmp;
|
||||||
|
n -= tmp;
|
||||||
|
}
|
||||||
|
assert(n == 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(__linux__) && !defined(SYS_getrandom) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(BSD)
|
||||||
|
static int randombytes_bsd_randombytes(void *buf, size_t n)
|
||||||
|
{
|
||||||
|
arc4random_buf(buf, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* defined(BSD) */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
static int randombytes_js_randombytes_nodejs(void *buf, size_t n) {
|
||||||
|
const int ret = EM_ASM_INT({
|
||||||
|
var crypto;
|
||||||
|
try {
|
||||||
|
crypto = require('crypto');
|
||||||
|
} catch (error) {
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
writeArrayToMemory(crypto.randomBytes($1), $0);
|
||||||
|
return 0;
|
||||||
|
} catch (error) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}, buf, n);
|
||||||
|
switch (ret) {
|
||||||
|
case 0:
|
||||||
|
return 0;
|
||||||
|
case -1:
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
case -2:
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
assert(false); // Unreachable
|
||||||
|
}
|
||||||
|
#endif /* defined(__EMSCRIPTEN__) */
|
||||||
|
|
||||||
|
|
||||||
|
int randombytes(uint8_t *buf, size_t n)
|
||||||
|
{
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
return randombytes_js_randombytes_nodejs(buf, n);
|
||||||
|
#elif defined(__linux__)
|
||||||
|
# if defined(SYS_getrandom)
|
||||||
|
/* Use getrandom system call */
|
||||||
|
return randombytes_linux_randombytes_getrandom(buf, n);
|
||||||
|
# else
|
||||||
|
/* When we have enough entropy, we can read from /dev/urandom */
|
||||||
|
return randombytes_linux_randombytes_urandom(buf, n);
|
||||||
|
# endif
|
||||||
|
#elif defined(BSD)
|
||||||
|
/* Use arc4random system call */
|
||||||
|
return randombytes_bsd_randombytes(buf, n);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
/* Use windows API */
|
||||||
|
return randombytes_win32_randombytes(buf, n);
|
||||||
|
#else
|
||||||
|
# error "randombytes(...) is not supported on this platform"
|
||||||
|
#endif
|
||||||
|
}
|
@ -2,6 +2,12 @@
|
|||||||
#define RANDOMBYTES_H
|
#define RANDOMBYTES_H
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void randombytes(uint8_t *x, uint64_t xlen);
|
#ifdef _WIN32
|
||||||
|
# include <CRTDEFS.H>
|
||||||
|
#else
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int randombytes(uint8_t *buf, size_t xlen);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
15
crypto_kem/kyber768/clean/Makefile
Normal file
15
crypto_kem/kyber768/clean/Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# This Makefile has been tested with GNU Make and BSD Make
|
||||||
|
|
||||||
|
LIB=libkyber768_clean.a
|
||||||
|
OBJECTS=cbd.o indcpa.o kem.o kex.o ntt.o poly.o polyvec.o precomp.o reduce.o verify.o
|
||||||
|
|
||||||
|
CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS)
|
||||||
|
|
||||||
|
all: $(LIB)
|
||||||
|
|
||||||
|
$(LIB): $(OBJECTS)
|
||||||
|
$(AR) -r $@ $(OBJECTS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJECTS)
|
||||||
|
$(RM) $(LIB)
|
@ -1,5 +1,7 @@
|
|||||||
LIB=libkyber768_clean.lib
|
# This Makefile can be used with Microsoft Visual Studio's nmake using the command:
|
||||||
|
# nmake /f Makefile.Microsoft_nmake
|
||||||
|
|
||||||
|
LIB=libkyber768_clean.lib
|
||||||
OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj
|
OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj
|
||||||
|
|
||||||
CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now
|
CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now
|
||||||
@ -7,8 +9,8 @@ CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1,
|
|||||||
all: $(LIB)
|
all: $(LIB)
|
||||||
|
|
||||||
$(LIB): $(OBJECTS)
|
$(LIB): $(OBJECTS)
|
||||||
LIB.EXE /OUT:$@ $**
|
LIB.EXE /OUT:$@ $**
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
DEL $(OBJECTS)
|
DEL $(OBJECTS)
|
||||||
DEL $(LIB)
|
DEL $(LIB)
|
||||||
|
Loading…
Reference in New Issue
Block a user