quantum init

This commit is contained in:
zhaoxiaomeng
2018-01-04 13:38:57 +08:00
committed by Simon
parent d11f845fde
commit 53af3b51ae
2361 changed files with 387455 additions and 144458 deletions

69
vendor/liboqs/.clang-format vendored Normal file
View File

@@ -0,0 +1,69 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BreakBeforeBinaryOperators: false
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
BinPackParameters: true
BinPackArguments: true
ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
DerivePointerAlignment: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
IndentWrappedFunctionNames: false
IndentFunctionDeclarationAfterType: false
MaxEmptyLinesToKeep: 1
KeepEmptyLinesAtTheStartOfBlocks: true
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpacesBeforeTrailingComments: 1
Standard: Cpp11
IndentWidth: 4
TabWidth: 4
UseTab: ForIndentation
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterCStyleCast: true
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
SpaceBeforeParens: ControlStatements
DisableFormat: false
SortIncludes: false
...

96
vendor/liboqs/.gitignore vendored Normal file
View File

@@ -0,0 +1,96 @@
*.swp
# Linked headers
include
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
/test_kex
/test_sig
/test_rand
/test_aes
benchmark_lowmc
pp_matrices
precomputed_data
# Debug files
*.dSYM/
*.su
# Generated documentation
docs/doxygen
# Backup files
*~
# Visual Studio files
VisualStudio/*.db
VisualStudio/*.opendb
VisualStudio/.vs/
VisualStudio/**/Win32/
VisualStudio/**/x64/
VisualStudio/include/
VisualStudio/**/*.user
# External sources
external
src/sig_picnic/external
#Autotools
autom4te.cache
.deps
Makefile.in
Makefile
aclocal.m4
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
config/libtool.m4
config/ltoptions.m4
config/ltsugar.m4
config/ltversion.m4
config/lt~obsolete.m4
configure
depcomp
install-sh
libtool
ltmain.sh
missing
stamp-h1
.libs
.dirstamp
#params
sample_params
data/

79
vendor/liboqs/.travis-tests.sh vendored Executable file
View File

@@ -0,0 +1,79 @@
#!/bin/bash
set -e
export CC=$CC_OQS
autoreconf -i
enable_disable_str=
if [[ ${USE_OPENSSL} == 1 ]];then
enable_disable_str=" --enable-openssl"
if [[ ! -z "${OPENSSL_DIR// }" ]];then
enable_disable_str+=" --with-openssl-dir=${OPENSSL_DIR}"
fi
fi
if [[ ${AES_NI} == 0 ]];then
enable_disable_str+=" --disable-aes-ni"
fi
if [[ ${ENABLE_CODE_MCBITS} == 1 ]];then
enable_disable_str+=" --enable-kex-code-mcbits"
if [[ ! -z "${SODIUM_DIR// }" ]];then
enable_disable_str+=" --with-sodium-dir=${SODIUM_DIR}"
fi
fi
if [[ ${ENABLE_SIDH_IQC_REF} == 1 ]];then
enable_disable_str+=" --enable-kex-sidh-iqc-ref"
if [[ ! -z "${GMP_DIR// }" ]];then
enable_disable_str+=" --with-gmp-dir=${GMP_DIR}"
fi
fi
if [[ ${ENABLE_KEX_LWE_FRODO} == 0 ]];then
enable_disable_str+=" --disable-kex-lwe-frodo"
fi
if [[ ${ENABLE_KEX_MLWE_KYBER} == 0 ]];then
enable_disable_str+=" --disable-kex-mlwe-kyber"
fi
if [[ ${ENABLE_KEX_NTRU} == 0 ]];then
enable_disable_str+=" --disable-kex-ntru"
fi
if [[ ${ENABLE_KEX_RLWE_MSRLN16} == 0 ]];then
enable_disable_str+=" --disable-kex-rlwe-msrln16"
fi
if [[ ${ENABLE_KEX_RLWE_NEWHOPE} == 0 ]];then
enable_disable_str+=" --disable-kex-rlwe-newhope"
fi
if [[ ${ENABLE_KEX_SIDH_CLN16} == 0 ]];then
enable_disable_str+=" --disable-kex-sidh-cln16"
fi
if [[ ${USE_PICNIC} == 1 ]];then
enable_disable_str+=" --enable-picnic"
./download-and-setup-picnic.sh
if [[ ! -z "${M4RI_DIR// }" ]];then
enable_disable_str+=" --with-m4ri-dir=${M4RI_DIR}"
fi
fi
./configure --enable-silent-rules ${enable_disable_str}
make clean
make
make test
for f in $(ls .travis/*-check.sh); do
if [[ ${USE_PICNIC} == 1 ]];then
if [[ ! "$f" == ".travis/global-namespace-check.sh" ]];then
bash $f;
fi
else
bash $f;
fi
done

84
vendor/liboqs/.travis.yml vendored Normal file
View File

@@ -0,0 +1,84 @@
language: c
dist: trusty
sudo: true
matrix:
include:
- os: linux
compiler: gcc
env:
- ENABLE_SIDH_IQC_REF=1
- ENABLE_KEX_LWE_FRODO=0
- ENABLE_KEX_MLWE_KYBER=0
- ENABLE_KEX_SIDH_CLN16=0
- USE_PICNIC=1
- USE_OPENSSL=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- libm4ri-dev
before_install:
- sh .travis/install-clang-format-linux.sh
- os: linux
compiler: gcc
env: CC_OQS=gcc-4.9
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-4.9
before_install:
- sh .travis/install-clang-format-linux.sh
- os: linux
compiler: gcc
env: CC_OQS=gcc-5
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-5
before_install:
- sh .travis/install-clang-format-linux.sh
- os: linux
compiler: gcc
env:
- CC_OQS=gcc-6
- USE_OPENSSL=1
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gcc-6
- libssl-dev
before_install:
- sh .travis/install-clang-format-linux.sh
- os: osx
compiler: clang
env:
- CC_OQS=clang
- AES_NI=0
before_install:
- brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/0c4314c499576b28e4c082b591228a8f940954c0/Formula/clang-format.rb
- os: osx
compiler: clang
env:
- CC_OQS=clang
- AES_NI=0
- USE_OPENSSL=1
- OPENSSL_DIR=/usr/local/opt/openssl # openssl is a keg-only package
- ENABLE_CODE_MCBITS=1
- ENABLE_SIDH_IQC_REF=1
- USE_PICNIC=1
- M4RI_DIR=/usr/local/
before_install:
- brew install libsodium
- brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/0c4314c499576b28e4c082b591228a8f940954c0/Formula/clang-format.rb
- brew install homebrew/science/m4ri
script:
- ./.travis-tests.sh

View File

@@ -0,0 +1,22 @@
#!/bin/bash
retvalue=0
if [[ $(find . -name '*.[ch]' -exec grep -H bzero {} \;) ]];
then
tput setaf 1;
echo "Code uses banned functions (bzero).";
tput sgr 0
retvalue=1;
fi;
# can add more checks here by copying the above code block
if [[ $retvalue == 0 ]];
then
tput setaf 2;
echo "Code does not use banned functions.";
tput sgr 0
fi;
exit $retvalue;

View File

@@ -0,0 +1,15 @@
#!/bin/bash
if [[ $(nm -g liboqs.a | grep ' T ' | grep -E -v -i ' T [_]?[OQS|ntru]') ]];
then
tput setaf 1;
echo "Code contains the following non-namespaced global symbols; see https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions for function naming conventions.";
tput sgr 0
nm -g liboqs.a | grep ' T ' | grep -E -v -i ' T [_]?[OQS|ntru]'
exit 1;
else
tput setaf 2;
echo "Code adheres to the project standards (global namespace).";
tput sgr 0
exit 0;
fi;

View File

@@ -0,0 +1,11 @@
#!/bin/bash
#
# Install clang-format on Linux
#
if [ ! -x "$(which clang-format-3.9)" ]; then
sudo add-apt-repository 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main'
wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update -qq
sudo apt-get install -qq -y clang-format-3.9
fi;

23
vendor/liboqs/.travis/style-check.sh vendored Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
if [ ! -x "$(which clang-format-3.9)" ]; then
# If clang-format is not version -3.9, just use clang-format
CLANGFORMAT=clang-format make prettyprint
else
CLANGFORMAT=clang-format-3.9 make prettyprint
fi;
modified=$(git status -s)
if [ "$modified" ]; then
tput setaf 1;
echo "Code does not adhere to the project standards. Run \"make prettyprint\".";
tput sgr 0;
git status -s
exit 1;
else
tput setaf 2;
echo "Code adheres to the project standards (prettyprint).";
tput sgr 0;
exit 0;
fi;

2384
vendor/liboqs/Doxyfile vendored Normal file

File diff suppressed because it is too large Load Diff

25
vendor/liboqs/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,25 @@
The MIT license, the text of which is below, applies to liboqs in general.
liboqs includes some third party libraries or modules that are licensed
differently; the corresponding subfolder contains the license that applies in
that case.
Copyright (c) 2016 Open Quantum Safe project
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.

187
vendor/liboqs/Makefile.am vendored Normal file
View File

@@ -0,0 +1,187 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I config
# DOXYGEN SUPPORT
include aminclude.am
# ensure the distribution of the doxygen configuration file
EXTRA_DIST = doxygen.cfg
CLANGFORMAT ?= clang-format-3.9
SUBDIRS = ${SRCDIR}
BUILT_SOURCES = links
lib_LTLIBRARIES = liboqs.la
liboqs_la_SOURCES =
liboqs_la_LIBADD = src/common/libcommon.la
liboqs_la_LIBADD += src/crypto/aes/libaes.la
liboqs_la_LIBADD += src/crypto/rand/librand.la
liboqs_la_LIBADD += src/crypto/rand_urandom_aesctr/librandaesctr.la
liboqs_la_LIBADD += src/crypto/rand_urandom_chacha20/librandchacha20.la
liboqs_la_LIBADD += src/crypto/sha3/libsha3.la
liboqs_la_LIBADD += src/kex/libkex.la
if USE_KEX_LWE_FRODO
liboqs_la_LIBADD += src/kex_lwe_frodo/libfrodo.la
endif
if USE_KEX_MLWE_KYBER
liboqs_la_LIBADD += src/kex_mlwe_kyber/libkyber.la
endif
if USE_KEX_NTRU
liboqs_la_LIBADD += src/kex_ntru/libntru.la
endif
liboqs_la_LIBADD += src/kex_rlwe_bcns15/libbcns15.la
if USE_KEX_RLWE_MSRLN16
liboqs_la_LIBADD += src/kex_rlwe_msrln16/libmsrln16.la
endif
if USE_KEX_RLWE_NEWHOPE
liboqs_la_LIBADD += src/kex_rlwe_newhope/libnewhope.la
endif
if USE_KEX_SIDH_CLN16
liboqs_la_LIBADD += src/kex_sidh_cln16/libcln16.la
endif
liboqs_la_LIBADD += src/sig/libsig.la
if USE_MCBITS
liboqs_la_LIBADD += src/kex_code_mcbits/libmcbits.la
endif
if USE_SIDH_IQC
liboqs_la_LIBADD += src/kex_sidh_iqc_ref/libsidhiqc.la
endif
if USE_PICNIC
liboqs_la_LIBADD += src/sig_picnic/libpicnic.la
endif
noinst_bin_PROGRAMS = test_rand test_kex test_aes
if USE_PICNIC
if USE_OPENSSL
noinst_bin_PROGRAMS += pp_matrices test_sig
endif
endif
noinst_bindir=$(prefix)/tests
test_kex_LDADD = liboqs.la -lm
test_kex_SOURCES = src/kex/test_kex.c
test_kex_CPPFLAGS = -I./include
test_kex_CPPFLAGS += $(AM_CPPFLAGS)
if USE_MCBITS
test_kex_LDADD += -L${SODIUM_DIR}/lib -lsodium
endif
if USE_OPENSSL
test_kex_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
endif
if USE_SIDH_IQC
test_kex_LDADD += -L$(GMP_DIR)/lib -lgmp
endif
if USE_PICNIC
if USE_OPENSSL
test_sig_LDADD = liboqs.la -lm
test_sig_SOURCES = src/sig/test_sig.c
test_sig_CPPFLAGS = -I${OPENSSL_DIR}/include -I./include
test_sig_CPPFLAGS += $(AM_CPPFLAGS)
test_sig_LDADD += -L${OPENSSL_DIR}/lib -lssl -lcrypto
pp_matrices_LDADD = liboqs.la -lm
pp_matrices_SOURCES = src/sig_picnic/external/Picnic-master/preprocessMatrices.c
pp_matrices_CPPFLAGS = -std=c99 -I${OPENSSL_DIR}/include -I${M4RI_DIR}/include/m4ri -I./include
#pp_matrices_CPPFLAGS += $(AM_CPPFLAGS)
pp_matrices_LDADD += -L${OPENSSL_DIR}/lib -L${M4RI_DIR}/lib -lssl -lcrypto -lm4ri
endif
endif
test_aes_LDADD = liboqs.la -lm
test_aes_SOURCES = src/crypto/aes/test_aes.c
test_aes_CPPFLAGS = -I./include
test_aes_CPPFLAGS += $(AM_CPPFLAGS)
if USE_OPENSSL
test_aes_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
endif
test_rand_SOURCES = src/crypto/rand/test_rand.c
test_rand_CPPFLAGS = -Iinclude -Isrc/crypto/rand_urandom_aesctr/
test_rand_CPPFLAGS += $(AM_CPPFLAGS)
test_rand_LDADD = liboqs.la
if USE_OPENSSL
test_rand_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
else
if USE_AES_NI
test_rand_CPPFLAGS += -maes -msse2
endif
endif
test: clean-tests
make
./test_kex --quiet
./test_rand --quiet
./test_aes
if USE_PICNIC
if USE_OPENSSL
mkdir -p precomputed_data
./pp_matrices
./test_sig
endif
endif
links:
$(MKDIR_P) include/oqs
cp -f src/common/common.h include/oqs
cp -f src/crypto/aes/aes.h include/oqs
cp -f src/crypto/rand/rand.h include/oqs
cp -f src/crypto/rand_urandom_aesctr/rand_urandom_aesctr.h include/oqs
cp -f src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h include/oqs
cp -f src/crypto/sha3/sha3.h include/oqs
cp -f src/kex/kex.h include/oqs
cp -f src/kex_lwe_frodo/kex_lwe_frodo.h include/oqs
cp -f src/kex_mlwe_kyber/kex_mlwe_kyber.h include/oqs
cp -f src/kex_ntru/kex_ntru.h include/oqs
cp -f src/kex_rlwe_bcns15/kex_rlwe_bcns15.h include/oqs
cp -f src/kex_rlwe_msrln16/kex_rlwe_msrln16.h include/oqs
cp -f src/kex_rlwe_newhope/kex_rlwe_newhope.h include/oqs
cp -f src/kex_sidh_cln16/kex_sidh_cln16.h include/oqs
cp -f src/kex_mlwe_kyber/kex_mlwe_kyber.h include/oqs
cp -f src/sig/sig.h include/oqs
if USE_PICNIC
if USE_OPENSSL
cp -f src/sig_picnic/external/Picnic-master/picnic.h include/oqs
endif
endif
$(LN_S) -f .libs/liboqs.a
if USE_MCBITS
cp -f src/kex_code_mcbits/kex_code_mcbits.h include/oqs
endif
if USE_SIDH_IQC
cp -f src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.h include/oqs
$(LN_S) -f src/kex_sidh_iqc_ref/sample_params
endif
if USE_PICNIC
$(LN_S) -f ../../src/sig_picnic/sig_picnic.h include/oqs
endif
clean-local:
rm -f liboqs.a
rm -rf include
if USE_SIDH_IQC
rm -f sample_params
endif
clean-tests:
rm -f test_kex test_rand test_aes
if USE_PICNIC
if USE_OPENSSL
rm -f test_sig
rm -f pp_matrices
rm -rf precomputed_data
endif
endif
prettyprint:
find src -name '*.c' -o -name '*.h' | grep -v Picnic*| xargs $(CLANGFORMAT) -style=file -i
docs: links
doxygen

295
vendor/liboqs/README.md vendored Normal file
View File

@@ -0,0 +1,295 @@
[![Build Status](https://travis-ci.org/open-quantum-safe/liboqs.svg?branch=master)](https://travis-ci.org/open-quantum-safe/liboqs)
[![Build status](https://ci.appveyor.com/api/projects/status/9d2ts78x88r8wnii/branch/master?svg=true)](https://ci.appveyor.com/project/dstebila/liboqs/branch/master)
liboqs
======
liboqs is a C library for quantum-resistant cryptographic algorithms.
Overview
--------
The **Open Quantum Safe (OQS) project** has the goal of developing and prototyping quantum-resistant cryptography.
**liboqs** is an open source C library for quantum-resistant cryptographic algorithms. liboqs initially focuses on key exchange algorithms. liboqs provides a common API suitable for post-quantum key exchange algorithms, and will collect together various implementations. liboqs will also include a test harness and benchmarking routines to compare performance of post-quantum implementations.
OQS will also include integrations into application-level protocols to provide easy prototyping of quantum-resistant cryptography. Our first integration is in OpenSSL:
- **open-quantum-safe/openssl** is an integration of liboqs into OpenSSL 1.0.2. The goal of this integration is to provide easy prototyping of quantum-resistant cryptography. The integration should not be considered "production quality". See more about this integration in its GitHub repository [open-quantum-safe/openssl/](https://github.com/open-quantum-safe/openssl/).
More information on OQS can be found on our website: [https://openquantumsafe.org/](https://openquantumsafe.org/).
Contents
--------
liboqs currently contains:
- `kex_rlwe_bcns15`: key exchange from the ring learning with errors problem (Bos, Costello, Naehrig, Stebila, *IEEE Symposium on Security & Privacy 2015*, [https://eprint.iacr.org/2014/599](https://eprint.iacr.org/2014/599))
- `kex_rlwe_newhope`: "NewHope": key exchange from the ring learning with errors problem (Alkim, Ducas, Pöppelmann, Schwabe, *USENIX Security 2016*, [https://eprint.iacr.org/2015/1092](https://eprint.iacr.org/2015/1092)) (using the reference C implementation of NewHope from [https://github.com/tpoeppelmann/newhope](https://github.com/tpoeppelmann/newhope))
- `kex_rlwe_msrln16`: Microsoft Research implementation of Peikert's ring-LWE key exchange (Longa, Naehrig, *CANS 2016*, [https://eprint.iacr.org/2016/504](https://eprint.iacr.org/2016/504)) (based on the implementation of Alkim, Ducas, Pöppelmann, and Schwabe, with improvements from Longa and Naehrig, see [https://www.microsoft.com/en-us/research/project/lattice-cryptography-library/](https://www.microsoft.com/en-us/research/project/lattice-cryptography-library/))
- `kex_lwe_frodo`: "Frodo": key exchange from the learning with errors problem (Bos, Costello, Ducas, Mironov, Naehrig, Nikolaenko, Raghunathan, Stebila, *ACM Conference on Computer and Communications Security 2016*, [https://eprint.iacr.org/2016/659](https://eprint.iacr.org/2016/659))
- `kex_sidh_cln16`: key exchange from the supersingular isogeny Diffie-Hellman problem (Costello, Naehrig, Longa, *CRYPTO 2016*, [https://eprint.iacr.org/2016/413](https://eprint.iacr.org/2016/413)), using the implementation of Microsoft Research [https://www.microsoft.com/en-us/research/project/sidh-library/](https://www.microsoft.com/en-us/research/project/sidh-library/)
- `kex_sidh_iqc_ref`: key exchange from the supersingular isogeny Diffie-Hellman problem (De Feo, Jao, Plût, *J. Math. Cryptol.* 8(3):209, 2014, [https://eprint.iacr.org/2011/506](https://eprint.iacr.org/2011/506)), using a reference implementation by Javad Doliskani
- `kex_code_mcbits`: "McBits": key exchange from the error correcting codes, specifically Niederreiter's form of McEliece public key encryption using hidden Goppa codes (Bernstein, Chou, Schwabe, *CHES 2013*, [https://eprint.iacr.org/2015/610](https://eprint.iacr.org/2015/610)), using the implementation of McBits from [https://www.win.tue.nl/~tchou/mcbits/](https://www.win.tue.nl/~tchou/mcbits/))
- `kex_ntru`: NTRU: key transport using NTRU public key encryption (Hoffstein, Pipher, Silverman, *ANTS 1998*) with the EES743EP1 parameter set, wrapper around the implementation from the NTRU Open Source project [https://github.com/NTRUOpenSourceProject/NTRUEncrypt](https://github.com/NTRUOpenSourceProject/NTRUEncrypt))
- `kex_mlwe_kyber`: Kyber: a CCA-secure module-lattice-based key exchange mechanism (Bos, Ducas, Kiltz, Lepoint, Lyubashevsky, Schwabe, Shanck, Stehlé, *Real World Crypto 2017*, [https://eprint.iacr.org/2017/634](https://eprint.iacr.org/2017/634)), using the reference C implementation of Kyber from [pq-crystals/kyber](https://github.com/pq-crystals/kyber)
- `sig_picnic`: signature based on zero-knowledge proof as specified in Post-Quantum Zero-Knowledge and Signatures from Symmetric-Key Primitives (Melissa Chase and David Derler and Steven Goldfeder and Claudio Orlandi and Sebastian Ramacher and Christian Rechberger and Daniel Slamanig and Greg Zaverucha, [https://eprint.iacr.org/2017/279.pdf](https://eprint.iacr.org/2017/279.pdf))
Detailed information about each algorithm and implementations can be found in the [docs/Algorithm data sheets](https://github.com/open-quantum-safe/liboqs/tree/master/docs/Algorithm%20data%20sheets) directory.
Building and Running on Linux and macOS
---------------------------------------
Builds have been tested on Mac OS X 10.11.6, macOS 10.12.5, Ubuntu 16.04.1.
### Install dependencies for macOS
You need to install `autoconf`, `automake` and `libtool`:
brew install autoconf automake libtool
### Install dependencies for Ubuntu
You need to install autoconf, automake and libtool:
sudo apt install autoconf automake libtool
### Building
To build, first clone or download the source from GitHub, then simply type:
autoreconf -i
./configure
make clean
make
This will generate:
- `liboqs.a`: A static library with implementations for the algorithms listed in "Contents" above.
- `test_rand`: A simple test harness for the random number generator. This will test the distance of PRNG output from uniform using statistical distance.
- `test_aes`: A simple test harness for AES. This will test the correctness of the C implementation (and of the AES-NI implementation, if not disabled) of AES, and will compare the speed of these implementations against OpenSSL's AES implementation.
- `test_kex`: A simple test harness for the default key exchange algorithm. This will output key exchange messages; indicate whether the parties agree on the session key or not over a large number of trials; and measure the distance of the sessions keys from uniform using statistical distance.
- `test_sig`: A simple test harness for the signature algorithms.
### Running
To run the tests, simply type:
make test
To run benchmarks, run
./test_kex --bench
To run benchmark only on some ciphers, run
./test_kex --help
to list the available ciphers and then run e.g.
./test_kex --bench rlwe_bcns15 rlwe_newhope
#### Memory benchmarks
To run one or more ciphers only once use `--mem-bench`, which is suitable for memory usage profiling:
./test_kex --mem-bench ntru
You may also get instant memory usage results of an algorithm (e.g. ntru) by running [valgrind's massif tool](http://valgrind.org/docs/manual/ms-manual.html) by running
./kex_bench_memory.sh ntru
### Additional build options
#### Building with OpenSSL algorithms enabled:
OpenSSL can be used for some symmetric crypto algorithms, which may result in better performance.
To build with OpenSSL enabled:
./configure --enable-openssl
make clean
make
You may need to specify the path to your OpenSSL directory:
./configure --enable-openssl --with-openssl-dir=/path/to/openssl/directory
make clean
make
### Building with `kex_sidh_iqc_ref` enabled
The `kex_sidh_iqc_ref ` key exchange method is not enabled by default since it requires an external library (libgmp).
To install the library on macOS:
brew install gmp
To build with `kex_sidh_iqc_ref ` enabled:
./configure --enable-sidhiqc
make clean
make
You may need to specify the path to your libgmp directory:
./configure --enable-sidhiqc --with-gmp-dir=/path/to/gmp/directory
make clean
make
### Building with `kex_code_mcbits` enabled
The `kex_code_mcbits` key exchange method is not enabled by default since it requires an external library (libsodium).
To install the library on macOS:
brew install libsodium
To install the library on Ubuntu:
sudo apt install libsodium-dev
To build with `kex_code_mcbits ` enabled:
./configure --enable-mcbits
make clean
make
### Building with the following KEX algorithms disabled
./configure --disable-kex-ntru --disable-kex-lwe-frodo --disable-kex-mlwe-kyber --disable-kex-rlwe-msrln16 --disable-kex-rlwe-newhope --disable-kex-sidh-cln16
make clean
make
### Building with `sig_picnic` enabled
The `sig_picnic` signature algorithm is not enabled by default since it requires:
- external libraries (`openssl` and `m4ri`);
- to download and setup Picnic;
- a parameters generation preprocessing step.
To install the libraries on macOS:
brew install openssl homebrew/science/m4ri
To install the libraries on Ubuntu:
sudo apt install libssl-dev libm4ri-dev
To download the Picnic source code:
./download-and-setup-picnic.sh
To build with `sig_picnic` enabled:
./configure --enable-picnic --enable-openssl [--with-openssl-dir=<..> --with-m4r-dir=<..>]
make clean
make
make test (this generates data needed by the Picnic library)
Building and running on Windows
-------------------------------
Windows binaries can be generated using the Visual Studio solution in the VisualStudio folder. Builds have been tested on Windows 10.
McBits is disabled by default in the Visual Studio build; follow these steps to enable it:
- Obtain the [libsodium library](https://libsodium.org); compile the static library from the Visual Studio projects.
- Add `ENABLE_CODE_MCBITS` and `SODIUM_STATIC` to the preprocessor definitions of the `oqs` and `test_kex` projects.
- Add the sodium "src/include" location to the "Additional Include Directories" in the oqs project C properties.
- Add the libsodium library to the "Additional Dependencies" in the `test_kex` project Linker properties.
Building for Android
--------------------
Install Android NDK
Create a standalone toolchain for the platform that you wish to cross compile for (e.g. NDK_BUNDLE="~/Android/Sdk/ndk-bundle" ARCH=arm64 INSTALL_DIR="/tmp/ndk-toolchain"):
$NDK_BUNDLE/build/tools/make_standalone_toolchain.py --arch $ARCH --install-dir $INSTALL_DIR
Configure and build for Android after running `autoreconf -i` (e.g. HOST=aarch64-linux-android TOOLCHAIN_DIR=$INSTALL_DIR):
./configure-android --host=$HOST --toolchain=$TOOLCHAIN_DIR
make
Run it from your Android device:
adb push test_kex /data/local/tmp/
adb shell "/data/local/tmp/test_kex"
Tested on SM-930F
Documentation
-------------
The directory `docs/Algorithm data sheets` contains information about some of the algorithms supported by liboqs.
### Doxygen documentation
Some source files contain inline Doxygen-formatted comments which can be used to generate additional documentation.
On macOS, you may need to install several dependencies first:
brew install doxygen graphviz
The documentation can be generated by running:
make docs
This will generate the `docs/doxygen/html` directory. Check `./configure --help` for generating other formats.
Contributing and using
----------------------
We hope OQS will provide a framework for many post-quantum implementations.
In the immediate term, if you have feedback on our API ([kex.h](https://github.com/open-quantum-safe/liboqs/blob/master/src/kex/kex.h), [sig.h](https://github.com/open-quantum-safe/liboqs/blob/master/src/sig/sig.h) or [rand.h](https://github.com/open-quantum-safe/liboqs/blob/master/src/rand/rand.h)), please contact us so we can ensure our API covers a wide range of implementation needs.
If you have or are writing an implementation of a post-quantum key exchange algorithm, we hope you will consider making an implementation that meets our API so that others may use it and would be happy to discuss including it directly in liboqs. Please take a look at our [coding conventions](https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions).
If you would like to use liboqs in an application-level protocol, please get in touch and we can provide some guidance on options for using liboqs.
We are also interested in assistance from code reviewers.
Please contact Douglas Stebila <[stebilad@mcmaster.ca](mailto:stebilad@mcmaster.ca)>.
License
-------
liboqs is licensed under the MIT License; see [LICENSE.txt](https://github.com/open-quantum-safe/liboqs/blob/master/LICENSE.txt) for details. liboqs includes some third party libraries or modules that are licensed differently; the corresponding subfolder contains the license that applies in that case. In particular:
- `src/crypto/aes/aes_c.c`: public domain
- `src/crypto/rand_urandom_chacha20/external`: public domain
- `src/kex_code_mcbits`: public domain
- `src/kex_mlwe_kyber`: public domain
- `src/kex_rlwe_bcns15`: public domain ([Unlicense](http://unlicense.org))
- `src/kex_rlwe_msrln16`: MIT License
- `src/kex_rlwe_msrln16/external`: public domain ([CC0](http://creativecommons.org/publicdomain/zero/1.0/))
- `src/kex_rlwe_newhope`: public domain
- `src/kex_sidh_cln16`: MIT License
- `src/kex_sidh_iqc_ref`: MIT License
- `src/sig_picnic`: MIT License
Team
----
The Open Quantum Safe project is lead by [Michele Mosca](http://faculty.iqc.uwaterloo.ca/mmosca/) (University of Waterloo) and [Douglas Stebila](https://www.douglas.stebila.ca/research/) (McMaster University).
### Contributors
- Javad Doliskani (University of Waterloo)
- Vlad Gheorghiu (evolutionQ / University of Waterloo)
- Tancrède Lepoint (SRI International)
- Shravan Mishra (University of Waterloo)
- Christian Paquin (Microsoft Research)
- Alex Parent (University of Waterloo)
- Sebastian Verschoor (University of Waterloo)
### Support
Development of Open Quantum Safe has been supported in part by the Tutte Institute for Mathematics and Computing. Research projects which developed specific components of Open Quantum Safe have been supported by various research grants; see the source papers for funding acknowledgments.

54
vendor/liboqs/VisualStudio/liboqs.sln vendored Normal file
View File

@@ -0,0 +1,54 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_rand", "test_rand\test_rand.vcxproj", "{6BB96591-0BCD-42E6-8863-4B9BFE75530C}"
ProjectSection(ProjectDependencies) = postProject
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74} = {DCFEFB81-4696-45D2-9FCA-351CCFC13C74}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oqs", "oqs\oqs.vcxproj", "{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_kex", "test_kex\test_kex.vcxproj", "{820B79FE-57D7-4539-A0CA-B668A0723B9B}"
ProjectSection(ProjectDependencies) = postProject
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74} = {DCFEFB81-4696-45D2-9FCA-351CCFC13C74}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Debug|x64.ActiveCfg = Debug|x64
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Debug|x64.Build.0 = Debug|x64
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Debug|x86.ActiveCfg = Debug|Win32
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Debug|x86.Build.0 = Debug|Win32
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Release|x64.ActiveCfg = Release|x64
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Release|x64.Build.0 = Release|x64
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Release|x86.ActiveCfg = Release|Win32
{6BB96591-0BCD-42E6-8863-4B9BFE75530C}.Release|x86.Build.0 = Release|Win32
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Debug|x64.ActiveCfg = Debug|x64
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Debug|x64.Build.0 = Debug|x64
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Debug|x86.ActiveCfg = Debug|Win32
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Debug|x86.Build.0 = Debug|Win32
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Release|x64.ActiveCfg = Release|x64
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Release|x64.Build.0 = Release|x64
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Release|x86.ActiveCfg = Release|Win32
{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}.Release|x86.Build.0 = Release|Win32
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Debug|x64.ActiveCfg = Debug|x64
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Debug|x64.Build.0 = Debug|x64
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Debug|x86.ActiveCfg = Debug|Win32
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Debug|x86.Build.0 = Debug|Win32
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Release|x64.ActiveCfg = Release|x64
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Release|x64.Build.0 = Release|x64
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Release|x86.ActiveCfg = Release|Win32
{820B79FE-57D7-4539-A0CA-B668A0723B9B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,293 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\common\common.h" />
<ClInclude Include="..\..\src\crypto\aes\aes.h" />
<ClInclude Include="..\..\src\crypto\aes\aes_local.h" />
<ClInclude Include="..\..\src\crypto\rand\rand.h" />
<ClInclude Include="..\..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h" />
<ClInclude Include="..\..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h" />
<ClInclude Include="..\..\src\crypto\sha3\sha3.h" />
<ClInclude Include="..\..\src\kex\kex.h" />
<ClInclude Include="..\..\src\kex_code_mcbits\kex_code_mcbits.h" />
<ClInclude Include="..\..\src\kex_code_mcbits\mcbits.h" />
<ClInclude Include="..\..\src\kex_lwe_frodo\kex_lwe_frodo.h" />
<ClInclude Include="..\..\src\kex_lwe_frodo\local.h" />
<ClInclude Include="..\..\src\kex_mlwe_kyber\kex_mlwe_kyber.h" />
<ClInclude Include="..\..\src\kex_ntru\kex_ntru.h" />
<ClInclude Include="..\..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h" />
<ClInclude Include="..\..\src\kex_rlwe_bcns15\local.h" />
<ClInclude Include="..\..\src\kex_rlwe_bcns15\rlwe_a.h" />
<ClInclude Include="..\..\src\kex_rlwe_bcns15\rlwe_table.h" />
<ClInclude Include="..\..\src\kex_rlwe_newhope\kex_rlwe_newhope.h" />
<ClInclude Include="..\..\src\kex_rlwe_newhope\params.h" />
<ClInclude Include="..\..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h" />
<ClInclude Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto.h" />
<ClInclude Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto_priv.h" />
<ClInclude Include="..\..\src\kex_sidh_cln16\kex_sidh_cln16.h" />
<ClInclude Include="..\..\src\kex_sidh_cln16\SIDH.h" />
<ClInclude Include="..\..\src\kex_sidh_cln16\SIDH_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\common\common.c" />
<ClCompile Include="..\..\src\crypto\aes\aes.c" />
<ClCompile Include="..\..\src\crypto\aes\aes_c.c" />
<ClCompile Include="..\..\src\crypto\aes\aes_ni.c" />
<ClCompile Include="..\..\src\crypto\rand\rand.c" />
<ClCompile Include="..\..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.c" />
<ClCompile Include="..\..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.c" />
<ClCompile Include="..\..\src\crypto\sha3\sha3.c" />
<ClCompile Include="..\..\src\kex\kex.c" />
<ClCompile Include="..\..\src\kex_code_mcbits\external\operations.c" />
<ClCompile Include="..\..\src\kex_code_mcbits\kex_code_mcbits.c" />
<ClCompile Include="..\..\src\kex_lwe_frodo\kex_lwe_frodo.c" />
<ClCompile Include="..\..\src\kex_lwe_frodo\lwe.c" />
<ClCompile Include="..\..\src\kex_lwe_frodo\lwe_noise.c" />
<ClCompile Include="..\..\src\kex_mlwe_kyber\kex_mlwe_kyber.c" />
<ClCompile Include="..\..\src\kex_ntru\kex_ntru.c" />
<ClCompile Include="..\..\src\kex_rlwe_bcns15\fft.c" />
<ClCompile Include="..\..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.c" />
<ClCompile Include="..\..\src\kex_rlwe_bcns15\rlwe.c" />
<ClCompile Include="..\..\src\kex_rlwe_bcns15\rlwe_kex.c" />
<ClCompile Include="..\..\src\kex_rlwe_newhope\kex_rlwe_newhope.c" />
<ClCompile Include="..\..\src\kex_rlwe_newhope\newhope.c" />
<ClCompile Include="..\..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.c" />
<ClCompile Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto_kex.c" />
<ClCompile Include="..\..\src\kex_rlwe_msrln16\ntt_constants.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\ec_isogeny.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\fpx.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\generic\fp_generic.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\kex_sidh_cln16.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\SIDH.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\sidh_kex.c" />
<ClCompile Include="..\..\src\kex_sidh_cln16\SIDH_setup.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DCFEFB81-4696-45D2-9FCA-351CCFC13C74}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>oqs</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;AES_DISABLE_NI;OQS_RAND_DEFAULT_URANDOM_CHACHA20;OQS_KEX_DEFAULT_BCNS15;CONSTANT_TIME;WINDOWS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<PreBuildEvent>
<Command>mkdir "$(SolutionDir)include\oqs"
del /Q "$(SolutionDir)include\oqs\*.*"
copy "$(SolutionDir)..\src\common\common.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\aes\aes.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand\rand.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\sha3\sha3.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_newhope\kex_rlwe_newhope.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_lwe_frodo\kex_lwe_frodo.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_sidh_cln16\kex_sidh_cln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_code_mcbits\kex_code_mcbits.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_mlwe_kyber\kex_mlwe_kyber.h" "$(SolutionDir)include\oqs\"
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;OQS_RAND_DEFAULT_URANDOM_CHACHA20;OQS_KEX_DEFAULT_BCNS15;CONSTANT_TIME;WINDOWS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
</Link>
<PreBuildEvent>
<Command>mkdir "$(SolutionDir)include\oqs"
del /Q "$(SolutionDir)include\oqs\*.*"
copy "$(SolutionDir)..\src\common\common.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\aes\aes.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand\rand.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\sha3\sha3.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_newhope\kex_rlwe_newhope.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_lwe_frodo\kex_lwe_frodo.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_sidh_cln16\kex_sidh_cln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_code_mcbits\kex_code_mcbits.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_mlwe_kyber\kex_mlwe_kyber.h" "$(SolutionDir)include\oqs\"
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;AES_DISABLE_NI;OQS_RAND_DEFAULT_URANDOM_CHACHA20;OQS_KEX_DEFAULT_BCNS15;CONSTANT_TIME;WINDOWS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>mkdir "$(SolutionDir)include\oqs"
del /Q "$(SolutionDir)include\oqs\*.*"
copy "$(SolutionDir)..\src\common\common.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\aes\aes.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand\rand.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\sha3\sha3.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_newhope\kex_rlwe_newhope.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_lwe_frodo\kex_lwe_frodo.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_sidh_cln16\kex_sidh_cln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_code_mcbits\kex_code_mcbits.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_mlwe_kyber\kex_mlwe_kyber.h" "$(SolutionDir)include\oqs\"
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;OQS_RAND_DEFAULT_URANDOM_CHACHA20;OQS_KEX_DEFAULT_BCNS15;CONSTANT_TIME;WINDOWS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>false</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<PreBuildEvent>
<Command>mkdir "$(SolutionDir)include\oqs"
del /Q "$(SolutionDir)include\oqs\*.*"
copy "$(SolutionDir)..\src\common\common.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\aes\aes.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand\rand.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\crypto\sha3\sha3.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_newhope\kex_rlwe_newhope.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_lwe_frodo\kex_lwe_frodo.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_sidh_cln16\kex_sidh_cln16.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_code_mcbits\kex_code_mcbits.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
copy "$(SolutionDir)..\src\kex_mlwe_kyber\kex_mlwe_kyber.h" "$(SolutionDir)include\oqs\"
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,225 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\..\src\kex_rlwe_bcns15\fft.c">
<Filter>KEX_BCNS15</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_lwe_frodo\kex_lwe_frodo.c">
<Filter>KEX_Frodo</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.c">
<Filter>KEX_BCNS15</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.c">
<Filter>KEX_MSR_LN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_newhope\kex_rlwe_newhope.c">
<Filter>KEX_NewHope</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto_kex.c">
<Filter>KEX_MSR_LN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_lwe_frodo\lwe.c">
<Filter>KEX_Frodo</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_lwe_frodo\lwe_noise.c">
<Filter>KEX_Frodo</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_newhope\newhope.c">
<Filter>KEX_NewHope</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_msrln16\ntt_constants.c">
<Filter>KEX_MSR_LN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_bcns15\rlwe.c">
<Filter>KEX_BCNS15</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_rlwe_bcns15\rlwe_kex.c">
<Filter>KEX_BCNS15</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\ec_isogeny.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\fpx.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\kex_sidh_cln16.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\SIDH.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\sidh_kex.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\SIDH_setup.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\common\common.c">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\aes\aes.c">
<Filter>Crypto\AES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\aes\aes_c.c">
<Filter>Crypto\AES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\aes\aes_ni.c">
<Filter>Crypto\AES</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\sha3\sha3.c">
<Filter>Crypto\SHA3</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\rand\rand.c">
<Filter>Crypto\Rand</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.c">
<Filter>Crypto\Rand</Filter>
</ClCompile>
<ClCompile Include="..\..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.c">
<Filter>Crypto\Rand</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex\kex.c">
<Filter>KEX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_code_mcbits\kex_code_mcbits.c">
<Filter>KEX_McBits</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_code_mcbits\external\operations.c">
<Filter>KEX_McBits</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_ntru\kex_ntru.c">
<Filter>KEX_NTRU</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_sidh_cln16\generic\fp_generic.c">
<Filter>KEX_SIDH_CLN16</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kex_mlwe_kyber\kex_mlwe_kyber.c">
<Filter>KEX_Kyber</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\kex_lwe_frodo\kex_lwe_frodo.h">
<Filter>KEX_Frodo</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_bcns15\kex_rlwe_bcns15.h">
<Filter>KEX_BCNS15</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_msrln16\kex_rlwe_msrln16.h">
<Filter>KEX_MSR_LN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_newhope\kex_rlwe_newhope.h">
<Filter>KEX_NewHope</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto.h">
<Filter>KEX_MSR_LN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_msrln16\LatticeCrypto_priv.h">
<Filter>KEX_MSR_LN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_bcns15\local.h">
<Filter>KEX_BCNS15</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_lwe_frodo\local.h">
<Filter>KEX_Frodo</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_newhope\params.h">
<Filter>KEX_NewHope</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_bcns15\rlwe_table.h">
<Filter>KEX_BCNS15</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_rlwe_bcns15\rlwe_a.h">
<Filter>KEX_BCNS15</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_sidh_cln16\kex_sidh_cln16.h">
<Filter>KEX_SIDH_CLN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_sidh_cln16\SIDH.h">
<Filter>KEX_SIDH_CLN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_sidh_cln16\SIDH_internal.h">
<Filter>KEX_SIDH_CLN16</Filter>
</ClInclude>
<ClInclude Include="..\..\src\common\common.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\aes\aes.h">
<Filter>Crypto\AES</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\aes\aes_local.h">
<Filter>Crypto\AES</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\sha3\sha3.h">
<Filter>Crypto\SHA3</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\rand\rand.h">
<Filter>Crypto\Rand</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\rand_urandom_aesctr\rand_urandom_aesctr.h">
<Filter>Crypto\Rand</Filter>
</ClInclude>
<ClInclude Include="..\..\src\crypto\rand_urandom_chacha20\rand_urandom_chacha20.h">
<Filter>Crypto\Rand</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex\kex.h">
<Filter>KEX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_code_mcbits\kex_code_mcbits.h">
<Filter>KEX_McBits</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_code_mcbits\mcbits.h">
<Filter>KEX_McBits</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_ntru\kex_ntru.h">
<Filter>KEX_NTRU</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kex_mlwe_kyber\kex_mlwe_kyber.h">
<Filter>KEX_Kyber</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="Common">
<UniqueIdentifier>{2b7cf696-2f08-4ea3-80c5-0d16a8c70cfa}</UniqueIdentifier>
</Filter>
<Filter Include="Crypto">
<UniqueIdentifier>{4a3e4a60-250c-46a9-8c6c-c8aecadee154}</UniqueIdentifier>
</Filter>
<Filter Include="Crypto\AES">
<UniqueIdentifier>{71c917ec-9181-4b88-bdfc-9611ee1abe9a}</UniqueIdentifier>
</Filter>
<Filter Include="Crypto\Rand">
<UniqueIdentifier>{fd44eb34-2f81-411e-a55f-f279c4b101de}</UniqueIdentifier>
</Filter>
<Filter Include="KEX">
<UniqueIdentifier>{3bb6aa76-f294-47a9-bf22-76245c9cb1d1}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_BCNS15">
<UniqueIdentifier>{ab581356-2a96-4211-99e3-f5cecd92eda3}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_Frodo">
<UniqueIdentifier>{6bfff158-3e78-402f-ba16-e8d315089de8}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_MSR_LN16">
<UniqueIdentifier>{9f5ed87f-ed1e-47b4-b7e7-1d6648cb88fd}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_NewHope">
<UniqueIdentifier>{d0291785-4232-4264-b1bd-08b7e3f8df5e}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_SIDH_CLN16">
<UniqueIdentifier>{3e550d03-8fd0-4307-ad38-832effa40102}</UniqueIdentifier>
</Filter>
<Filter Include="Crypto\SHA3">
<UniqueIdentifier>{a9a0db92-1388-4ea2-b0d5-d61a51581993}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_McBits">
<UniqueIdentifier>{9c91a128-d5a0-4eec-998e-a7bc85b3691e}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_NTRU">
<UniqueIdentifier>{f2432c4a-5195-4990-af30-65a61bf36897}</UniqueIdentifier>
</Filter>
<Filter Include="KEX_Kyber">
<UniqueIdentifier>{c95ab174-03e5-4e85-a903-ccef78182c4f}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{820B79FE-57D7-4539-A0CA-B668A0723B9B}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>test_kex</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WINDOWS;DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WINDOWS;DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WINDOWS;DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WINDOWS;DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kex\test_kex.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\kex\test_kex.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\crypto\rand\test_rand.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6BB96591-0BCD-42E6-8863-4B9BFE75530C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>test_rand</RootNamespace>
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(SolutionDir)include</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;oqs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)$(Platform)\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\crypto\rand\test_rand.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

321
vendor/liboqs/acinclude.m4 vendored Normal file
View File

@@ -0,0 +1,321 @@
# This file is part of Autoconf. -*- Autoconf -*-
# Copyright (C) 2004 Oren Ben-Kiki
# This file is distributed under the same terms as the Autoconf macro files.
########## CHANGELOG ##################
# 2009-01-14 Martin Mann
# * DX_ARG_ABLE : new variable 'DX_FLAG_DX_CURRENT_FEATURE'
# * DX_CLEAR_DEPEND : use of explicit variable 'DX_FLAG_DX_CURRENT_FEATURE'
# in AC_SUBST instead of 'DX_FLAG[]DX_CURRENT_FEATURE' which is rejected by
# newer autotools
# Generate automatic documentation using Doxygen. Works in concert with the
# aminclude.m4 file and a compatible doxygen configuration file. Defines the
# following public macros:
#
# DX_???_FEATURE(ON|OFF) - control the default setting fo a Doxygen feature.
# Supported features are 'DOXYGEN' itself, 'DOT' for generating graphics,
# 'HTML' for plain HTML, 'CHM' for compressed HTML help (for MS users), 'CHI'
# for generating a separate .chi file by the .chm file, and 'MAN', 'RTF',
# 'XML', 'PDF' and 'PS' for the appropriate output formats. The environment
# variable DOXYGEN_PAPER_SIZE may be specified to override the default 'a4wide'
# paper size.
#
# By default, HTML, PDF and PS documentation is generated as this seems to be
# the most popular and portable combination. MAN pages created by Doxygen are
# usually problematic, though by picking an appropriate subset and doing some
# massaging they might be better than nothing. CHM and RTF are specific for MS
# (note that you can't generate both HTML and CHM at the same time). The XML is
# rather useless unless you apply specialized post-processing to it.
#
# The macro mainly controls the default state of the feature. The use can
# override the default by specifying --enable or --disable. The macros ensure
# that contradictory flags are not given (e.g., --enable-doxygen-html and
# --enable-doxygen-chm, --enable-doxygen-anything with --disable-doxygen, etc.)
# Finally, each feature will be automatically disabled (with a warning) if the
# required programs are missing.
#
# Once all the feature defaults have been specified, call DX_INIT_DOXYGEN with
# the following parameters: a one-word name for the project for use as a
# filename base etc., an optional configuration file name (the default is
# 'Doxyfile', the same as Doxygen's default), and an optional output directory
# name (the default is 'doxygen-doc').
## ----------##
## Defaults. ##
## ----------##
DX_ENV=""
AC_DEFUN([DX_FEATURE_doc], ON)
AC_DEFUN([DX_FEATURE_dot], ON)
AC_DEFUN([DX_FEATURE_man], OFF)
AC_DEFUN([DX_FEATURE_html], ON)
AC_DEFUN([DX_FEATURE_chm], OFF)
AC_DEFUN([DX_FEATURE_chi], OFF)
AC_DEFUN([DX_FEATURE_rtf], OFF)
AC_DEFUN([DX_FEATURE_xml], OFF)
AC_DEFUN([DX_FEATURE_pdf], ON)
AC_DEFUN([DX_FEATURE_ps], ON)
## --------------- ##
## Private macros. ##
## --------------- ##
# DX_ENV_APPEND(VARIABLE, VALUE)
# ------------------------------
# Append VARIABLE="VALUE" to DX_ENV for invoking doxygen.
AC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], ["$DX_ENV $1='$2'"])])
# DX_DIRNAME_EXPR
# ---------------
# Expand into a shell expression prints the directory part of a path.
AC_DEFUN([DX_DIRNAME_EXPR],
[[expr ".$1" : '\(\.\)[^/]*$' \| "x$1" : 'x\(.*\)/[^/]*$']])
# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)
# -------------------------------------
# Expands according to the M4 (static) status of the feature.
AC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])
# DX_REQUIRE_PROG(VARIABLE, PROGRAM)
# ----------------------------------
# Require the specified program to be found for the DX_CURRENT_FEATURE to work.
AC_DEFUN([DX_REQUIRE_PROG], [
AC_PATH_TOOL([$1], [$2])
if test "$DX_FLAG_DX_CURRENT_FEATURE$$1" = 1; then
AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
fi
])
# DX_TEST_FEATURE(FEATURE)
# ------------------------
# Expand to a shell expression testing whether the feature is active.
AC_DEFUN([DX_TEST_FEATURE], [test "$DX_FLAG_$1" = 1])
# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)
# -------------------------------------------------
# Verify that a required features has the right state before trying to turn on
# the DX_CURRENT_FEATURE.
AC_DEFUN([DX_CHECK_DEPEND], [
test "$DX_FLAG_$1" = "$2" \
|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,
requires, contradicts) doxygen-DX_CURRENT_FEATURE])
])
# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)
# ----------------------------------------------------------
# Turn off the DX_CURRENT_FEATURE if the required feature is off.
AC_DEFUN([DX_CLEAR_DEPEND], [
test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_DX_CURRENT_FEATURE], 0)
])
# DX_FEATURE_ARG(FEATURE, DESCRIPTION,
# CHECK_DEPEND, CLEAR_DEPEND,
# REQUIRE, DO-IF-ON, DO-IF-OFF)
# --------------------------------------------
# Parse the command-line option controlling a feature. CHECK_DEPEND is called
# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),
# otherwise CLEAR_DEPEND is called to turn off the default state if a required
# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional
# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and
# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.
AC_DEFUN([DX_ARG_ABLE], [
AC_DEFUN([DX_CURRENT_FEATURE], [$1])
AC_DEFUN([DX_FLAG_DX_CURRENT_FEATURE], [DX_FLAG_$1])
AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])
AC_ARG_ENABLE(doxygen-$1,
[AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],
[--enable-doxygen-$1]),
DX_IF_FEATURE([$1], [don't $2], [$2]))],
[
case "$enableval" in
#(
y|Y|yes|Yes|YES)
AC_SUBST([DX_FLAG_$1], 1)
$3
;; #(
n|N|no|No|NO)
AC_SUBST([DX_FLAG_$1], 0)
;; #(
*)
AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])
;;
esac
], [
AC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])
$4
])
if DX_TEST_FEATURE([$1]); then
$5
:
fi
if DX_TEST_FEATURE([$1]); then
AM_CONDITIONAL(DX_COND_$1, :)
$6
:
else
AM_CONDITIONAL(DX_COND_$1, false)
$7
:
fi
])
## -------------- ##
## Public macros. ##
## -------------- ##
# DX_XXX_FEATURE(DEFAULT_STATE)
# -----------------------------
AC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc], [$1])])
AC_DEFUN([DX_MAN_FEATURE], [AC_DEFUN([DX_FEATURE_man], [$1])])
AC_DEFUN([DX_HTML_FEATURE], [AC_DEFUN([DX_FEATURE_html], [$1])])
AC_DEFUN([DX_CHM_FEATURE], [AC_DEFUN([DX_FEATURE_chm], [$1])])
AC_DEFUN([DX_CHI_FEATURE], [AC_DEFUN([DX_FEATURE_chi], [$1])])
AC_DEFUN([DX_RTF_FEATURE], [AC_DEFUN([DX_FEATURE_rtf], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_XML_FEATURE], [AC_DEFUN([DX_FEATURE_xml], [$1])])
AC_DEFUN([DX_PDF_FEATURE], [AC_DEFUN([DX_FEATURE_pdf], [$1])])
AC_DEFUN([DX_PS_FEATURE], [AC_DEFUN([DX_FEATURE_ps], [$1])])
# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])
# ---------------------------------------------------------
# PROJECT also serves as the base name for the documentation files.
# The default CONFIG-FILE is "Doxyfile" and OUTPUT-DOC-DIR is "doxygen-doc".
AC_DEFUN([DX_INIT_DOXYGEN], [
# Files:
AC_SUBST([DX_PROJECT], [$1])
AC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])
AC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])
# Environment variables used inside doxygen.cfg:
DX_ENV_APPEND(SRCDIR, $srcdir)
DX_ENV_APPEND(PROJECT, $DX_PROJECT)
DX_ENV_APPEND(DOCDIR, $DX_DOCDIR)
DX_ENV_APPEND(VERSION, $PACKAGE_VERSION)
# Doxygen itself:
DX_ARG_ABLE(doc, [generate any doxygen documentation],
[],
[],
[DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)
DX_REQUIRE_PROG([DX_PERL], perl)],
[DX_ENV_APPEND(PERL_PATH, $DX_PERL)])
# Dot for graphics:
DX_ARG_ABLE(dot, [generate graphics for doxygen documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_DOT], dot)],
[DX_ENV_APPEND(HAVE_DOT, YES)
DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],
[DX_ENV_APPEND(HAVE_DOT, NO)])
# Man pages generation:
DX_ARG_ABLE(man, [generate doxygen manual pages],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_MAN, YES)],
[DX_ENV_APPEND(GENERATE_MAN, NO)])
# RTF file generation:
DX_ARG_ABLE(rtf, [generate doxygen RTF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_RTF, YES)],
[DX_ENV_APPEND(GENERATE_RTF, NO)])
# XML file generation:
DX_ARG_ABLE(xml, [generate doxygen XML documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[],
[DX_ENV_APPEND(GENERATE_XML, YES)],
[DX_ENV_APPEND(GENERATE_XML, NO)])
# (Compressed) HTML help generation:
DX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_HHC], hhc)],
[DX_ENV_APPEND(HHC_PATH, $DX_HHC)
DX_ENV_APPEND(GENERATE_HTML, YES)
DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],
[DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])
# Separate CHI file generation.
DX_ARG_ABLE(chi, [generate doxygen separate compressed HTML help index file],
[DX_CHECK_DEPEND(chm, 1)],
[DX_CLEAR_DEPEND(chm, 1)],
[],
[DX_ENV_APPEND(GENERATE_CHI, YES)],
[DX_ENV_APPEND(GENERATE_CHI, NO)])
# Plain HTML pages generation:
DX_ARG_ABLE(html, [generate doxygen plain HTML documentation],
[DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],
[DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],
[],
[DX_ENV_APPEND(GENERATE_HTML, YES)],
[DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])
# PostScript file generation:
DX_ARG_ABLE(ps, [generate doxygen PostScript documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_LATEX], latex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_DVIPS], dvips)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# PDF file generation:
DX_ARG_ABLE(pdf, [generate doxygen PDF documentation],
[DX_CHECK_DEPEND(doc, 1)],
[DX_CLEAR_DEPEND(doc, 1)],
[DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)
DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)
DX_REQUIRE_PROG([DX_EGREP], egrep)])
# LaTeX generation for PS and/or PDF:
if DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then
AM_CONDITIONAL(DX_COND_latex, :)
DX_ENV_APPEND(GENERATE_LATEX, YES)
else
AM_CONDITIONAL(DX_COND_latex, false)
DX_ENV_APPEND(GENERATE_LATEX, NO)
fi
# Paper size for PS and/or PDF:
AC_ARG_VAR(DOXYGEN_PAPER_SIZE,
[a4wide (default), a4, letter, legal or executive])
case "$DOXYGEN_PAPER_SIZE" in
#(
"")
AC_SUBST(DOXYGEN_PAPER_SIZE, "")
;; #(
a4wide|a4|letter|legal|executive)
DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)
;; #(
*)
AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])
;;
esac
#For debugging:
#echo DX_FLAG_doc=$DX_FLAG_doc
#echo DX_FLAG_dot=$DX_FLAG_dot
#echo DX_FLAG_man=$DX_FLAG_man
#echo DX_FLAG_html=$DX_FLAG_html
#echo DX_FLAG_chm=$DX_FLAG_chm
#echo DX_FLAG_chi=$DX_FLAG_chi
#echo DX_FLAG_rtf=$DX_FLAG_rtf
#echo DX_FLAG_xml=$DX_FLAG_xml
#echo DX_FLAG_pdf=$DX_FLAG_pdf
#echo DX_FLAG_ps=$DX_FLAG_ps
#echo DX_ENV=$DX_ENV
])

186
vendor/liboqs/aminclude.am vendored Normal file
View File

@@ -0,0 +1,186 @@
# Copyright (C) 2004 Oren Ben-Kiki
# This file is distributed under the same terms as the Automake macro files.
# Generate automatic documentation using Doxygen. Goals and variables values
# are controlled by the various DX_COND_??? conditionals set by autoconf.
#
# The provided goals are:
# doxygen-doc: Generate all doxygen documentation.
# doxygen-run: Run doxygen, which will generate some of the documentation
# (HTML, CHM, CHI, MAN, RTF, XML) but will not do the post
# processing required for the rest of it (PS, PDF, and some MAN).
# doxygen-man: Rename some doxygen generated man pages.
# doxygen-ps: Generate doxygen PostScript documentation.
# doxygen-pdf: Generate doxygen PDF documentation.
#
# Note that by default these are not integrated into the automake goals. If
# doxygen is used to generate man pages, you can achieve this integration by
# setting man3_MANS to the list of man pages generated and then adding the
# dependency:
#
# $(man3_MANS): doxygen-doc
#
# This will cause make to run doxygen and generate all the documentation.
#
# The following variable is intended for use in Makefile.am:
#
# DX_CLEANFILES = everything to clean.
#
# This is usually added to MOSTLYCLEANFILES.
## --------------------------------- ##
## Format-independent Doxygen rules. ##
## --------------------------------- ##
if DX_COND_doc
## ------------------------------- ##
## Rules specific for HTML output. ##
## ------------------------------- ##
if DX_COND_html
DX_CLEAN_HTML = @DX_DOCDIR@/html
endif DX_COND_html
## ------------------------------ ##
## Rules specific for CHM output. ##
## ------------------------------ ##
if DX_COND_chm
DX_CLEAN_CHM = @DX_DOCDIR@/chm
if DX_COND_chi
DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi
endif DX_COND_chi
endif DX_COND_chm
## ------------------------------ ##
## Rules specific for MAN output. ##
## ------------------------------ ##
if DX_COND_man
DX_CLEAN_MAN = @DX_DOCDIR@/man
endif DX_COND_man
## ------------------------------ ##
## Rules specific for RTF output. ##
## ------------------------------ ##
if DX_COND_rtf
DX_CLEAN_RTF = @DX_DOCDIR@/rtf
endif DX_COND_rtf
## ------------------------------ ##
## Rules specific for XML output. ##
## ------------------------------ ##
if DX_COND_xml
DX_CLEAN_XML = @DX_DOCDIR@/xml
endif DX_COND_xml
## ----------------------------- ##
## Rules specific for PS output. ##
## ----------------------------- ##
if DX_COND_ps
DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps
DX_PS_GOAL = doxygen-ps
doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps
@DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag
cd @DX_DOCDIR@/latex; \
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
$(DX_LATEX) refman.tex; \
$(MAKEINDEX_PATH) refman.idx; \
$(DX_LATEX) refman.tex; \
countdown=5; \
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
refman.log > /dev/null 2>&1 \
&& test $$countdown -gt 0; do \
$(DX_LATEX) refman.tex; \
countdown=`expr $$countdown - 1`; \
done; \
$(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi
endif DX_COND_ps
## ------------------------------ ##
## Rules specific for PDF output. ##
## ------------------------------ ##
if DX_COND_pdf
DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf
DX_PDF_GOAL = doxygen-pdf
doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf
@DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag
cd @DX_DOCDIR@/latex; \
rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \
$(DX_PDFLATEX) refman.tex; \
$(DX_MAKEINDEX) refman.idx; \
$(DX_PDFLATEX) refman.tex; \
countdown=5; \
while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \
refman.log > /dev/null 2>&1 \
&& test $$countdown -gt 0; do \
$(DX_PDFLATEX) refman.tex; \
countdown=`expr $$countdown - 1`; \
done; \
mv refman.pdf ../@PACKAGE@.pdf
endif DX_COND_pdf
## ------------------------------------------------- ##
## Rules specific for LaTeX (shared for PS and PDF). ##
## ------------------------------------------------- ##
if DX_COND_latex
DX_CLEAN_LATEX = @DX_DOCDIR@/latex
endif DX_COND_latex
.PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)
.INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag
doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)
@DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)
rm -rf @DX_DOCDIR@
$(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)
DX_CLEANFILES = \
@DX_DOCDIR@/@PACKAGE@.tag \
-r \
$(DX_CLEAN_HTML) \
$(DX_CLEAN_CHM) \
$(DX_CLEAN_CHI) \
$(DX_CLEAN_MAN) \
$(DX_CLEAN_RTF) \
$(DX_CLEAN_XML) \
$(DX_CLEAN_PS) \
$(DX_CLEAN_PDF) \
$(DX_CLEAN_LATEX)
endif DX_COND_doc

9
vendor/liboqs/appveyor.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
version: 1.0.{build}
image: Visual Studio 2017
build:
verbosity: minimal
test_script:
- cmd: >-
C:\projects\liboqs\VisualStudio\x64\Debug\test_rand.exe
C:\projects\liboqs\VisualStudio\x64\Debug\test_kex.exe

0
vendor/liboqs/config/.gitkeep vendored Normal file
View File

39
vendor/liboqs/config/enable-disable.m4 vendored Normal file
View File

@@ -0,0 +1,39 @@
# ARG_ENABL_SET(option, help)
# ---------------------------
# Create a --enable-$1 option with helptext, set a variable $1 to true/false
# All $1 are collected in the variable $disabled_by_default
AC_DEFUN([ARG_ENABL_SET],
[AC_ARG_ENABLE(
[$1],
AS_HELP_STRING([--enable-$1], [$2]),
[patsubst([$1], [-], [_])_given=true
if test x$enableval = xyes; then
patsubst([$1], [-], [_])=true
else
patsubst([$1], [-], [_])=false
fi],
[patsubst([$1], [-], [_])=false
patsubst([$1], [-], [_])_given=false]
)
disabled_by_default=${disabled_by_default}" patsubst([$1], [-], [_])"]
)
# ARG_DISBL_SET(option, help)
# ---------------------------
# Create a --disable-$1 option with helptext, set a variable $1 to true/false
# All $1 are collected in the variable $enabled_by_default
AC_DEFUN([ARG_DISBL_SET],
[AC_ARG_ENABLE(
[$1],
AS_HELP_STRING([--disable-$1], [$2]),
[patsubst([$1], [-], [_])_given=true
if test x$enableval = xyes; then
patsubst([$1], [-], [_])=true
else
patsubst([$1], [-], [_])=false
fi],
[patsubst([$1], [-], [_])=true
patsubst([$1], [-], [_])_given=false]
)
enabled_by_default=${enabled_by_default}" patsubst([$1], [-], [_])"]
)

24
vendor/liboqs/config/with.m4 vendored Normal file
View File

@@ -0,0 +1,24 @@
# ARG_WITH_SUBST(option, default, help)
# -----------------------------------
# Create a --with-$1 option with helptext, AC_SUBST($1) to $withval/default
AC_DEFUN([ARG_WITH_SUBST],
[AC_ARG_WITH(
[$1],
AS_HELP_STRING([--with-$1=arg], [$3 (default: $2).]),
[AC_SUBST(patsubst([$1], [-], [_]), ["$withval"])],
[AC_SUBST(patsubst([$1], [-], [_]), ["$2"])]
)]
)
# ARG_WITH_SET(option, default, help)
# -----------------------------------
# Create a --with-$1 option with helptext, set a variable $1 to $withval/default
AC_DEFUN([ARG_WITH_SET],
[AC_ARG_WITH(
[$1],
AS_HELP_STRING([--with-$1=arg], [$3 (default: $2).]),
patsubst([$1], [-], [_])="$withval",
patsubst([$1], [-], [_])=$2
)]
)

56
vendor/liboqs/configure-android vendored Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/bash
HOST="aarch64-linux-android"
ANDROID_NDK_TOOLCHAIN_DIR=""
#parse arguments
for arg in "$@"
do
case $arg in
-h=*|--host=*)
HOST="${arg#*=}"
shift
;;
-t=*|--toolchain=*)
ANDROID_NDK_TOOLCHAIN_DIR="${arg#*=}"
shift
;;
esac
done
#validate arguments
function print_help {
cat << EOF
Usage: $0 [OPTION]... [VAR=VALUE]...
--host=HOST cross-compile to build programs to run on HOST [default: aarch64-linux-android]
--toolchain=DIR Android NDK standalone toolchain
Example usage: $0 --host=aarch64-linux-android --toolchain=/ram/arm
EOF
exit 0
}
if [[ ! -d $ANDROID_NDK_TOOLCHAIN_DIR ]]; then
print_help
fi
# configure
ANDROID_NDK_ROOT=${ANDROID_NDK_TOOLCHAIN_DIR}
ANDROID_NDK_BIN="${ANDROID_NDK_ROOT}/bin"
ANDROID_SYSROOT_DIR="${ANDROID_NDK_ROOT}/sysroot"
COMPILER_PREFIX=$HOST
export CC=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-gcc
export CPP=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-cpp
export CXX=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-g++
export LD=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-ld
export AR=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-ar
export RANLIB=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-ranlib
export STRIP=${ANDROID_NDK_BIN}/${COMPILER_PREFIX}-strip
./configure --host="${COMPILER_PREFIX}" --disable-aes-ni --with-sysroot="${ANDROID_SYSROOT_DIR}"

285
vendor/liboqs/configure.ac vendored Normal file
View File

@@ -0,0 +1,285 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
# Init
AC_INIT([liboqs], [1.0.0], [])
LT_INIT([disable-shared])
AM_INIT_AUTOMAKE([subdir-objects no-dependencies])
# Configure
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_SRCDIR([src/ds_benchmark.h])
AC_CONFIG_MACRO_DIRS([config])
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AM_PROG_AS
# Checks for libraries.
AC_ARG_WITH(
[openssl-dir],
AS_HELP_STRING([--with-openssl-dir=dir],[openssl dir used locally (default /usr).]),
[AC_DEFINE_UNQUOTED(OPENSSLDIR, [$withval], [OPENSSL DIR used locally])
AC_SUBST(OPENSSL_DIR, [$withval])],
[AC_SUBST(OPENSSL_DIR, /usr)]
)
AC_ARG_WITH(
[gmp-dir],
AS_HELP_STRING([--with-gmp-dir=dir],[gmp dir used locally (default /usr).]),
[AC_DEFINE_UNQUOTED(GMPDIR, [$withval], [GMP DIR used locally])
AC_SUBST(GMP_DIR, [$withval])],
[AC_SUBST(GMP_DIR, /usr)]
)
AC_ARG_WITH(
[sodium-dir],
AS_HELP_STRING([--with-sodium-dir=dir],[sodium dir used locally (default /usr).]),
[AC_DEFINE_UNQUOTED(SODIUMDIR, [$withval], [SODIUM DIR used locally])
AC_SUBST(SODIUM_DIR, [$withval])],
[AC_SUBST(SODIUM_DIR, /usr)]
)
AC_ARG_WITH(
[m4ri-dir],
AS_HELP_STRING([--with-m4ri-dir=dir],[m4ri dir used locally (default /usr).]),
[AC_DEFINE_UNQUOTED(M4RIDIR, [$withval], [M4RI DIR used locally])
AC_SUBST(M4RI_DIR, [$withval])],
[AC_SUBST(M4RI_DIR, /usr)]
)
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stddef.h stdint.h stdlib.h string.h strings.h sys/time.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_INT8_T
AC_TYPE_SIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_CHECK_FUNCS([gettimeofday memmove memset pow sqrt strdup])
AC_CHECK_SIZEOF([size_t])
# Silent rules
#m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
######################################################################
# DOXYGEN SUPPORT
######################################################################
DX_HTML_FEATURE(ON)
DX_CHM_FEATURE(OFF)
DX_CHI_FEATURE(OFF)
DX_MAN_FEATURE(OFF)
DX_RTF_FEATURE(OFF)
DX_XML_FEATURE(OFF)
DX_PDF_FEATURE(OFF)
DX_PS_FEATURE(OFF)
DX_INIT_DOXYGEN([$PACKAGE_NAME],[doxygen.cfg])
######################################################################
ARG_DISBL_SET([aes-ni], [enable AES-NI.])
AM_CONDITIONAL([aes_ni], [test "x$aes_ni" = xtrue])
AM_CONDITIONAL([USE_AES_NI], [test "x$aes_ni" = xtrue])
ARG_ENABL_SET([openssl], [enable OPENSSL.])
AM_CONDITIONAL([openssl], [test "x$openssl" = xtrue])
AM_CONDITIONAL([USE_OPENSSL], [test "x$openssl" = xtrue])
ARG_ENABL_SET([kex-code-mcbits], [enable KEX-CODE-MCBITS.])
AM_CONDITIONAL([kex_code_mcbits], [test "x$kex_code_mcbits" = xtrue])
AM_CONDITIONAL([USE_MCBITS], [test "x$kex_code_mcbits" = xtrue])
ARG_ENABL_SET([picnic], [enable PICNIC.])
AM_CONDITIONAL([picnic], [test "x$picnic" = xtrue])
AM_CONDITIONAL([USE_PICNIC], [test "x$picnic" = xtrue])
ARG_ENABL_SET([kex-sidh-iqc-ref], [enable KEX-SIDH-IQC-REF.])
AM_CONDITIONAL([kex_sidh_iqc_ref], [test "x$kex_sidh_iqc_ref" = xtrue])
AM_CONDITIONAL([USE_SIDH_IQC], [test "x$kex_sidh_iqc_ref" = xtrue])
ARG_DISBL_SET([kex-lwe-frodo], [disable KEX-LWE-FRODO.])
AM_CONDITIONAL([kex_lwe_frodo], [test "x$kex_lwe_frodo" = xtrue])
AM_CONDITIONAL([USE_KEX_LWE_FRODO], [test "x$kex_lwe_frodo" = xtrue])
ARG_DISBL_SET([kex-mlwe-kyber], [disable KEX-MLWE-KYBER.])
AM_CONDITIONAL([kex_mlwe_kyber], [test "x$kex_mlwe_kyber" = xtrue])
AM_CONDITIONAL([USE_KEX_MLWE_KYBER], [test "x$kex_mlwe_kyber" = xtrue])
ARG_DISBL_SET([kex-ntru], [disable KEX-NTRU.])
AM_CONDITIONAL([kex_ntru], [test "x$kex_ntru" = xtrue])
AM_CONDITIONAL([USE_KEX_NTRU], [test "x$kex_ntru" = xtrue])
ARG_DISBL_SET([kex-rlwe-msrln16], [disable KEX-RLWE-MSRLN16.])
AM_CONDITIONAL([kex_rlwe_msrln16], [test "x$kex_rlwe_msrln16" = xtrue])
AM_CONDITIONAL([USE_KEX_RLWE_MSRLN16], [test "x$kex_rlwe_msrln16" = xtrue])
ARG_DISBL_SET([kex-rlwe-newhope], [disable KEX-RLWE-NEWHOPE.])
AM_CONDITIONAL([kex_rlwe_newhope], [test "x$kex_rlwe_newhope" = xtrue])
AM_CONDITIONAL([USE_KEX_RLWE_NEWHOPE], [test "x$kex_rlwe_newhope" = xtrue])
ARG_DISBL_SET([kex-sidh-cln16], [disable KEX-SIDH-CLN16.])
AM_CONDITIONAL([kex_sidh_cln16], [test "x$kex_sidh_cln16" = xtrue])
AM_CONDITIONAL([USE_KEX_SIDH_CLN16], [test "x$kex_sidh_cln16" = xtrue])
AC_CANONICAL_HOST
# Check for which host we are on and setup a few things
# specifically based on the host
case $host_os in
darwin* )
darwin=true
;;
linux-android*)
AM_CFLAGS=${AM_CFLAGS}" -pie "
linux=true
;;
linux*)
linux=true
;;
*)
#Default Case
AC_MSG_ERROR([Your platform is not currently supported])
;;
esac
AM_CONDITIONAL([ON_DARWIN], [test "x$darwin" = xtrue])
# Enable assembly optimizations here
# Appearenly asm optimizations do not work well with darwin
if test x"$linux" = x"true"; then
case $host_cpu in
x86_64* )
AM_CPPFLAGS=${AM_CPPFLAGS}" -DSIDH_ASM -march=x86-64"
x86_64=true
;;
aarch64* )
AM_CPPFLAGS=${AM_CPPFLAGS}" -DSIDH_ASM -march=armv8-a+crc"
arm64=true
;;
esac
fi
AM_CONDITIONAL([X86_64], [test "x$x86_64" = xtrue])
AM_CONDITIONAL([ARM64], [test "x$arm64" = xtrue])
# Common sources
SRCDIR=" src/common"
# Crypto sources
SRCDIR=${SRCDIR}" src/crypto/aes src/crypto/rand src/crypto/sha3 src/crypto/rand_urandom_aesctr src/crypto/rand_urandom_chacha20"
# KEX
SRCDIR=${SRCDIR}" src/kex"
SRCDIR=${SRCDIR}" src/kex_rlwe_bcns15"
if test x"$kex_lwe_frodo" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_lwe_frodo"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_LWE_FRODO"
fi
if test x"$kex_mlwe_kyber" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_mlwe_kyber"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_MLWE_KYBER"
fi
if test x"$kex_ntru" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_ntru"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_NTRU"
fi
if test x"$kex_rlwe_msrln16" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_rlwe_msrln16"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_RLWE_MSRLN16"
fi
if test x"$kex_rlwe_newhope" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_rlwe_newhope"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_RLWE_NEWHOPE"
fi
if test x"$kex_sidh_cln16" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_sidh_cln16"
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_KEX_SIDH_CLN16"
fi
SRCDIR=${SRCDIR}" src/sig"
# Conditional KEX
if test x"$kex_code_mcbits" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_code_mcbits"
fi
if test x"$kex_sidh_iqc_ref" = x"true"; then
SRCDIR=${SRCDIR}" src/kex_sidh_iqc_ref"
fi
# Flags
AM_CPPFLAGS=${AM_CPPFLAGS}" -g -std=gnu11 -Wno-unused-function -Werror -Wpedantic -Wall -Wextra -DCONSTANT_TIME"
if test x"$aes_ni" = x"true"; then
AM_CPPFLAGS=${AM_CPPFLAGS}" -DAES_ENABLE_NI"
fi
if test x"$openssl" = x"true"; then
AM_CPPFLAGS=${AM_CPPFLAGS}" -DUSE_OPENSSL"
fi
if test x"$kex_code_mcbits" = x"true"; then
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_CODE_MCBITS"
fi
if test x"$kex_sidh_iqc_ref" = x"true"; then
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_SIDH_IQC_REF"
SRCDIR=${SRCDIR}" src/kex_sidh_iqc_ref"
fi
if test x"$picnic" = x"true"; then
AM_CPPFLAGS=${AM_CPPFLAGS}" -DENABLE_PICNIC"
SRCDIR=${SRCDIR}" src/sig_picnic"
fi
AC_SUBST(AM_CPPFLAGS)
AC_SUBST(AM_CFLAGS)
AC_SUBST(SRCDIR)
AC_SUBST(USE_OPENSSL)
AC_SUBST(USE_AES_NI)
AC_SUBST(USE_KEX_NTRU)
AC_SUBST(USE_MCBITS)
AC_SUBST(USE_SIDH_IQC)
AC_SUBST(USE_KEX_LWE_FRODO)
AC_SUBST(USE_KEX_MLWE_KYBER)
AC_SUBST(USE_KEX_RLWE_MSRLN16)
AC_SUBST(USE_KEX_RLWE_NEWHOPE)
AC_SUBST(USE_KEX_SIDH_CLN16)
AC_SUBST(USE_PICNIC)
AC_SUBST(ON_DARWIN)
AC_SUBST(X86_64)
AC_CONFIG_FILES([Makefile
src/common/Makefile
src/kex/Makefile
src/crypto/sha3/Makefile
src/crypto/rand/Makefile
src/crypto/rand_urandom_chacha20/Makefile
src/crypto/rand_urandom_aesctr/Makefile
src/crypto/aes/Makefile
src/kex_rlwe_bcns15/Makefile
src/kex_rlwe_newhope/Makefile
src/kex_rlwe_msrln16/Makefile
src/kex_sidh_cln16/Makefile
src/kex_code_mcbits/Makefile
src/kex_ntru/Makefile
src/kex_sidh_iqc_ref/Makefile
src/kex_lwe_frodo/Makefile
src/sig/Makefile
src/sig_picnic/Makefile
src/kex_mlwe_kyber/Makefile])
AC_OUTPUT

View File

@@ -0,0 +1,60 @@
Algorithm data sheet: `kex_lwe_frodo`
=======================================
Algorithm
---------
**Name:** Frodo
**Description:** Key exchange protocol proposed by Bos et al. [BCDMNNRS16] based on the ring learning with errors problem. Instantiation of the Lindner–Peikert approximate LWE key agreement scheme [LP10], which was an adaptation of the LWE public key encryption scheme of in public key encryption scheme of Regev [Reg05], using reconciliation mechanism of Peikert [Pei14].
**Supporting research:**
- [BCDMNNRS16] Joppe Bos, Craig Costello, Léo Ducas, Ilya Mironov, Michael Naehrig, Valeria Nikolaenko, Ananth Raghunathan, Douglas Stebila. Frodo: Take off the ring! Practical, quantum-secure key exchange from LWE. In *Proc. 23rd ACM Conference on Computer and Communications Security (CCS) 2016*, pp. 1006-1018. ACM, October 2016. [https://eprint.iacr.org/2016/659](https://eprint.iacr.org/2016/659)
- [Pei14] Chris Peikert. Lattice cryptography for the Internet. In *PQCrypto 2014*, volume 8772 of LNCS, pages 197–219. Springer, 2014. [https://eprint.iacr.org/2014/070](https://eprint.iacr.org/2014/070)
- [LP10] Richard Lindner and Chris Peikert. Better key sizes (and attacks) for LWE-based encryption. In *Proc. CT-RSA 2011*, *LNCS*, vol. 6558, pp. 319–339. Springer, February 2011. [https://eprint.iacr.org/2010/613](https://eprint.iacr.org/2010/613)
- [Reg05] Oded Regev. On lattices, learning with errors, random linear codes, and cryptography. In *Proc. 37th ACM STOC*, pp. 84–93. ACM Press, May 2005.
Security
--------
**Security model:** Unauthenticated key exchange / passive (IND-CPA) key encapsulation mechanism
**Underlying hard problem(s):** Decision learning with errors problem
Parameter set 1
---------------
"Recommended" parameter set from [BCDMNNRS16]
**Claimed classical security:**
- 2^144 (original paper)
**Claimed quantum security:**
- 2^130 (original paper)
**Communication size:**
- Alice → Bob: 11,377 bytes
- Bob → Alice: 11,296 bytes
- total: 22,673 bytes
Implementation
--------------
**Source of implementation:** Original research paper ([https://github.com/lwe-frodo/lwe-frodo](https://github.com/lwe-frodo/lwe-frodo))
**License:** MIT License
**Language:** C
**Constant-time:** Yes
**Testing:**
- Correctness: covered by test harness `test_kex`
- Statistics of shared secrets: covered by test harness `test_kex`
- Static analysis:
- `scan_build`

View File

@@ -0,0 +1,80 @@
Algorithm data sheet: `kex_rlwe_bcns15`
=======================================
Algorithm
---------
**Name:** BCNS15
**Description:** Key exchange protocol proposed by Bos et al. [BCNS15] based on the ring learning with errors problem. Instantiation of the approximate KEM in public key encryption scheme of Lyubashevsky, Peikert, Regev [LPR10], using reconciliation mechanism of Peikert [Pei14].
**Supporting research:**
- [BCNS15] Joppe W. Bos, Craig Costello, Michael Naehrig, Douglas Stebila. Post-quantum key exchange for the TLS protocol from the ring learning with errors problem. In *IEEE Symposium on Security and Privacy (S&P) 2015*, pp. 553-570. IEEE, May 2015. [https://eprint.iacr.org/2014/599](https://eprint.iacr.org/2014/599)
- [Pei14] Chris Peikert. Lattice cryptography for the Internet. In *PQCrypto 2014*, volume 8772 of LNCS, pages 197–219. Springer, 2014. [https://eprint.iacr.org/2014/070](https://eprint.iacr.org/2014/070)
- [LPR10] Vadim Lyubashevsky, Chris Peikert, and Oded Regev. On ideal lattices and learning with errors over rings. In *EUROCRYPT 2010*, volume 6110 of LNCS, pages 1–23. Springer, May 2010. [https://eprint.iacr.org/2012/230](https://eprint.iacr.org/2012/230)
Security
--------
**Security model:** Unauthenticated key exchange / passive (IND-CPA) key encapsulation mechanism
**Underlying hard problem(s):** Decision ring learning with errors problem
Parameter set 1
---------------
**Claimed classical security:**
- 2^163.8 (original paper)
- 2^86 ([https://eprint.iacr.org/2015/1092](https://eprint.iacr.org/2015/1092))
**Claimed quantum security:**
- ≥ 2^81.9 (original paper)
- 2^78 ([https://eprint.iacr.org/2015/1092](https://eprint.iacr.org/2015/1092))
**Communication size:**
- Alice → Bob: 4,096 bytes
- Bob → Alice: 4,224 bytes
- total: 8,320 bytes
Implementation
--------------
**Source of implementation:** Original research paper ([https://github.com/dstebila/rlwekex](https://github.com/dstebila/rlwekex))
**License:** Public domain ("Unlicense", [http://unlicense.org](http://unlicense.org))
**Language:** C
**Constant-time:** When preprocessor macro `CONSTANT_TIME` is defined
**Options:**
- preprocessor macro `CONSTANT_TIME` to enable constant-time code
**Testing:**
- Correctness: covered by test harness `test_kex`
- Statistics of shared secrets: covered by test harness `test_kex`
- statistical distance from uniform over 100 iterations: 0.0561185025
- Static analysis:
- `scan_build`
**Runtime:**
Operation | Iterations | Total time (s) | Time (us): mean | pop. stdev | CPU cycles: mean | pop. stdev
------------------------------ | ----------:| --------------:| ---------------:| ----------:| ----------------:| ----------:
alice 0 | 17664 | 10.000 | 566.145 | 24.189 | 2269004 | 96901
bob | 10923 | 10.001 | 915.562 | 53.806 | 3669454 | 215632
alice 1 | 86154 | 10.000 | 116.071 | 13.987 | 465102 | 56014
Runtime measurement configuration:
- CPU: Intel Core i7 (6700K "Skylake") with 4 cores each running at 4.0 GHz; single-threaded runtime measurements
- TurboBoost and hyperthreading (hardware multithreading): disabled
- liboqs version: commit [c5382941aecc85df90b9179458c9fba7a9f45611](https://github.com/open-quantum-safe/liboqs/commit/c5382941aecc85df90b9179458c9fba7a9f45611)
- compiler: gcc-6 (Homebrew gcc 6.2.0) 6.2.0
- build command: make CC=gcc-6

View File

@@ -0,0 +1,68 @@
Algorithm data sheet: `kex_sidh_cln16`
======================================
Algorithm
---------
**Name:** SIDH CLN16
**Description:**
The Supersingular Isogeny Diffie-Hellman (SIDH) key exchange protocol was proposed by Jao and DeFeo in [JD11]. The mathematical structures that provide the key exchange operations are supersingular elliptic curves and isogeny maps between them. Despite the use of elliptic curves, its security is not based on the hardness of the elliptic curve discrete logarithm problem, but instead on the hardness of computing large-degree isogenies between two given elliptic curves, believed to be resistant to quantum computers.
The library, provided by Microsoft Research, implements the algorithms of Costello, Longa, and Naehrig [CLN16], including public key compression algorithms of [CJLNRU17]. It is fully protected against timing and cache attacks: all operations on secret data run in constant time. More details at [https://www.microsoft.com/en-us/research/project/sidh-library/#].
The chosen parameters aim to provide 128 bits of security against attackers running a large-scale quantum computer, and 192 bits of security against classical algorithms. SIDH has the option of a hybrid key exchange that combines supersingular isogeny Diffie-Hellman with a high-security classical elliptic curve Diffie-Hellman key exchange at a small overhead.
SIDH is the first supersingular isogeny Diffie-Hellman software that is fully protected against timing and cache attacks: all operations on secret data run in constant time. The library is also significantly faster than previous implementations, e.g., it is about 3 times faster than the previously best (non-constant-time) supersingular isogeny Diffie-Hellman software.
**Supporting research:**
- [CLN16] Craig Costello, Patrick Longa, and Michael Naehrig. Efficient algorithms for supersingular isogeny Diffie-Hellman, available at [http://eprint.iacr.org/2016/413].
- [JD11] David Jao and Luca DeFeo. Towards quantum-resistant cryptosystems from supersingular elliptic curve isogenies, in PQCrypto 2011, LNCS 7071, pp. 19-34, 2011.
- [CJLNRU17] Craig Costello, David Jao, Patrick Longa, Michael Naehrig, Joost Renes, and David Urbanik. Efficient compression of SIDH public keys. Advances in Cryptology EUROCRYPT 2017, LNCS 10210, pp. 679-706, 2017. The preprint version is available at [http://eprint.iacr.org/2016/963].
Security
--------
**Security model:** Unauthenticated key exchange / passive (IND-CPA) key encapsulation mechanism
**Underlying hard problem(s):** hardness of computing large-degree isogenies between two given elliptic curves
Parameter set 1
---------------
"Recommended" parameter set from [CLN16]
**Claimed classical security:**
- 2^192 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Communication size:**
- Alice → Bob: 564 bytes (uncompressed), 330 bytes (compressed)
- Bob → Alice: 564 bytes (uncompressed), 330 bytes (compressed)
- total: 1128 bytes (uncompressed), 660 bytes (compressed)
Implementation
--------------
**Source of implementation:** Original research paper ([https://github.com/Microsoft/PQCrypto-SIDH](https://github.com/Microsoft/PQCrypto-SIDH))
**License:** MIT License
**Language:** C
**Constant-time:** Yes
**Testing:**
- Correctness: covered by test harness `test_kex`
- Statistics of shared secrets: covered by test harness `test_kex`
- Static analysis:
- `scan_build`

View File

@@ -0,0 +1,159 @@
Algorithm data sheet: `sig_picnic`
==================================
Algorithm
---------
**Name:** Picnic
**Description:**
Picnic is a post-quantum digital signature scheme that: (a) derives its security from the security of symmetric-key primitives, believed to be quantum-secure, and (b) has extremely small keypairs, and, (c) is highly parametrizable.
The public key is an image y=f(x) of a one-way function f (the block cipher LowMC) and the secret key is x. A signature is a non-interactive zero-knowledge proof of x, that incorporates a message to be signed. For this proof, improvements to the recent progress of Giacomelli et al. (USENIX'16) in constructing an efficient sigma protocol for statements over general circuits are leveraged, resulting in smaller signature sizes.
Two mechanisms for making the proof non-interactive can be used: the Fiat-Shamir transform, and Unruh's transform (EUROCRYPT'12,'15,'16). The former has smaller signatures, while the latter has a security analysis in the quantum-accessible random oracle model. By customizing Unruh's transform, the overhead is reduced to 1.6x when compared to the Fiat-Shamir transform.
**Supporting research:**
- [CDGORRSZ] Melissa Chase, David Derler, Steven Goldfeder, Claudio Orlandi, Sebastian Ramacher, Christian Rechberger, Daniel Slamanig, and Greg Zaverucha. Post-Quantum Zero-Knowledge and Signatures from Symmetric-Key Primitives, Proceedings of ACM CCS 2017, and available at [http://eprint.iacr.org/2017/279].
Security
--------
**Security model:** existential unforgeability in the random oracle model (ROM), or quantum
random oracle model (QROM).
**Underlying hard problem(s):** hash function security (ROM/QROM), key recovery attacks on the lowMC
block cipher
Parameter set 1
---------------
"Picnic_1_316_FS" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 103464 bytes
Parameter set 2
---------------
"Picnic_1_316_UR" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 174434 bytes
Parameter set 3
---------------
"Picnic_10_38_FS" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 114264 bytes
Parameter set 4
---------------
"Picnic_10_38_UR" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 195458 bytes
Parameter set 5
---------------
"Picnic_42_14_FS" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 148236 bytes
Parameter set 6
---------------
"Picnic_42_14_UR" parameter set from [CDGORRSZ]
**Claimed classical security:**
- 2^256 (original paper)
**Claimed quantum security:**
- 2^128 (original paper)
**Data sizes:**
- Private key: 130 bytes
- Public key: 65 bytes
- Signature: 263786 bytes
Implementation
--------------
**Source of implementation:** Original research paper ([https://github.com/Microsoft/Picnic](https://github.com/Microsoft/Picnic))
**License:** MIT License
**Language:** C
**Constant-time:** Yes
**Testing:**
- Correctness: covered by test harness `test_sig`
- Statistics of signatures: covered by test harness `test_sig`
- Static analysis:
- `scan_build`

9
vendor/liboqs/download-and-setup-picnic.sh vendored Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
mkdir -p src/sig_picnic/external
cd src/sig_picnic/external
wget https://github.com/Microsoft/Picnic/archive/master.zip
unzip master
cd Picnic-master

59
vendor/liboqs/kex_bench_memory.sh vendored Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
# This script outputs kex memory benchmarks using valgrind
DEFAULT_TMP_DIR=/tmp
TMP_DIR=$DEFAULT_TMP_DIR
ALGORITHMS=""
ROOT_DIR=`dirname $0`
TEST_KEX_CMD=$ROOT_DIR/test_kex
#check for installed programs
for prog in valgrind ms_print $TEST_KEX_CMD
do
command -v $prog >/dev/null 2>&1 || { echo >&2 "Command $prog was not found. Aborting."; exit 1; }
done
#parse arguments
for arg in "$@"
do
case $arg in
-tmp-dir=*|-t=*)
TMP_DIR="${arg#*=}"
shift
;;
*)
ALGORITHMS="$ALGORITHMS $arg"
;;
esac
done
function print_help {
cat << EOF
Usage: $0 [OPTION]... ALGORITHM
--tmp-dir=DIR temporary directory [default: $DEFAULT_TMP_DIR]
ALGORITHM algorithm to test
Example usage: $0 ntru
EOF
exit 0
}
if [[ ! -d $TMP_DIR ]]; then
print_help
fi
TMP_FILE_NAME="oqs_mem_bench"
TMP_FILE_PATH=$TMP_DIR/$TMP_FILE_NAME
rm -f $TMP_FILE_PATH
valgrind --tool=massif --massif-out-file=$TMP_FILE_PATH $TEST_KEX_CMD -m $ALGORITHMS
ms_print $TMP_FILE_PATH
rm -f $TMP_FILE_PATH

8
vendor/liboqs/src/common/Makefile.am vendored Normal file
View File

@@ -0,0 +1,8 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = common.c
libcommon_la_CPPFLAGS = -I../../include
libcommon_la_CPPFLAGS += $(AM_CPPFLAGS)

28
vendor/liboqs/src/common/common.c vendored Normal file
View File

@@ -0,0 +1,28 @@
#include <oqs/common.h>
#include <string.h>
#if defined(WINDOWS)
#include <windows.h>
#endif
void OQS_MEM_cleanse(void *ptr, size_t len) {
#if defined(WINDOWS)
SecureZeroMemory(ptr, len);
#elif defined(HAVE_MEMSET_S)
if (0U < len && memset_s(ptr, (rsize_t) len, 0, (rsize_t) len) != 0) {
abort();
}
#else
typedef void *(*memset_t)(void *, int, size_t);
static volatile memset_t memset_func = memset;
memset_func(ptr, 0, len);
#endif
}
void OQS_MEM_secure_free(void *ptr, size_t len) {
if (ptr != NULL) {
OQS_MEM_cleanse(ptr, len);
free(ptr);
}
}

19
vendor/liboqs/src/common/common.h vendored Normal file
View File

@@ -0,0 +1,19 @@
#ifndef __OQS_COMMON_H
#define __OQS_COMMON_H
#include <stdlib.h>
#define OQS_SUCCESS 1
#define OQS_ERROR 0
void OQS_MEM_cleanse(void *ptr, size_t len);
void OQS_MEM_secure_free(void *ptr, size_t len);
#if __ANDROID__
//android workaround
#define eprintf(...) printf(__VA_ARGS__);
#else
#define eprintf(...) fprintf(stderr, __VA_ARGS__);
#endif
#endif

View File

@@ -0,0 +1,18 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libaes.la
libaes_la_SOURCES = aes.c
libaes_la_CPPFLAGS = -I../../../include
if USE_OPENSSL
libaes_la_CPPFLAGS += -I$(OPENSSL_DIR)/include
endif
if USE_AES_NI
libaes_la_CPPFLAGS += -maes -msse2
libaes_la_SOURCES += aes_ni.c
endif
libaes_la_SOURCES += aes_c.c
libaes_la_CPPFLAGS += $(AM_CPPFLAGS)

194
vendor/liboqs/src/crypto/aes/aes.c vendored Normal file
View File

@@ -0,0 +1,194 @@
#include <assert.h>
#include "aes.h"
#include "aes_local.h"
void OQS_AES128_load_schedule(const uint8_t *key, void **schedule, int for_encryption) {
#ifdef USE_OPENSSL
oqs_aes128_load_schedule_ossl(key, schedule, for_encryption);
#else
for_encryption++; // need some dummy operation to avoid unused parameter warning
#ifdef AES_ENABLE_NI
oqs_aes128_load_schedule_ni(key, schedule);
#else
oqs_aes128_load_schedule_c(key, schedule);
#endif
#endif
}
void OQS_AES128_free_schedule(void *schedule) {
#ifdef USE_OPENSSL
oqs_aes128_free_schedule_ossl(schedule);
#else
#ifdef AES_ENABLE_NI
oqs_aes128_free_schedule_ni(schedule);
#else
oqs_aes128_free_schedule_c(schedule);
#endif
#endif
}
void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
#ifdef USE_OPENSSL
oqs_aes128_ecb_enc_ossl(plaintext, plaintext_len, key, ciphertext);
#else
#ifdef AES_ENABLE_NI
oqs_aes128_ecb_enc_ni(plaintext, plaintext_len, key, ciphertext);
#else
oqs_aes128_ecb_enc_c(plaintext, plaintext_len, key, ciphertext);
#endif
#endif
}
void OQS_AES128_ECB_dec(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext) {
#ifdef USE_OPENSSL
oqs_aes128_ecb_dec_ossl(ciphertext, ciphertext_len, key, plaintext);
#else
#ifdef AES_ENABLE_NI
oqs_aes128_ecb_dec_ni(ciphertext, ciphertext_len, key, plaintext);
#else
oqs_aes128_ecb_dec_c(ciphertext, ciphertext_len, key, plaintext);
#endif
#endif
}
void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
#ifdef USE_OPENSSL
oqs_aes128_ecb_enc_sch_ossl(plaintext, plaintext_len, schedule, ciphertext);
#else
#ifdef AES_ENABLE_NI
oqs_aes128_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext);
#else
oqs_aes128_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext);
#endif
#endif
}
void OQS_AES128_ECB_dec_sch(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext) {
#ifdef USE_OPENSSL
oqs_aes128_ecb_dec_sch_ossl(ciphertext, ciphertext_len, schedule, plaintext);
#else
#ifdef AES_ENABLE_NI
oqs_aes128_ecb_dec_sch_ni(ciphertext, ciphertext_len, schedule, plaintext);
#else
oqs_aes128_ecb_dec_sch_c(ciphertext, ciphertext_len, schedule, plaintext);
#endif
#endif
}
#ifdef AES_ENABLE_NI
inline void oqs_aes128_ecb_enc_ni(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
void *schedule = NULL;
oqs_aes128_load_schedule_ni(key, &schedule);
oqs_aes128_ecb_enc_sch_ni(plaintext, plaintext_len, schedule, ciphertext);
oqs_aes128_free_schedule_ni(schedule);
}
#endif
inline void oqs_aes128_ecb_enc_c(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
void *schedule = NULL;
oqs_aes128_load_schedule_c(key, &schedule);
oqs_aes128_ecb_enc_sch_c(plaintext, plaintext_len, schedule, ciphertext);
oqs_aes128_free_schedule_c(schedule);
}
#ifdef AES_ENABLE_NI
inline void oqs_aes128_ecb_enc_sch_ni(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
assert(plaintext_len % 16 == 0);
for (size_t block = 0; block < plaintext_len / 16; block++) {
oqs_aes128_enc_ni(plaintext + (16 * block), schedule, ciphertext + (16 * block));
}
}
#endif
inline void oqs_aes128_ecb_enc_sch_c(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
assert(plaintext_len % 16 == 0);
for (size_t block = 0; block < plaintext_len / 16; block++) {
oqs_aes128_enc_c(plaintext + (16 * block), schedule, ciphertext + (16 * block));
}
}
#ifdef AES_ENABLE_NI
inline void oqs_aes128_ecb_dec_ni(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext) {
void *schedule = NULL;
oqs_aes128_load_schedule_ni(key, &schedule);
oqs_aes128_ecb_dec_sch_ni(ciphertext, ciphertext_len, schedule, plaintext);
oqs_aes128_free_schedule_ni(schedule);
}
#endif
inline void oqs_aes128_ecb_dec_c(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext) {
void *schedule = NULL;
oqs_aes128_load_schedule_c(key, &schedule);
oqs_aes128_ecb_dec_sch_c(ciphertext, ciphertext_len, schedule, plaintext);
oqs_aes128_free_schedule_c(schedule);
}
#ifdef AES_ENABLE_NI
inline void oqs_aes128_ecb_dec_sch_ni(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext) {
assert(ciphertext_len % 16 == 0);
for (size_t block = 0; block < ciphertext_len / 16; block++) {
oqs_aes128_dec_ni(ciphertext + (16 * block), schedule, plaintext + (16 * block));
}
}
#endif
inline void oqs_aes128_ecb_dec_sch_c(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext) {
assert(ciphertext_len % 16 == 0);
for (size_t block = 0; block < ciphertext_len / 16; block++) {
oqs_aes128_dec_c(ciphertext + (16 * block), schedule, plaintext + (16 * block));
}
}
#ifdef USE_OPENSSL
#include <openssl/evp.h>
inline void oqs_aes128_load_schedule_ossl(const uint8_t *key, void **schedule, int for_encryption) {
EVP_CIPHER_CTX *aes_ctx = EVP_CIPHER_CTX_new();
assert(aes_ctx != NULL);
if (for_encryption) {
assert(1 == EVP_EncryptInit_ex(aes_ctx, EVP_aes_128_ecb(), NULL, key, NULL));
} else {
assert(1 == EVP_DecryptInit_ex(aes_ctx, EVP_aes_128_ecb(), NULL, key, NULL));
}
EVP_CIPHER_CTX_set_padding(aes_ctx, 0);
*schedule = aes_ctx;
}
inline void oqs_aes128_free_schedule_ossl(void *schedule) {
if (schedule != NULL) {
EVP_CIPHER_CTX_free((EVP_CIPHER_CTX *) schedule);
}
}
inline void oqs_aes128_ecb_enc_ossl(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
void *schedule = NULL;
oqs_aes128_load_schedule_ossl(key, &schedule, 1);
oqs_aes128_ecb_enc_sch_ossl(plaintext, plaintext_len, schedule, ciphertext);
oqs_aes128_free_schedule_ossl(schedule);
}
inline void oqs_aes128_ecb_dec_ossl(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext) {
void *schedule = NULL;
oqs_aes128_load_schedule_ossl(key, &schedule, 0);
oqs_aes128_ecb_dec_sch_ossl(ciphertext, ciphertext_len, schedule, plaintext);
oqs_aes128_free_schedule_ossl(schedule);
}
inline void oqs_aes128_ecb_enc_sch_ossl(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
assert(plaintext_len % 16 == 0);
int outlen;
assert(1 == EVP_EncryptUpdate((EVP_CIPHER_CTX *) schedule, ciphertext, &outlen, plaintext, plaintext_len));
assert((size_t) outlen == plaintext_len);
assert(1 == EVP_EncryptFinal_ex((EVP_CIPHER_CTX *) schedule, ciphertext, &outlen));
}
inline void oqs_aes128_ecb_dec_sch_ossl(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext) {
assert(ciphertext_len % 16 == 0);
int outlen;
assert(1 == EVP_DecryptUpdate((EVP_CIPHER_CTX *) schedule, plaintext, &outlen, ciphertext, ciphertext_len));
assert((size_t) outlen == ciphertext_len);
assert(1 == EVP_DecryptFinal_ex((EVP_CIPHER_CTX *) schedule, plaintext, &outlen));
}
#endif

66
vendor/liboqs/src/crypto/aes/aes.h vendored Normal file
View File

@@ -0,0 +1,66 @@
/**
* \file aes.h
* \brief Header defining the API for OQS AES
*/
#ifndef __OQS_AES_H
#define __OQS_AES_H
#include <stdint.h>
#include <stdlib.h>
/**
* Function to fill a key schedule given an initial key.
*
* @param key Initial Key.
* @param schedule Abstract data structure for a key schedule.
* @param forEncryption 1 if key schedule is for encryption, 0 if for decryption.
*/
void OQS_AES128_load_schedule(const uint8_t *key, void **schedule, int for_encryption);
/**
* Function to free a key schedule.
*
* @param schedule Schedule generated with OQS_AES128_load_schedule().
*/
void OQS_AES128_free_schedule(void *schedule);
/**
* Function to encrypt blocks of plaintext using ECB mode.
* A schedule based on the key is generated and used internally.
*
* @param plaintext Plaintext to be encrypted.
* @param plaintext_len Length on the plaintext in bytes. Must be a multiple of 16.
* @param key Key to be used for encryption.
* @param ciphertext Pointer to a block of memory which >= in size to the plaintext block. The result will be written here.
*/
void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext);
/**
* Function to decrypt blocks of plaintext using ECB mode.
* A schedule based on the key is generated and used internally.
*
* @param ciphertext Ciphertext to be decrypted.
* @param ciphertext_len Length on the ciphertext in bytes. Must be a multiple of 16.
* @param key Key to be used for encryption.
* @param ciphertext Pointer to a block of memory which >= in size to the ciphertext block. The result will be written here.
*/
void OQS_AES128_ECB_dec(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext);
/**
* Same as OQS_AES128_ECB_enc() except a schedule generated by
* OQS_AES128_load_schedule() is passed rather then a key. This is faster
* if the same schedule is used for multiple encryptions since it does
* not have to be regenerated from the key.
*/
void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext);
/**
* Same as OQS_AES128_ECB_dec() except a schedule generated by
* OQS_AES128_load_schedule() is passed rather then a key. This is faster
* if the same schedule is used for multiple encryptions since it does
* not have to be regenerated from the key.
*/
void OQS_AES128_ECB_dec_sch(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext);
#endif

340
vendor/liboqs/src/crypto/aes/aes_c.c vendored Normal file
View File

@@ -0,0 +1,340 @@
// Simple, thoroughly commented implementation of 128-bit AES / Rijndael using C
// Chris Hulbert - chris.hulbert@gmail.com - http://splinter.com.au/blog
// References:
// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
// http://en.wikipedia.org/wiki/Rijndael_key_schedule
// http://en.wikipedia.org/wiki/Rijndael_mix_columns
// http://en.wikipedia.org/wiki/Rijndael_S-box
// This code is public domain, or any OSI-approved license, your choice. No warranty.
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "aes.h"
typedef unsigned char byte;
// Here are all the lookup tables for the row shifts, rcon, s-boxes, and galois field multiplications
static const byte shift_rows_table[] = {0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11};
static const byte shift_rows_table_inv[] = {0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3};
static const byte lookup_rcon[] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a};
static const byte lookup_sbox[] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};
static const byte lookup_sbox_inv[] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};
static const byte lookup_g2[] = {
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5};
static const byte lookup_g3[] = {
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a};
static const byte lookup_g9[] = {
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46};
static const byte lookup_g11[] = {
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3};
static const byte lookup_g13[] = {
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97};
static const byte lookup_g14[] = {
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d};
// Xor's all elements in a n byte array a by b
static void xor (byte * a, const byte *b, int n) {
int i;
for (i = 0; i < n; i++) {
a[i] ^= b[i];
}
}
// Xor the current cipher state by a specific round key
static void xor_round_key(byte *state, const byte *keys, int round) {
xor(state, keys + round * 16, 16);
}
// Apply the rijndael s-box to all elements in an array
// http://en.wikipedia.org/wiki/Rijndael_S-box
static void sub_bytes(byte *a, int n) {
int i;
for (i = 0; i < n; i++) {
a[i] = lookup_sbox[a[i]];
}
}
static void sub_bytes_inv(byte *a, int n) {
int i;
for (i = 0; i < n; i++) {
a[i] = lookup_sbox_inv[a[i]];
}
}
// Perform the core key schedule transform on 4 bytes, as part of the key expansion process
// http://en.wikipedia.org/wiki/Rijndael_key_schedule#Key_schedule_core
static void key_schedule_core(byte *a, int i) {
byte temp = a[0]; // Rotate the output eight bits to the left
a[0] = a[1];
a[1] = a[2];
a[2] = a[3];
a[3] = temp;
sub_bytes(a, 4); // Apply Rijndael's S-box on all four individual bytes in the output word
a[0] ^= lookup_rcon[i]; // On just the first (leftmost) byte of the output word, perform the rcon operation with i
// as the input, and exclusive or the rcon output with the first byte of the output word
}
// Expand the 16-byte key to 11 round keys (176 bytes)
// http://en.wikipedia.org/wiki/Rijndael_key_schedule#The_key_schedule
void oqs_aes128_load_schedule_c(const uint8_t *key, void **_schedule) {
*_schedule = malloc(16 * 11);
assert(*_schedule != NULL);
uint8_t *schedule = (uint8_t *) *_schedule;
int bytes = 16; // The count of how many bytes we've created so far
int i = 1; // The rcon iteration value i is set to 1
int j; // For repeating the second stage 3 times
byte t[4]; // Temporary working area known as 't' in the Wiki article
memcpy(schedule, key, 16); // The first 16 bytes of the expanded key are simply the encryption key
while (bytes < 176) { // Until we have 176 bytes of expanded key, we do the following:
memcpy(t, schedule + bytes - 4, 4); // We assign the value of the previous four bytes in the expanded key to t
key_schedule_core(t, i); // We perform the key schedule core on t, with i as the rcon iteration value
i++; // We increment i by 1
xor(t, schedule + bytes - 16, 4); // We exclusive-or t with the four-byte block 16 bytes before the new expanded key.
memcpy(schedule + bytes, t, 4); // This becomes the next 4 bytes in the expanded key
bytes += 4; // Keep track of how many expanded key bytes we've added
// We then do the following three times to create the next twelve bytes
for (j = 0; j < 3; j++) {
memcpy(t, schedule + bytes - 4, 4); // We assign the value of the previous 4 bytes in the expanded key to t
xor(t, schedule + bytes - 16, 4); // We exclusive-or t with the four-byte block n bytes before
memcpy(schedule + bytes, t, 4); // This becomes the next 4 bytes in the expanded key
bytes += 4; // Keep track of how many expanded key bytes we've added
}
}
}
void oqs_aes128_free_schedule_c(void *schedule) {
if (schedule != NULL) {
free(schedule);
}
}
// Apply the shift rows step on the 16 byte cipher state
// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard#The_ShiftRows_step
static void shift_rows(byte *state) {
int i;
byte temp[16];
memcpy(temp, state, 16);
for (i = 0; i < 16; i++) {
state[i] = temp[shift_rows_table[i]];
}
}
static void shift_rows_inv(byte *state) {
int i;
byte temp[16];
memcpy(temp, state, 16);
for (i = 0; i < 16; i++) {
state[i] = temp[shift_rows_table_inv[i]];
}
}
// Perform the mix columns matrix on one column of 4 bytes
// http://en.wikipedia.org/wiki/Rijndael_mix_columns
static void mix_col(byte *state) {
byte a0 = state[0];
byte a1 = state[1];
byte a2 = state[2];
byte a3 = state[3];
state[0] = lookup_g2[a0] ^ lookup_g3[a1] ^ a2 ^ a3;
state[1] = lookup_g2[a1] ^ lookup_g3[a2] ^ a3 ^ a0;
state[2] = lookup_g2[a2] ^ lookup_g3[a3] ^ a0 ^ a1;
state[3] = lookup_g2[a3] ^ lookup_g3[a0] ^ a1 ^ a2;
}
// Perform the mix columns matrix on each column of the 16 bytes
static void mix_cols(byte *state) {
mix_col(state);
mix_col(state + 4);
mix_col(state + 8);
mix_col(state + 12);
}
// Perform the inverse mix columns matrix on one column of 4 bytes
// http://en.wikipedia.org/wiki/Rijndael_mix_columns
static void mix_col_inv(byte *state) {
byte a0 = state[0];
byte a1 = state[1];
byte a2 = state[2];
byte a3 = state[3];
state[0] = lookup_g14[a0] ^ lookup_g9[a3] ^ lookup_g13[a2] ^ lookup_g11[a1];
state[1] = lookup_g14[a1] ^ lookup_g9[a0] ^ lookup_g13[a3] ^ lookup_g11[a2];
state[2] = lookup_g14[a2] ^ lookup_g9[a1] ^ lookup_g13[a0] ^ lookup_g11[a3];
state[3] = lookup_g14[a3] ^ lookup_g9[a2] ^ lookup_g13[a1] ^ lookup_g11[a0];
}
// Perform the inverse mix columns matrix on each column of the 16 bytes
static void mix_cols_inv(byte *state) {
mix_col_inv(state);
mix_col_inv(state + 4);
mix_col_inv(state + 8);
mix_col_inv(state + 12);
}
void oqs_aes128_enc_c(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext) {
const uint8_t *schedule = (const uint8_t *) _schedule;
int i; // To count the rounds
// First Round
memcpy(ciphertext, plaintext, 16);
xor_round_key(ciphertext, schedule, 0);
// Middle rounds
for (i = 0; i < 9; i++) {
sub_bytes(ciphertext, 16);
shift_rows(ciphertext);
mix_cols(ciphertext);
xor_round_key(ciphertext, schedule, i + 1);
}
// Final Round
sub_bytes(ciphertext, 16);
shift_rows(ciphertext);
xor_round_key(ciphertext, schedule, 10);
}
void oqs_aes128_dec_c(const uint8_t *ciphertext, const void *_schedule, uint8_t *plaintext) {
const uint8_t *schedule = (const uint8_t *) _schedule;
int i; // To count the rounds
// Reverse the final Round
memcpy(plaintext, ciphertext, 16);
xor_round_key(plaintext, schedule, 10);
shift_rows_inv(plaintext);
sub_bytes_inv(plaintext, 16);
// Reverse the middle rounds
for (i = 0; i < 9; i++) {
xor_round_key(plaintext, schedule, 9 - i);
mix_cols_inv(plaintext);
shift_rows_inv(plaintext);
sub_bytes_inv(plaintext, 16);
}
// Reverse the first Round
xor_round_key(plaintext, schedule, 0);
}

View File

@@ -0,0 +1,39 @@
/**
* \file aes_local.h
* \brief Header defining additional internal functions for OQS AES
*/
#ifndef __OQS_AES_LOCAL_H
#define __OQS_AES_LOCAL_H
#include <stdint.h>
#include <stdlib.h>
void oqs_aes128_load_schedule_ni(const uint8_t *key, void **schedule);
void oqs_aes128_free_schedule_ni(void *schedule);
void oqs_aes128_enc_ni(const uint8_t *plaintext, const void *schedule, uint8_t *ciphertext);
void oqs_aes128_dec_ni(const uint8_t *ciphertext, const void *schedule, uint8_t *plaintext);
void oqs_aes128_ecb_enc_ni(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_ni(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext);
void oqs_aes128_ecb_enc_sch_ni(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_sch_ni(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext);
void oqs_aes128_load_schedule_c(const uint8_t *key, void **schedule);
void oqs_aes128_free_schedule_c(void *schedule);
void oqs_aes128_enc_c(const uint8_t *plaintext, const void *schedule, uint8_t *ciphertext);
void oqs_aes128_dec_c(const uint8_t *ciphertext, const void *schedule, uint8_t *plaintext);
void oqs_aes128_ecb_enc_c(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_c(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext);
void oqs_aes128_ecb_enc_sch_c(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_sch_c(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext);
#ifdef USE_OPENSSL
void oqs_aes128_load_schedule_ossl(const uint8_t *key, void **schedule, int for_encryption);
void oqs_aes128_free_schedule_ossl(void *schedule);
void oqs_aes128_ecb_enc_ossl(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_ossl(const uint8_t *ciphertext, const size_t ciphertext_len, const uint8_t *key, uint8_t *plaintext);
void oqs_aes128_ecb_enc_sch_ossl(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext);
void oqs_aes128_ecb_dec_sch_ossl(const uint8_t *ciphertext, const size_t ciphertext_len, const void *schedule, uint8_t *plaintext);
#endif
#endif

100
vendor/liboqs/src/crypto/aes/aes_ni.c vendored Normal file
View File

@@ -0,0 +1,100 @@
#if defined(WINDOWS)
#define UNUSED
// __attribute__ not supported in VS, is there something else I should define?
#else
#define UNUSED __attribute__((unused))
#endif
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#ifndef AES_ENABLE_NI
#include <assert.h>
void oqs_aes128_load_schedule_ni(UNUSED const uint8_t *key, UNUSED void **_schedule) {
assert(0);
}
void oqs_aes128_free_schedule_ni(UNUSED void *_schedule) {
assert(0);
}
void oqs_aes128_enc_ni(UNUSED const uint8_t *plaintext, UNUSED const void *_schedule, UNUSED uint8_t *ciphertext) {
assert(0);
}
void oqs_aes128_dec_ni(UNUSED const uint8_t *ciphertext, UNUSED const void *_schedule, UNUSED uint8_t *plaintext) {
assert(0);
}
#else
#include <wmmintrin.h>
static __m128i key_expand(__m128i key, __m128i keygened) {
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
// The last 4 bytes from aeskeygenassist store the values we want so
// and they need to be xored all four sets of bytes in the result so
keygened = _mm_shuffle_epi32(keygened, _MM_SHUFFLE(3, 3, 3, 3));
return _mm_xor_si128(key, keygened);
}
//This is needed since the rcon argument to _mm_aeskeygenassist_si128
//must be a compile time constaint
#define key_exp(k, rcon) key_expand(k, _mm_aeskeygenassist_si128(k, rcon))
void oqs_aes128_load_schedule_ni(const uint8_t *key, void **_schedule) {
*_schedule = malloc(20 * 16);
assert(*_schedule != NULL);
__m128i *schedule = (__m128i *) *_schedule;
schedule[0] = _mm_loadu_si128((const __m128i *) key);
schedule[1] = key_exp(schedule[0], 0x01);
schedule[2] = key_exp(schedule[1], 0x02);
schedule[3] = key_exp(schedule[2], 0x04);
schedule[4] = key_exp(schedule[3], 0x08);
schedule[5] = key_exp(schedule[4], 0x10);
schedule[6] = key_exp(schedule[5], 0x20);
schedule[7] = key_exp(schedule[6], 0x40);
schedule[8] = key_exp(schedule[7], 0x80);
schedule[9] = key_exp(schedule[8], 0x1b);
schedule[10] = key_exp(schedule[9], 0x36);
// generate decryption keys in reverse order.
// schedule[10] is shared by last encryption and first decryption rounds
// schedule[0] is shared by first encryption round and last decryption round
for (size_t i = 0; i < 9; i++) {
schedule[11 + i] = _mm_aesimc_si128(schedule[9 - i]);
}
}
void oqs_aes128_free_schedule_ni(void *schedule) {
if (schedule != NULL) {
free(schedule);
}
}
void oqs_aes128_enc_ni(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext) {
__m128i *schedule = (__m128i *) _schedule;
__m128i m = _mm_loadu_si128((__m128i *) plaintext);
m = _mm_xor_si128(m, schedule[0]);
for (size_t i = 1; i < 10; i++) {
m = _mm_aesenc_si128(m, schedule[i]);
}
m = _mm_aesenclast_si128(m, schedule[10]);
_mm_storeu_si128((__m128i *) ciphertext, m);
}
void oqs_aes128_dec_ni(const uint8_t *ciphertext, const void *_schedule, uint8_t *plaintext) {
__m128i *schedule = (__m128i *) _schedule;
__m128i m = _mm_loadu_si128((__m128i *) ciphertext);
m = _mm_xor_si128(m, schedule[10]);
for (size_t i = 1; i < 10; i++) {
m = _mm_aesdec_si128(m, schedule[10 + i]);
}
m = _mm_aesdeclast_si128(m, schedule[0]);
_mm_storeu_si128((__m128i *) plaintext, m);
}
#endif

276
vendor/liboqs/src/crypto/aes/test_aes.c vendored Normal file
View File

@@ -0,0 +1,276 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oqs/rand.h>
#include "../../ds_benchmark.h"
#include "../../common/common.h"
#include "aes.h"
#include "aes_local.h"
#define BENCH_DURATION 1
#define TEST_ITERATIONS 100
#define TEST_REPEATEDLY(x) \
for (int i = 0; i < TEST_ITERATIONS; i++) { \
int ok = (x); \
if (ok != EXIT_SUCCESS) { \
eprintf("Failure in %s (iteration %d)\n", #x, i); \
return EXIT_FAILURE; \
} \
}
static void print_bytes(uint8_t *bytes, size_t num_bytes) {
for (size_t i = 0; i < num_bytes; i++) {
printf("%02x", (unsigned) bytes[i]);
}
}
static int test_aes128_correctness_c(OQS_RAND *rand) {
uint8_t key[16], plaintext[16], ciphertext[16], decrypted[16];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 16);
oqs_aes128_load_schedule_c(key, &schedule);
oqs_aes128_enc_c(plaintext, schedule, ciphertext);
oqs_aes128_dec_c(ciphertext, schedule, decrypted);
oqs_aes128_free_schedule_c(schedule);
if (memcmp(plaintext, decrypted, 16) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(plaintext, 16);
printf("\n");
print_bytes(decrypted, 16);
printf("\n");
return EXIT_FAILURE;
}
}
#ifdef AES_ENABLE_NI
static int test_aes128_correctness_ni(OQS_RAND *rand) {
uint8_t key[16], plaintext[16], ciphertext[16], decrypted[16];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 16);
oqs_aes128_load_schedule_ni(key, &schedule);
oqs_aes128_enc_ni(plaintext, schedule, ciphertext);
oqs_aes128_dec_ni(ciphertext, schedule, decrypted);
oqs_aes128_free_schedule_ni(schedule);
if (memcmp(plaintext, decrypted, 16) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(plaintext, 16);
printf("\n");
print_bytes(decrypted, 16);
printf("\n");
return EXIT_FAILURE;
}
}
static int test_aes128_c_equals_ni(OQS_RAND *rand) {
uint8_t key[16], plaintext[16], ciphertext_c[16], ciphertext_ni[16];
void *schedule_c = NULL, *schedule_ni = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 16);
oqs_aes128_load_schedule_c(key, &schedule_c);
oqs_aes128_load_schedule_ni(key, &schedule_ni);
oqs_aes128_enc_c(plaintext, schedule_c, ciphertext_c);
oqs_aes128_enc_ni(plaintext, schedule_ni, ciphertext_ni);
oqs_aes128_free_schedule_c(schedule_c);
oqs_aes128_free_schedule_ni(schedule_ni);
if (memcmp(ciphertext_c, ciphertext_ni, 16) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(ciphertext_c, 16);
printf("\n");
print_bytes(ciphertext_ni, 16);
printf("\n");
return EXIT_FAILURE;
}
}
static int test_aes128_ecb_correctness_ni(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320], decrypted[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
oqs_aes128_load_schedule_ni(key, &schedule);
oqs_aes128_ecb_enc_ni(plaintext, 320, schedule, ciphertext);
oqs_aes128_ecb_dec_ni(ciphertext, 320, schedule, decrypted);
oqs_aes128_free_schedule_ni(schedule);
if (memcmp(plaintext, decrypted, 320) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(plaintext, 320);
printf("\n");
print_bytes(decrypted, 320);
printf("\n");
return EXIT_FAILURE;
}
}
#endif
static int test_aes128_ecb_correctness_c(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320], decrypted[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
oqs_aes128_load_schedule_c(key, &schedule);
oqs_aes128_ecb_enc_c(plaintext, 320, schedule, ciphertext);
oqs_aes128_ecb_dec_c(ciphertext, 320, schedule, decrypted);
oqs_aes128_free_schedule_c(schedule);
if (memcmp(plaintext, decrypted, 320) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(plaintext, 320);
printf("\n");
print_bytes(decrypted, 320);
printf("\n");
return EXIT_FAILURE;
}
}
#ifdef USE_OPENSSL
static int test_aes128_ecb_correctness_ossl(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320], decrypted[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
oqs_aes128_load_schedule_ossl(key, &schedule, 1);
oqs_aes128_ecb_enc_ossl(plaintext, 320, schedule, ciphertext);
oqs_aes128_free_schedule_ossl(schedule);
oqs_aes128_load_schedule_ossl(key, &schedule, 0);
oqs_aes128_ecb_dec_ossl(ciphertext, 320, schedule, decrypted);
oqs_aes128_free_schedule_ossl(schedule);
if (memcmp(plaintext, decrypted, 320) == 0) {
return EXIT_SUCCESS;
} else {
print_bytes(plaintext, 320);
printf("\n");
print_bytes(decrypted, 320);
printf("\n");
return EXIT_FAILURE;
}
}
#endif
static void speed_aes128_c(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320], decrypted[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
TIME_OPERATION_SECONDS({ oqs_aes128_load_schedule_c(key, &schedule); oqs_aes128_free_schedule_c(schedule); }, "oqs_aes128_load_schedule_c", BENCH_DURATION);
oqs_aes128_load_schedule_c(key, &schedule);
TIME_OPERATION_SECONDS(oqs_aes128_enc_c(plaintext, schedule, ciphertext), "oqs_aes128_enc_c", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_dec_c(ciphertext, schedule, decrypted), "oqs_aes128_dec_c", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_c(plaintext, 320, key, ciphertext), "oqs_aes128_ecb_enc_c", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_c(ciphertext, 320, key, decrypted), "oqs_aes128_ecb_dec_c", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_sch_c(plaintext, 320, schedule, ciphertext), "oqs_aes128_ecb_enc_sch_c", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_sch_c(ciphertext, 320, schedule, decrypted), "oqs_aes128_ecb_dec_sch_c", BENCH_DURATION);
oqs_aes128_free_schedule_c(schedule);
}
#ifdef AES_ENABLE_NI
static void speed_aes128_ni(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320], decrypted[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
TIME_OPERATION_SECONDS({ oqs_aes128_load_schedule_ni(key, &schedule); oqs_aes128_free_schedule_ni(schedule); }, "oqs_aes128_load_schedule_ni", BENCH_DURATION);
oqs_aes128_load_schedule_ni(key, &schedule);
TIME_OPERATION_SECONDS(oqs_aes128_enc_ni(plaintext, schedule, ciphertext), "oqs_aes128_enc_ni", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_dec_ni(ciphertext, schedule, decrypted), "oqs_aes128_dec_ni", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_ni(plaintext, 320, key, ciphertext), "oqs_aes128_ecb_enc_ni", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_ni(ciphertext, 320, key, decrypted), "oqs_aes128_ecb_dec_ni", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_sch_ni(plaintext, 320, schedule, ciphertext), "oqs_aes128_ecb_enc_sch_ni", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_sch_ni(ciphertext, 320, schedule, decrypted), "oqs_aes128_ecb_dec_sch_ni", BENCH_DURATION);
oqs_aes128_free_schedule_ni(schedule);
}
#endif
#ifdef USE_OPENSSL
static void speed_aes128_ossl(OQS_RAND *rand) {
uint8_t key[16], plaintext[320], ciphertext[320];
void *schedule = NULL;
OQS_RAND_n(rand, key, 16);
OQS_RAND_n(rand, plaintext, 320);
TIME_OPERATION_SECONDS(oqs_aes128_load_schedule_ossl(key, &schedule, 1), "oqs_aes128_load_schedule_ossl 1", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_load_schedule_ossl(key, &schedule, 0), "oqs_aes128_load_schedule_ossl 0", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_ossl(plaintext, 320, key, ciphertext), "oqs_aes128_ecb_enc_ossl", BENCH_DURATION);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_ossl(ciphertext, 320, key, plaintext), "oqs_aes128_ecb_dec_ossl", BENCH_DURATION);
oqs_aes128_load_schedule_ossl(key, &schedule, 1);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_enc_sch_ossl(plaintext, 320, schedule, ciphertext), "oqs_aes128_ecb_enc_sch_ossl", BENCH_DURATION);
oqs_aes128_load_schedule_ossl(key, &schedule, 0);
TIME_OPERATION_SECONDS(oqs_aes128_ecb_dec_sch_ossl(ciphertext, 320, schedule, plaintext), "oqs_aes128_ecb_dec_sch_ossl", BENCH_DURATION);
}
#endif
int main(int argc, char **argv) {
int ret;
bool bench = false;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "--bench") == 0 || strcmp(argv[i], "-b") == 0) {
bench = true;
} else {
printf("Usage: ./test_rand [options]\n");
printf("\nOptions:\n");
printf(" --bench, -b\n");
printf(" Run benchmarks\n");
if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}
}
}
printf("=== test_aes correctness ===\n");
OQS_RAND *rand = OQS_RAND_new(OQS_RAND_alg_default);
if (rand == NULL) {
eprintf("OQS_RAND_new() failed\n");
goto err;
}
TEST_REPEATEDLY(test_aes128_correctness_c(rand));
#ifdef AES_ENABLE_NI
TEST_REPEATEDLY(test_aes128_correctness_ni(rand));
TEST_REPEATEDLY(test_aes128_c_equals_ni(rand));
#endif
TEST_REPEATEDLY(test_aes128_ecb_correctness_c(rand));
#ifdef AES_ENABLE_NI
TEST_REPEATEDLY(test_aes128_ecb_correctness_ni(rand));
#endif
#ifdef USE_OPENSSL
TEST_REPEATEDLY(test_aes128_ecb_correctness_ossl(rand));
#endif
printf("Tests passed.\n\n");
if (bench) {
printf("=== test_aes performance ===\n");
PRINT_TIMER_HEADER
speed_aes128_c(rand);
#ifdef AES_ENABLE_NI
speed_aes128_ni(rand);
#endif
#ifdef USE_OPENSSL
speed_aes128_ossl(rand);
#endif
PRINT_TIMER_FOOTER
}
ret = EXIT_SUCCESS;
goto cleanup;
err:
ret = EXIT_FAILURE;
cleanup:
OQS_RAND_free(rand);
return ret;
}

View File

@@ -0,0 +1,16 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = librand.la
librand_la_SOURCES = rand.c
librand_la_CPPFLAGS = -I../../../include
if USE_OPENSSL
librand_la_CPPFLAGS += -I$(OPENSSL_DIR)/include
endif
librand_la_CPPFLAGS += $(AM_CPPFLAGS)
librand_la_LDFLAGS =
if USE_OPENSSL
librand_la_LDFLAGS += -L$(OPENSSL_DIR)/lib
endif
librand_la_LDFLAGS += $(AM_LDFLAGS)

183
vendor/liboqs/src/crypto/rand/rand.c vendored Normal file
View File

@@ -0,0 +1,183 @@
#include <assert.h>
#include <stdio.h>
#include <math.h>
#if defined(WINDOWS)
#include <windows.h>
#include <Wincrypt.h>
#else
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#endif
#include <oqs/rand.h>
#include <oqs/rand_urandom_aesctr.h>
#include <oqs/rand_urandom_chacha20.h>
OQS_RAND *OQS_RAND_new(enum OQS_RAND_alg_name alg_name) {
switch (alg_name) {
case OQS_RAND_alg_default:
case OQS_RAND_alg_urandom_chacha20:
return OQS_RAND_urandom_chacha20_new();
case OQS_RAND_alg_urandom_aesctr:
return OQS_RAND_urandom_aesctr_new();
default:
assert(0);
return NULL; // avoid the warning of potentialy uninitialized variable in VS
}
}
uint8_t OQS_RAND_8(OQS_RAND *r) {
return r->rand_8(r);
}
uint32_t OQS_RAND_32(OQS_RAND *r) {
return r->rand_32(r);
}
uint64_t OQS_RAND_64(OQS_RAND *r) {
return r->rand_64(r);
}
void OQS_RAND_n(OQS_RAND *r, uint8_t *out, size_t n) {
r->rand_n(r, out, n);
}
void OQS_RAND_free(OQS_RAND *r) {
if (r) {
r->free(r);
}
}
#if !defined(WINDOWS)
/* For some reason specifying inline results in a build error */
inline
#endif
void
OQS_RAND_test_record_occurrence(const unsigned char b, unsigned long occurrences[256]) {
occurrences[b] += 1;
}
double OQS_RAND_test_statistical_distance_from_uniform(const unsigned long occurrences[256]) {
// compute total number of samples
unsigned long total = 0;
for (int i = 0; i < 256; i++) {
total += occurrences[i];
}
// compute statistical distance from uniform
// SD(X,Y) = 1/2 \sum_z | Pr[X=z] - Pr[Y=z] |
// = 1/2 \sum_z | 1/256 - Pr[Y=z] |
double distance = 0.0;
for (int i = 0; i < 256; i++) {
distance += fabs(1.0 / 256.0 - (double) occurrences[i] / (double) total);
}
distance /= 2.0;
return distance;
}
// Even for a perfectly uniform generator, if the number of samples is
// low then the std dev of the counts will be high. So, instead, whilst
// still assuming the number of samples isn't super-low, we calculate an
// approximate Chi-squared statistic and back-convert to the Normal
// distribution. The number of sigmas is reported: -3 to +3 is pretty
// ordinary, big negative is suspiciously-flat counts, big positive is
// wildly-fluctuating counts.
double OQS_RAND_zscore_deviation_from_uniform(const unsigned long occurrences[256]) {
double quantiles[102] = {
156.7872, 158.4155, 160.0555, 161.7072, 163.3707, 165.0460, 166.7331, 168.4321,
170.1430, 171.8658, 173.6006, 175.3475, 177.1064, 178.8773, 180.6604, 182.4557,
184.2631, 186.0828, 187.9147, 189.7589, 191.6155, 193.4844, 195.3657, 197.2594,
199.1656, 201.0843, 203.0155, 204.9593, 206.9157, 208.8847, 210.8663, 212.8607,
214.8678, 216.8877, 218.9203, 220.9658, 223.0241, 225.0953, 227.1794, 229.2765,
231.3866, 233.5096, 235.6457, 237.7949, 239.9572, 242.1326, 244.3212, 246.5230,
248.7380, 250.9663, 253.2079, 255.4627, 257.7310, 260.0126, 262.3076, 264.6160,
266.9379, 269.2733, 271.6222, 273.9846, 276.3607, 278.7503, 281.1536, 283.5705,
286.0011, 288.4454, 290.9035, 293.3754, 295.8610, 298.3605, 300.8739, 303.4011,
305.9422, 308.4973, 311.0663, 313.6493, 316.2463, 318.8574, 321.4825, 324.1217,
326.7751, 329.4426, 332.1242, 334.8201, 337.5301, 340.2544, 342.9930, 345.7459,
348.5131, 351.2947, 354.0906, 356.9009, 359.7256, 362.5648, 365.4184, 368.2866,
371.1692, 374.0664, 376.9782, 379.9045, 382.8454, 385.8010}; // -5.05 to +5.05 sigma: qchisq(pnorm(seq(-5.05,5.05,length.out=102)),255)
unsigned long total;
double chsq;
int i;
for (total = i = 0; i < 256; i++) {
total += occurrences[i];
}
if (total / 256. < 5) {
return ZSCORE_SPARSE;
}
for (chsq = i = 0; i < 256; i++) {
chsq += pow(occurrences[i] - total / 256., 2) * 256. / total;
}
if (chsq <= quantiles[0]) {
return ZSCORE_BIGNEG;
}
for (i = 1; i < 102; i++) {
if (chsq <= quantiles[i]) {
return (i - 51) / 10.0;
}
}
return ZSCORE_BIGPOS;
}
//
// convenience function for statistics reporting
void OQS_RAND_report_statistics(const unsigned long occurrences[256], const char *indent) {
double zscore = OQS_RAND_zscore_deviation_from_uniform(occurrences);
printf("%sStatistical distance from uniform: %12.10f\n", indent, OQS_RAND_test_statistical_distance_from_uniform(occurrences));
printf("%s Z-score deviation from uniform: ", indent);
if (zscore == ZSCORE_BIGNEG) {
printf("less than -5.0 sigma ***\n");
} else if (zscore == ZSCORE_BIGPOS) {
printf("more than +5.0 sigma ***\n");
} else if (zscore == ZSCORE_SPARSE) {
printf("(too few data)\n");
} else {
printf("about %.1f sigma\n", zscore);
}
return;
}
int OQS_RAND_get_system_entropy(uint8_t *buf, size_t n) {
int result = 0;
#if !defined(WINDOWS)
int fd = 0;
#endif
if (!buf) {
goto err;
}
#if defined(WINDOWS)
HCRYPTPROV hCryptProv;
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) ||
!CryptGenRandom(hCryptProv, n, buf)) {
goto err;
}
#else
fd = open("/dev/urandom", O_RDONLY);
if (fd <= 0) {
goto err;
}
size_t r = read(fd, buf, n);
if (r != n) {
goto err;
}
#endif
result = 1;
err:
#if !defined(WINDOWS)
if (fd > 0) {
close(fd);
}
#endif
return result;
}

98
vendor/liboqs/src/crypto/rand/rand.h vendored Normal file
View File

@@ -0,0 +1,98 @@
/**
* \file rand.h
* \brief Header defining the generic OQS PRNG
*/
#ifndef __OQS_RAND_H
#define __OQS_RAND_H
#include <stddef.h>
#include <stdint.h>
enum OQS_RAND_alg_name {
OQS_RAND_alg_default,
OQS_RAND_alg_urandom_chacha20,
OQS_RAND_alg_urandom_aesctr,
};
typedef struct OQS_RAND OQS_RAND;
/**
* OQS PRNG object
*/
struct OQS_RAND {
/**
* Specifies the name of the random number function
*/
char *method_name;
/**
* Estimated number of bits of security provided against a classical
* attacker
*/
uint16_t estimated_classical_security;
/**
* Estimated number of bits of security provided against a quantum
* attacker
*/
uint16_t estimated_quantum_security;
/**
* Pointer for storing the state of the PRNG
*/
void *ctx;
/**
* Function which returns an 8-bit random unsigned integer
*/
uint8_t (*rand_8)(OQS_RAND *r);
/**
* Function which returns an 32-bit random unsigned integer
*/
uint32_t (*rand_32)(OQS_RAND *r);
/**
* Function which returns an 64-bit random unsigned integer
*/
uint64_t (*rand_64)(OQS_RAND *r);
/**
* Function which generates n random 8-bit unsigned integers
*
* @param out : pointer to an array large enough to store the output integers (\f$\text{size} \geq n\f$)
* @param n : number of integers to generate
*/
void (*rand_n)(OQS_RAND *r, uint8_t *out, size_t n);
/**
* Pointer to a function for freeing the allocated key exchange structure
*
* @param k : Key exchange structure
*
*/
void (*free)(OQS_RAND *r);
};
OQS_RAND *OQS_RAND_new(enum OQS_RAND_alg_name alg_name);
uint8_t OQS_RAND_8(OQS_RAND *r);
uint32_t OQS_RAND_32(OQS_RAND *r);
uint64_t OQS_RAND_64(OQS_RAND *r);
void OQS_RAND_n(OQS_RAND *r, uint8_t *out, size_t n);
void OQS_RAND_free(OQS_RAND *r);
void OQS_RAND_test_record_occurrence(const unsigned char b, unsigned long occurrences[256]);
double OQS_RAND_test_statistical_distance_from_uniform(const unsigned long occurrences[256]);
#define ZSCORE_SPARSE (999.999)
#define ZSCORE_BIGNEG (-100.0)
#define ZSCORE_BIGPOS (+100.0)
double OQS_RAND_zscore_deviation_from_uniform(const unsigned long occurrences[256]);
void OQS_RAND_report_statistics(const unsigned long occurrences[256], const char *indent);
int OQS_RAND_get_system_entropy(uint8_t *buf, size_t n);
#endif

View File

@@ -0,0 +1,197 @@
#include <inttypes.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oqs/rand.h>
#include "../../common/common.h"
struct rand_testcase {
enum OQS_RAND_alg_name alg_name;
};
/* Add new testcases here */
struct rand_testcase rand_testcases[] = {
{OQS_RAND_alg_urandom_chacha20},
{OQS_RAND_alg_urandom_aesctr},
};
#define RAND_TEST_ITERATIONS 10000000L
static void rand_test_distribution_8(OQS_RAND *rand, unsigned long occurrences[256], int iterations) {
uint8_t b;
for (int i = 0; i < iterations; i++) {
b = OQS_RAND_8(rand);
OQS_RAND_test_record_occurrence(b, occurrences);
}
}
static void rand_test_distribution_32(OQS_RAND *rand, unsigned long occurrences[256], int iterations) {
uint32_t x;
for (int i = 0; i < iterations; i++) {
x = OQS_RAND_32(rand);
uint8_t b;
for (size_t j = 0; j < sizeof(uint32_t); j++) {
b = (x >> j) & 0xFF;
OQS_RAND_test_record_occurrence(b, occurrences);
}
}
}
static void rand_test_distribution_64(OQS_RAND *rand, unsigned long occurrences[256], int iterations) {
uint64_t x;
for (int i = 0; i < iterations; i++) {
x = OQS_RAND_64(rand);
uint8_t b;
for (size_t j = 0; j < sizeof(uint64_t); j++) {
b = (x >> j) & 0xFF;
OQS_RAND_test_record_occurrence(b, occurrences);
}
}
}
static int rand_test_distribution_n(OQS_RAND *rand, unsigned long occurrences[256], int len) {
uint8_t *x = malloc(len);
if (x == NULL) {
return 0;
}
OQS_RAND_n(rand, x, len);
for (int i = 0; i < len; i++) {
OQS_RAND_test_record_occurrence(x[i], occurrences);
}
free(x);
return 1;
}
#define PRINT_HEX_STRING(label, str, len) \
{ \
printf("%-20s (%4zu bytes): ", (label), (size_t)(len)); \
for (size_t i = 0; i < (len); i++) { \
printf("%02X", ((unsigned char *) (str))[i]); \
} \
printf("\n"); \
}
static int rand_test_distribution_wrapper(enum OQS_RAND_alg_name alg_name, int iterations, bool quiet) {
OQS_RAND *rand = OQS_RAND_new(alg_name);
if (rand == NULL) {
eprintf("rand is NULL\n");
return 0;
}
if (!quiet) {
printf("================================================================================\n");
printf("Sample outputs of PRNG %s\n", rand->method_name);
printf("================================================================================\n");
uint8_t x[256];
OQS_RAND_n(rand, x, 256);
PRINT_HEX_STRING("OQS_RAND_n, n = 256", x, 256)
uint8_t y8 = OQS_RAND_8(rand);
PRINT_HEX_STRING("OQS_RAND_8", (uint8_t *) &y8, sizeof(y8));
y8 = OQS_RAND_8(rand);
PRINT_HEX_STRING("OQS_RAND_8", (uint8_t *) &y8, sizeof(y8));
uint32_t y32 = OQS_RAND_32(rand);
PRINT_HEX_STRING("OQS_RAND_32", (uint8_t *) &y32, sizeof(y32));
y32 = OQS_RAND_32(rand);
PRINT_HEX_STRING("OQS_RAND_32", (uint8_t *) &y32, sizeof(y32));
uint64_t y64 = OQS_RAND_64(rand);
PRINT_HEX_STRING("OQS_RAND_64", (uint8_t *) &y64, sizeof(y64));
y64 = OQS_RAND_64(rand);
PRINT_HEX_STRING("OQS_RAND_64", (uint8_t *) &y64, sizeof(y64));
OQS_RAND_n(rand, x, 256);
PRINT_HEX_STRING("OQS_RAND_n, n = 256", x, 256)
}
printf("================================================================================\n");
printf("Testing distribution of PRNG %s\n", rand->method_name);
printf("================================================================================\n");
unsigned long occurrences[256];
for (int i = 0; i < 256; i++) {
occurrences[i] = 0;
}
printf("1-byte mode for %d iterations\n", 8 * iterations);
rand_test_distribution_8(rand, occurrences, 8 * iterations);
OQS_RAND_report_statistics(occurrences, " ");
for (int i = 0; i < 256; i++) {
occurrences[i] = 0;
}
printf("4-byte mode for %d iterations\n", 2 * iterations);
rand_test_distribution_32(rand, occurrences, 2 * iterations);
OQS_RAND_report_statistics(occurrences, " ");
for (int i = 0; i < 256; i++) {
occurrences[i] = 0;
}
printf("8-byte mode for %d iterations\n", iterations);
rand_test_distribution_64(rand, occurrences, iterations);
OQS_RAND_report_statistics(occurrences, " ");
for (int i = 0; i < 256; i++) {
occurrences[i] = 0;
}
printf("n-byte mode for %d bytes\n", 8 * iterations);
rand_test_distribution_n(rand, occurrences, 8 * iterations);
OQS_RAND_report_statistics(occurrences, " ");
OQS_RAND_free(rand);
return 1;
}
int main(int argc, char **argv) {
int success;
bool quiet = false;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if (strcmp(argv[i], "--quiet") == 0 || strcmp(argv[i], "-q") == 0) {
quiet = true;
} else {
printf("Usage: ./test_rand [options]\n");
printf("\nOptions:\n");
printf(" --quiet, -q\n");
printf(" Less verbose output\n");
if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
}
}
}
size_t rand_testcases_len = sizeof(rand_testcases) / sizeof(struct rand_testcase);
for (size_t i = 0; i < rand_testcases_len; i++) {
success = rand_test_distribution_wrapper(rand_testcases[i].alg_name, RAND_TEST_ITERATIONS, quiet);
if (success != 1) {
goto err;
}
}
success = 1;
goto cleanup;
err:
success = 0;
eprintf("ERROR!\n");
cleanup:
return (success == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,7 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = librandaesctr.la
librandaesctr_la_SOURCES = rand_urandom_aesctr.c
librandaesctr_la_CPPFLAGS = -I../../../include -I.
librandaesctr_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@@ -0,0 +1,138 @@
#include <sys/types.h>
#if defined(WINDOWS)
#include <windows.h>
#include <Wincrypt.h>
#else
#include <strings.h>
#include <sys/uio.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h> //memcpy
#include <assert.h>
#include <oqs/aes.h>
#include <oqs/rand.h>
#include <oqs/rand_urandom_aesctr.h>
typedef struct oqs_rand_urandom_aesctr_ctx {
uint64_t ctr;
void *schedule;
uint8_t cache[64];
size_t cache_next_byte;
} oqs_rand_urandom_aesctr_ctx;
static oqs_rand_urandom_aesctr_ctx *oqs_rand_urandom_aesctr_ctx_new() {
oqs_rand_urandom_aesctr_ctx *rand_ctx = NULL;
rand_ctx = (oqs_rand_urandom_aesctr_ctx *) malloc(sizeof(oqs_rand_urandom_aesctr_ctx));
if (rand_ctx == NULL) {
goto err;
}
uint8_t key[16];
if (!OQS_RAND_get_system_entropy(key, 16)) {
goto err;
}
OQS_AES128_load_schedule(key, &rand_ctx->schedule, 1);
rand_ctx->cache_next_byte = 64; // cache is empty
rand_ctx->ctr = 0;
goto okay;
err:
if (rand_ctx) {
free(rand_ctx);
}
return NULL;
okay:
return rand_ctx;
}
void OQS_RAND_urandom_aesctr_n(OQS_RAND *r, uint8_t *out, size_t n) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
const uint64_t num_full_blocks = n / 16;
uint64_t *half_blocks = (uint64_t *) out;
for (size_t i = 0; i < num_full_blocks; i++) {
half_blocks[2 * i] = rand_ctx->ctr++;
half_blocks[2 * i + 1] = rand_ctx->ctr++;
}
OQS_AES128_ECB_enc_sch(out, 16 * num_full_blocks, rand_ctx->schedule, out);
if (n % 16 > 0) {
uint8_t tmp_8[16];
uint64_t *tmp_64 = (uint64_t *) tmp_8;
tmp_64[0] = rand_ctx->ctr++;
tmp_64[1] = rand_ctx->ctr++;
OQS_AES128_ECB_enc_sch(tmp_8, 16, rand_ctx->schedule, tmp_8);
memcpy(out + 16 * num_full_blocks, tmp_8, n % 16);
}
}
static void OQS_RAND_urandom_aesctr_fill_cache(OQS_RAND *r) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
OQS_RAND_urandom_aesctr_n(r, rand_ctx->cache, sizeof(rand_ctx->cache));
rand_ctx->cache_next_byte = 0;
}
uint8_t OQS_RAND_urandom_aesctr_8(OQS_RAND *r) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > sizeof(rand_ctx->cache) - 1) {
OQS_RAND_urandom_aesctr_fill_cache(r);
}
uint8_t out = rand_ctx->cache[rand_ctx->cache_next_byte];
rand_ctx->cache_next_byte += 1;
return out;
}
uint32_t OQS_RAND_urandom_aesctr_32(OQS_RAND *r) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > sizeof(rand_ctx->cache) - 4) {
OQS_RAND_urandom_aesctr_fill_cache(r);
}
uint32_t out;
memcpy(&out, &rand_ctx->cache[rand_ctx->cache_next_byte], 4);
rand_ctx->cache_next_byte += 4;
return out;
}
uint64_t OQS_RAND_urandom_aesctr_64(OQS_RAND *r) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > sizeof(rand_ctx->cache) - 8) {
OQS_RAND_urandom_aesctr_fill_cache(r);
}
uint64_t out;
memcpy(&out, &rand_ctx->cache[rand_ctx->cache_next_byte], 8);
rand_ctx->cache_next_byte += 8;
return out;
}
void OQS_RAND_urandom_aesctr_free(OQS_RAND *r) {
if (r) {
oqs_rand_urandom_aesctr_ctx *rand_ctx = (oqs_rand_urandom_aesctr_ctx *) r->ctx;
if (rand_ctx) {
OQS_AES128_free_schedule(rand_ctx->schedule);
}
free(r->ctx);
free(r->method_name);
}
free(r);
}
OQS_RAND *OQS_RAND_urandom_aesctr_new() {
OQS_RAND *r = malloc(sizeof(OQS_RAND));
if (r == NULL) {
return NULL;
}
r->method_name = strdup("urandom_aesctr");
r->ctx = oqs_rand_urandom_aesctr_ctx_new();
if (r->ctx == NULL || r->method_name == NULL) {
OQS_RAND_urandom_aesctr_free(r);
return NULL;
}
r->estimated_classical_security = 128;
r->estimated_quantum_security = 64; // Grover search
r->rand_8 = &OQS_RAND_urandom_aesctr_8;
r->rand_32 = &OQS_RAND_urandom_aesctr_32;
r->rand_64 = &OQS_RAND_urandom_aesctr_64;
r->rand_n = &OQS_RAND_urandom_aesctr_n;
r->free = &OQS_RAND_urandom_aesctr_free;
return r;
}

View File

@@ -0,0 +1,23 @@
/**
* \file rand_urandom_aesctr.h
* \brief Header for the chacha implementation of OQS_RAND
*/
#ifndef __OQS_RAND_URANDOM_AESCTR_H
#define __OQS_RAND_URANDOM_AESCTR_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/rand.h>
OQS_RAND *OQS_RAND_urandom_aesctr_new();
uint8_t OQS_RAND_urandom_aesctr_8(OQS_RAND *r);
uint32_t OQS_RAND_urandom_aesctr_32(OQS_RAND *r);
uint64_t OQS_RAND_urandom_aesctr_64(OQS_RAND *r);
void OQS_RAND_urandom_aesctr_n(OQS_RAND *r, uint8_t *out, size_t n);
void OQS_RAND_urandom_aesctr_free(OQS_RAND *r);
#endif

View File

@@ -0,0 +1,8 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = librandchacha20.la
librandchacha20_la_SOURCES = rand_urandom_chacha20.c
librandchacha20_la_CPPFLAGS = -I../../../include -I.
librandchacha20_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@@ -0,0 +1,135 @@
#include <sys/types.h>
#if defined(WINDOWS)
#include <windows.h>
#include <Wincrypt.h>
#else
#include <strings.h>
#include <sys/uio.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <oqs/rand.h>
#include <oqs/rand_urandom_chacha20.h>
#include "external/chacha20.c"
typedef struct OQS_RAND_urandom_chacha20_ctx {
uint8_t key[32];
uint32_t nonce[2];
uint8_t cache[64];
size_t cache_next_byte;
uint32_t chacha20_input[16];
} OQS_RAND_urandom_chacha20_ctx;
static OQS_RAND_urandom_chacha20_ctx *OQS_RAND_urandom_chacha20_ctx_new();
static void OQS_RAND_urandom_chacha20_fill_cache(OQS_RAND *r);
static void OQS_RAND_urandom_chacha20_ctx_free(void *rand_ctx);
OQS_RAND *OQS_RAND_urandom_chacha20_new() {
OQS_RAND *r = malloc(sizeof(OQS_RAND));
if (r == NULL) {
return NULL;
}
r->method_name = strdup("urandom_chacha20");
r->ctx = OQS_RAND_urandom_chacha20_ctx_new();
if (r->ctx == NULL || r->method_name == NULL) {
OQS_RAND_urandom_chacha20_free(r);
return NULL;
}
r->estimated_classical_security = 256;
r->estimated_quantum_security = 128; // Grover search
r->rand_8 = &OQS_RAND_urandom_chacha20_8;
r->rand_32 = &OQS_RAND_urandom_chacha20_32;
r->rand_64 = &OQS_RAND_urandom_chacha20_64;
r->rand_n = &OQS_RAND_urandom_chacha20_n;
r->free = &OQS_RAND_urandom_chacha20_free;
return r;
}
static OQS_RAND_urandom_chacha20_ctx *OQS_RAND_urandom_chacha20_ctx_new() {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = NULL;
rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) malloc(sizeof(OQS_RAND_urandom_chacha20_ctx));
if (rand_ctx == NULL) {
goto err;
}
if (!OQS_RAND_get_system_entropy(rand_ctx->key, 32)) {
goto err;
}
memset(rand_ctx->nonce, 0, 8);
rand_ctx->cache_next_byte = 64; // cache is empty
ECRYPT_keysetup(rand_ctx->chacha20_input, rand_ctx->key);
goto okay;
err:
if (rand_ctx) {
free(rand_ctx);
}
return NULL;
okay:
return rand_ctx;
}
static void OQS_RAND_urandom_chacha20_fill_cache(OQS_RAND *r) {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) r->ctx;
r->rand_n(r, rand_ctx->cache, 64);
rand_ctx->cache_next_byte = 0;
}
uint8_t OQS_RAND_urandom_chacha20_8(OQS_RAND *r) {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > 64 - 1) {
OQS_RAND_urandom_chacha20_fill_cache(r);
}
uint8_t out = rand_ctx->cache[rand_ctx->cache_next_byte];
rand_ctx->cache_next_byte += 1;
return out;
}
uint32_t OQS_RAND_urandom_chacha20_32(OQS_RAND *r) {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > 64 - 4) {
OQS_RAND_urandom_chacha20_fill_cache(r);
}
uint32_t out;
memcpy(&out, &rand_ctx->cache[rand_ctx->cache_next_byte], 4);
rand_ctx->cache_next_byte += 4;
return out;
}
uint64_t OQS_RAND_urandom_chacha20_64(OQS_RAND *r) {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) r->ctx;
if (rand_ctx->cache_next_byte > 64 - 8) {
OQS_RAND_urandom_chacha20_fill_cache(r);
}
uint64_t out;
memcpy(&out, &rand_ctx->cache[rand_ctx->cache_next_byte], 8);
rand_ctx->cache_next_byte += 8;
return out;
}
void OQS_RAND_urandom_chacha20_n(OQS_RAND *r, uint8_t *out, size_t n) {
OQS_RAND_urandom_chacha20_ctx *rand_ctx = (OQS_RAND_urandom_chacha20_ctx *) r->ctx;
rand_ctx->nonce[0]++;
if (rand_ctx->nonce[0] == 0) {
rand_ctx->nonce[1]++;
}
ECRYPT_ivsetup(rand_ctx->chacha20_input, (u8 *) rand_ctx->nonce);
ECRYPT_keystream_bytes(rand_ctx->chacha20_input, out, n);
}
static void OQS_RAND_urandom_chacha20_ctx_free(void *rand_ctx) {
free(rand_ctx);
}
void OQS_RAND_urandom_chacha20_free(OQS_RAND *r) {
if (r) {
OQS_RAND_urandom_chacha20_ctx_free(r->ctx);
}
if (r) {
free(r->method_name);
}
free(r);
}

View File

@@ -0,0 +1,23 @@
/**
* \file rand_urandom_chacha20.h
* \brief Header for the chacha implementation of OQS_RAND
*/
#ifndef __OQS_RAND_URANDOM_CHACHA20_H
#define __OQS_RAND_URANDOM_CHACHA20_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/rand.h>
OQS_RAND *OQS_RAND_urandom_chacha20_new();
uint8_t OQS_RAND_urandom_chacha20_8(OQS_RAND *r);
uint32_t OQS_RAND_urandom_chacha20_32(OQS_RAND *r);
uint64_t OQS_RAND_urandom_chacha20_64(OQS_RAND *r);
void OQS_RAND_urandom_chacha20_n(OQS_RAND *r, uint8_t *out, size_t n);
void OQS_RAND_urandom_chacha20_free(OQS_RAND *r);
#endif

View File

@@ -0,0 +1,8 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libsha3.la
libsha3_la_SOURCES = sha3.c
libsha3_la_CPPFLAGS = -I../../../include -I.
libsha3_la_CPPFLAGS += $(AM_CPPFLAGS)

476
vendor/liboqs/src/crypto/sha3/sha3.c vendored Normal file
View File

@@ -0,0 +1,476 @@
/* Based on the public domain implementation in
* crypto_hash/keccakc512/simple/ from http://bench.cr.yp.to/supercop.html
* by Ronny Van Keer
* and the public domain "TweetFips202" implementation
* from https://twitter.com/tweetfips202
* by Gilles Van Assche, Daniel J. Bernstein, and Peter Schwabe */
#include <assert.h>
#include <oqs/sha3.h>
#include <stdint.h>
#define SHAKE128_RATE OQS_SHA3_SHAKE128_RATE
#define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE
#define SHA3_512_RATE OQS_SHA3_SHA3_512_RATE
#define NROUNDS 24
#define ROL(a, offset) ((a << offset) ^ (a >> (64 - offset)))
static uint64_t load64(const unsigned char *x) {
unsigned long long r = 0, i;
for (i = 0; i < 8; ++i) {
r |= (unsigned long long) x[i] << 8 * i;
}
return r;
}
static void store64(uint8_t *x, uint64_t u) {
unsigned int i;
for (i = 0; i < 8; ++i) {
x[i] = u;
u >>= 8;
}
}
static const uint64_t KeccakF_RoundConstants[NROUNDS] = {
(uint64_t) 0x0000000000000001ULL,
(uint64_t) 0x0000000000008082ULL,
(uint64_t) 0x800000000000808aULL,
(uint64_t) 0x8000000080008000ULL,
(uint64_t) 0x000000000000808bULL,
(uint64_t) 0x0000000080000001ULL,
(uint64_t) 0x8000000080008081ULL,
(uint64_t) 0x8000000000008009ULL,
(uint64_t) 0x000000000000008aULL,
(uint64_t) 0x0000000000000088ULL,
(uint64_t) 0x0000000080008009ULL,
(uint64_t) 0x000000008000000aULL,
(uint64_t) 0x000000008000808bULL,
(uint64_t) 0x800000000000008bULL,
(uint64_t) 0x8000000000008089ULL,
(uint64_t) 0x8000000000008003ULL,
(uint64_t) 0x8000000000008002ULL,
(uint64_t) 0x8000000000000080ULL,
(uint64_t) 0x000000000000800aULL,
(uint64_t) 0x800000008000000aULL,
(uint64_t) 0x8000000080008081ULL,
(uint64_t) 0x8000000000008080ULL,
(uint64_t) 0x0000000080000001ULL,
(uint64_t) 0x8000000080008008ULL};
static void KeccakF1600_StatePermute(uint64_t *state) {
int round;
uint64_t Aba, Abe, Abi, Abo, Abu;
uint64_t Aga, Age, Agi, Ago, Agu;
uint64_t Aka, Ake, Aki, Ako, Aku;
uint64_t Ama, Ame, Ami, Amo, Amu;
uint64_t Asa, Ase, Asi, Aso, Asu;
uint64_t BCa, BCe, BCi, BCo, BCu;
uint64_t Da, De, Di, Do, Du;
uint64_t Eba, Ebe, Ebi, Ebo, Ebu;
uint64_t Ega, Ege, Egi, Ego, Egu;
uint64_t Eka, Eke, Eki, Eko, Eku;
uint64_t Ema, Eme, Emi, Emo, Emu;
uint64_t Esa, Ese, Esi, Eso, Esu;
//copyFromState(A, state)
Aba = state[0];
Abe = state[1];
Abi = state[2];
Abo = state[3];
Abu = state[4];
Aga = state[5];
Age = state[6];
Agi = state[7];
Ago = state[8];
Agu = state[9];
Aka = state[10];
Ake = state[11];
Aki = state[12];
Ako = state[13];
Aku = state[14];
Ama = state[15];
Ame = state[16];
Ami = state[17];
Amo = state[18];
Amu = state[19];
Asa = state[20];
Ase = state[21];
Asi = state[22];
Aso = state[23];
Asu = state[24];
for (round = 0; round < NROUNDS; round += 2) {
// prepareTheta
BCa = Aba ^ Aga ^ Aka ^ Ama ^ Asa;
BCe = Abe ^ Age ^ Ake ^ Ame ^ Ase;
BCi = Abi ^ Agi ^ Aki ^ Ami ^ Asi;
BCo = Abo ^ Ago ^ Ako ^ Amo ^ Aso;
BCu = Abu ^ Agu ^ Aku ^ Amu ^ Asu;
//thetaRhoPiChiIotaPrepareTheta(round , A, E)
Da = BCu ^ ROL(BCe, 1);
De = BCa ^ ROL(BCi, 1);
Di = BCe ^ ROL(BCo, 1);
Do = BCi ^ ROL(BCu, 1);
Du = BCo ^ ROL(BCa, 1);
Aba ^= Da;
BCa = Aba;
Age ^= De;
BCe = ROL(Age, 44);
Aki ^= Di;
BCi = ROL(Aki, 43);
Amo ^= Do;
BCo = ROL(Amo, 21);
Asu ^= Du;
BCu = ROL(Asu, 14);
Eba = BCa ^ ((~BCe) & BCi);
Eba ^= (uint64_t) KeccakF_RoundConstants[round];
Ebe = BCe ^ ((~BCi) & BCo);
Ebi = BCi ^ ((~BCo) & BCu);
Ebo = BCo ^ ((~BCu) & BCa);
Ebu = BCu ^ ((~BCa) & BCe);
Abo ^= Do;
BCa = ROL(Abo, 28);
Agu ^= Du;
BCe = ROL(Agu, 20);
Aka ^= Da;
BCi = ROL(Aka, 3);
Ame ^= De;
BCo = ROL(Ame, 45);
Asi ^= Di;
BCu = ROL(Asi, 61);
Ega = BCa ^ ((~BCe) & BCi);
Ege = BCe ^ ((~BCi) & BCo);
Egi = BCi ^ ((~BCo) & BCu);
Ego = BCo ^ ((~BCu) & BCa);
Egu = BCu ^ ((~BCa) & BCe);
Abe ^= De;
BCa = ROL(Abe, 1);
Agi ^= Di;
BCe = ROL(Agi, 6);
Ako ^= Do;
BCi = ROL(Ako, 25);
Amu ^= Du;
BCo = ROL(Amu, 8);
Asa ^= Da;
BCu = ROL(Asa, 18);
Eka = BCa ^ ((~BCe) & BCi);
Eke = BCe ^ ((~BCi) & BCo);
Eki = BCi ^ ((~BCo) & BCu);
Eko = BCo ^ ((~BCu) & BCa);
Eku = BCu ^ ((~BCa) & BCe);
Abu ^= Du;
BCa = ROL(Abu, 27);
Aga ^= Da;
BCe = ROL(Aga, 36);
Ake ^= De;
BCi = ROL(Ake, 10);
Ami ^= Di;
BCo = ROL(Ami, 15);
Aso ^= Do;
BCu = ROL(Aso, 56);
Ema = BCa ^ ((~BCe) & BCi);
Eme = BCe ^ ((~BCi) & BCo);
Emi = BCi ^ ((~BCo) & BCu);
Emo = BCo ^ ((~BCu) & BCa);
Emu = BCu ^ ((~BCa) & BCe);
Abi ^= Di;
BCa = ROL(Abi, 62);
Ago ^= Do;
BCe = ROL(Ago, 55);
Aku ^= Du;
BCi = ROL(Aku, 39);
Ama ^= Da;
BCo = ROL(Ama, 41);
Ase ^= De;
BCu = ROL(Ase, 2);
Esa = BCa ^ ((~BCe) & BCi);
Ese = BCe ^ ((~BCi) & BCo);
Esi = BCi ^ ((~BCo) & BCu);
Eso = BCo ^ ((~BCu) & BCa);
Esu = BCu ^ ((~BCa) & BCe);
// prepareTheta
BCa = Eba ^ Ega ^ Eka ^ Ema ^ Esa;
BCe = Ebe ^ Ege ^ Eke ^ Eme ^ Ese;
BCi = Ebi ^ Egi ^ Eki ^ Emi ^ Esi;
BCo = Ebo ^ Ego ^ Eko ^ Emo ^ Eso;
BCu = Ebu ^ Egu ^ Eku ^ Emu ^ Esu;
//thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
Da = BCu ^ ROL(BCe, 1);
De = BCa ^ ROL(BCi, 1);
Di = BCe ^ ROL(BCo, 1);
Do = BCi ^ ROL(BCu, 1);
Du = BCo ^ ROL(BCa, 1);
Eba ^= Da;
BCa = Eba;
Ege ^= De;
BCe = ROL(Ege, 44);
Eki ^= Di;
BCi = ROL(Eki, 43);
Emo ^= Do;
BCo = ROL(Emo, 21);
Esu ^= Du;
BCu = ROL(Esu, 14);
Aba = BCa ^ ((~BCe) & BCi);
Aba ^= (uint64_t) KeccakF_RoundConstants[round + 1];
Abe = BCe ^ ((~BCi) & BCo);
Abi = BCi ^ ((~BCo) & BCu);
Abo = BCo ^ ((~BCu) & BCa);
Abu = BCu ^ ((~BCa) & BCe);
Ebo ^= Do;
BCa = ROL(Ebo, 28);
Egu ^= Du;
BCe = ROL(Egu, 20);
Eka ^= Da;
BCi = ROL(Eka, 3);
Eme ^= De;
BCo = ROL(Eme, 45);
Esi ^= Di;
BCu = ROL(Esi, 61);
Aga = BCa ^ ((~BCe) & BCi);
Age = BCe ^ ((~BCi) & BCo);
Agi = BCi ^ ((~BCo) & BCu);
Ago = BCo ^ ((~BCu) & BCa);
Agu = BCu ^ ((~BCa) & BCe);
Ebe ^= De;
BCa = ROL(Ebe, 1);
Egi ^= Di;
BCe = ROL(Egi, 6);
Eko ^= Do;
BCi = ROL(Eko, 25);
Emu ^= Du;
BCo = ROL(Emu, 8);
Esa ^= Da;
BCu = ROL(Esa, 18);
Aka = BCa ^ ((~BCe) & BCi);
Ake = BCe ^ ((~BCi) & BCo);
Aki = BCi ^ ((~BCo) & BCu);
Ako = BCo ^ ((~BCu) & BCa);
Aku = BCu ^ ((~BCa) & BCe);
Ebu ^= Du;
BCa = ROL(Ebu, 27);
Ega ^= Da;
BCe = ROL(Ega, 36);
Eke ^= De;
BCi = ROL(Eke, 10);
Emi ^= Di;
BCo = ROL(Emi, 15);
Eso ^= Do;
BCu = ROL(Eso, 56);
Ama = BCa ^ ((~BCe) & BCi);
Ame = BCe ^ ((~BCi) & BCo);
Ami = BCi ^ ((~BCo) & BCu);
Amo = BCo ^ ((~BCu) & BCa);
Amu = BCu ^ ((~BCa) & BCe);
Ebi ^= Di;
BCa = ROL(Ebi, 62);
Ego ^= Do;
BCe = ROL(Ego, 55);
Eku ^= Du;
BCi = ROL(Eku, 39);
Ema ^= Da;
BCo = ROL(Ema, 41);
Ese ^= De;
BCu = ROL(Ese, 2);
Asa = BCa ^ ((~BCe) & BCi);
Ase = BCe ^ ((~BCi) & BCo);
Asi = BCi ^ ((~BCo) & BCu);
Aso = BCo ^ ((~BCu) & BCa);
Asu = BCu ^ ((~BCa) & BCe);
}
//copyToState(state, A)
state[0] = Aba;
state[1] = Abe;
state[2] = Abi;
state[3] = Abo;
state[4] = Abu;
state[5] = Aga;
state[6] = Age;
state[7] = Agi;
state[8] = Ago;
state[9] = Agu;
state[10] = Aka;
state[11] = Ake;
state[12] = Aki;
state[13] = Ako;
state[14] = Aku;
state[15] = Ama;
state[16] = Ame;
state[17] = Ami;
state[18] = Amo;
state[19] = Amu;
state[20] = Asa;
state[21] = Ase;
state[22] = Asi;
state[23] = Aso;
state[24] = Asu;
#undef round
}
#include <string.h>
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static void keccak_absorb(uint64_t *s,
unsigned int r,
const unsigned char *m, unsigned long long int mlen,
unsigned char p) {
unsigned long long i;
unsigned char t[200];
for (i = 0; i < 25; ++i)
s[i] = 0;
while (mlen >= r) {
for (i = 0; i < r / 8; ++i)
s[i] ^= load64(m + 8 * i);
KeccakF1600_StatePermute(s);
mlen -= r;
m += r;
}
for (i = 0; i < r; ++i)
t[i] = 0;
for (i = 0; i < mlen; ++i)
t[i] = m[i];
t[i] = p;
t[r - 1] |= 128;
for (i = 0; i < r / 8; ++i)
s[i] ^= load64(t + 8 * i);
}
void OQS_SHA3_keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks,
uint64_t *s,
unsigned int r) {
unsigned int i;
while (nblocks > 0) {
KeccakF1600_StatePermute(s);
for (i = 0; i < (r >> 3); i++) {
store64(h + 8 * i, s[i]);
}
h += r;
nblocks--;
}
}
void OQS_SHA3_sha3256(unsigned char *output, const unsigned char *input, unsigned int inputByteLen) {
uint64_t s[25];
unsigned char t[SHA3_256_RATE];
int i;
keccak_absorb(s, SHA3_256_RATE, input, inputByteLen, 0x06);
OQS_SHA3_keccak_squeezeblocks(t, 1, s, SHA3_256_RATE);
for (i = 0; i < 32; i++)
output[i] = t[i];
}
void OQS_SHA3_sha3512(unsigned char *output, const unsigned char *input, unsigned int inputByteLen) {
uint64_t s[25];
unsigned char t[SHA3_512_RATE];
int i;
//TODO: not sure about 0x80
keccak_absorb(s, SHA3_512_RATE, input, inputByteLen, 0x80);
OQS_SHA3_keccak_squeezeblocks(t, 1, s, SHA3_512_RATE);
for (i = 0; i < 64; i++)
output[i] = t[i];
}
void OQS_SHA3_shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen) {
keccak_absorb(s, SHAKE128_RATE, input, inputByteLen, 0x1F);
}
void OQS_SHA3_shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
OQS_SHA3_keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
}
void OQS_SHA3_shake128(unsigned char *output, unsigned long long outlen,
const unsigned char *input, unsigned long long inlen) {
uint64_t s[25];
unsigned char t[SHAKE128_RATE];
unsigned long long nblocks = outlen / SHAKE128_RATE;
size_t i;
for (i = 0; i < 25; ++i)
s[i] = 0;
/* Absorb input */
keccak_absorb(s, SHAKE128_RATE, input, inlen, 0x1F);
/* Squeeze output */
OQS_SHA3_keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
output += nblocks * SHAKE128_RATE;
outlen -= nblocks * SHAKE128_RATE;
if (outlen) {
OQS_SHA3_keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
for (i = 0; i < outlen; i++)
output[i] = t[i];
}
}
void OQS_SHA3_cshake128_simple_absorb(uint64_t s[25],
uint16_t cstm, // 2-byte domain separator
const unsigned char *in, unsigned long long inlen) {
unsigned char *sep = (unsigned char *) s;
unsigned int i;
for (i = 0; i < 25; i++)
s[i] = 0;
/* Absorb customization (domain-separation) string */
sep[0] = 0x01;
sep[1] = 0xa8;
sep[2] = 0x01;
sep[3] = 0x00;
sep[4] = 0x01;
sep[5] = 16; // fixed bitlen of cstm
sep[6] = cstm & 0xff;
sep[7] = cstm >> 8;
KeccakF1600_StatePermute(s);
/* Absorb input */
keccak_absorb(s, SHAKE128_RATE, in, inlen, 0x04);
}
void OQS_SHA3_cshake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s) {
OQS_SHA3_keccak_squeezeblocks(output, nblocks, s, SHAKE128_RATE);
}
void OQS_SHA3_cshake128_simple(unsigned char *output, unsigned long long outlen,
uint16_t cstm, // 2-byte domain separator
const unsigned char *in, unsigned long long inlen) {
uint64_t s[25];
unsigned char t[SHAKE128_RATE];
unsigned int i;
OQS_SHA3_cshake128_simple_absorb(s, cstm, in, inlen);
/* Squeeze output */
OQS_SHA3_keccak_squeezeblocks(output, outlen / SHAKE128_RATE, s, SHAKE128_RATE);
output += (outlen / SHAKE128_RATE) * SHAKE128_RATE;
if (outlen % SHAKE128_RATE) {
OQS_SHA3_keccak_squeezeblocks(t, 1, s, SHAKE128_RATE);
for (i = 0; i < outlen % SHAKE128_RATE; i++)
output[i] = t[i];
}
}

35
vendor/liboqs/src/crypto/sha3/sha3.h vendored Normal file
View File

@@ -0,0 +1,35 @@
/**
* \file sha3.h
* \brief Header defining the API for OQS SHA3
*/
#ifndef __OQS_SHA3_H
#define __OQS_SHA3_H
#include <stdint.h>
#define OQS_SHA3_STATESIZE 25
#define OQS_SHA3_SHAKE128_RATE 168
#define OQS_SHA3_SHA3_256_RATE 136
#define OQS_SHA3_SHA3_512_RATE 72
void OQS_SHA3_keccak_squeezeblocks(unsigned char *h, unsigned long long int nblocks, uint64_t *s, unsigned int r);
void OQS_SHA3_sha3256(unsigned char *output, const unsigned char *input, unsigned int inputByteLen);
void OQS_SHA3_sha3512(unsigned char *output, const unsigned char *input, unsigned int inputByteLen);
// SHAKE128
void OQS_SHA3_shake128_absorb(uint64_t *s, const unsigned char *input, unsigned int inputByteLen);
void OQS_SHA3_shake128_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
void OQS_SHA3_shake128(unsigned char *output, unsigned long long outlen,
const unsigned char *input, unsigned long long inlen);
// cSHAKE128
void OQS_SHA3_cshake128_simple_absorb(uint64_t *s,
uint16_t cstm, // 2-byte domain separator
const unsigned char *in, unsigned long long inlen);
void OQS_SHA3_cshake128_simple_squeezeblocks(unsigned char *output, unsigned long long nblocks, uint64_t *s);
void OQS_SHA3_cshake128_simple(unsigned char *output, unsigned long long outlen,
uint16_t cstm, // 2-byte domain separator
const unsigned char *in, unsigned long long inlen);
#endif

238
vendor/liboqs/src/ds_benchmark.h vendored Normal file
View File

@@ -0,0 +1,238 @@
/********************************************************************************************
* ds_benchmark.h: Macros for simple benchmarking of C code.
*
* See instructions for usage below.
* Software originally developed by Douglas Stebila.
* Most recent version at https://gist.github.com/dstebila/6980008ec98209ef6075
*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
*
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* 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 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.
*
* For more information, please refer to <http://unlicense.org>
********************************************************************************************/
/** \file ds_benchmark.h
* Macros for simple benchmarking of C code.
*/
#if 0
/* example code: timing two operations */
#include "ds_benchmark.h"
...
DEFINE_TIMER_VARIABLES
INITIALIZE_TIMER
START_TIMER
// your operation here
STOP_TIMER
START_TIMER
// another operation here
STOP_TIMER
FINALIZE_TIMER
PRINT_TIME_HEADER
PRINT_TIMER_AVG("my operation")
PRINT_TIMER_FOOTER
/* example code: average multiple runs, run for e.g. 30 seconds */
#include "ds_benchmark.h"
...
PRINT_TIMER_HEADER
TIME_OPERATION_SECONDS(MyFunction(myarg1, myarg2, ...), "my operation", 30)
TIME_OPERATION_SECONDS(MyOtherFunction(myarg3), "my other operation", 30)
PRINT_TIMER_FOOTER
/* example code: average multiple runs, run for e.g. 100 iterations */
#include "ds_benchmark.h"
...
PRINT_TIMER_HEADER
TIME_OPERATION_ITERATIONS(MyFunction(myarg1, myarg2, ...), "my operation", 1000)
TIME_OPERATION_ITERATIONS(MyOtherFunction(myarg3), "my other operation", 100)
PRINT_TIMER_FOOTER
/* For most accurate results:
* - disable hyperthreading a.k.a. hardware multithreading
* (Linux instructions: http://bench.cr.yp.to/supercop.html)
* (Mac OS X instructions: Instruments -> Preferences -> CPUs -> uncheck "Hardware Multi-Threading"
* http://forums.macrumors.com/showthread.php?t=1484684)
* - disable TurboBoost
* (Linux instructions: http://bench.cr.yp.to/supercop.html)
* (Max OS X: use http://www.rugarciap.com/turbo-boost-switcher-for-os-x/)
* - run when the computer is idle (e.g., shut down all other applications, disable network access if possible, ...)
*/
#endif
#ifndef _DS_BENCHMARK_H
#define _DS_BENCHMARK_H
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#if !defined(WINDOWS)
#include <sys/time.h>
#endif
#include <math.h>
#include <time.h>
#if defined(WINDOWS)
#include <Windows.h>
int gettimeofday(struct timeval *tp, struct timezone *tzp) {
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
SYSTEMTIME system_time;
FILETIME file_time;
uint64_t time;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
time = ((uint64_t) file_time.dwLowDateTime);
time += ((uint64_t) file_time.dwHighDateTime) << 32;
tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
return 0;
}
#endif
static uint64_t rdtsc(void) {
#if defined(WINDOWS)
return __rdtsc();
#elif defined(__aarch64__)
uint64_t x;
asm volatile("isb; mrs %0, cntvct_el0"
: "=r"(x));
return x;
#else
uint64_t x;
__asm__ volatile(".byte 0x0f, 0x31"
: "=A"(x));
return x;
#endif
}
#define DEFINE_TIMER_VARIABLES \
volatile uint64_t _bench_cycles_start, _bench_cycles_end; \
uint64_t _bench_cycles_cumulative = 0; \
int64_t _bench_cycles_diff; \
struct timeval _bench_timeval_start, _bench_timeval_end; \
uint64_t _bench_iterations, _bench_time_cumulative; \
double _bench_cycles_x, _bench_cycles_mean, _bench_cycles_delta, _bench_cycles_M2, _bench_cycles_stdev; \
double _bench_time_x, _bench_time_mean, _bench_time_delta, _bench_time_M2, _bench_time_stdev;
#define INITIALIZE_TIMER \
_bench_iterations = 0; \
_bench_cycles_mean = 0.0; \
_bench_cycles_M2 = 0.0; \
_bench_time_cumulative = 0; \
_bench_time_mean = 0.0; \
_bench_time_M2 = 0.0;
#define START_TIMER \
gettimeofday(&_bench_timeval_start, NULL); \
_bench_cycles_start = rdtsc();
// Mean and population standard deviation are calculated in an online way using the algorithm in
// http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm
#define STOP_TIMER \
_bench_cycles_end = rdtsc(); \
gettimeofday(&_bench_timeval_end, NULL); \
_bench_iterations += 1; \
if (_bench_cycles_end < _bench_cycles_start) { \
_bench_cycles_end += 1UL << 32; \
} \
_bench_cycles_diff = _bench_cycles_end; \
_bench_cycles_diff -= _bench_cycles_start; \
_bench_cycles_cumulative += _bench_cycles_diff; \
_bench_cycles_x = (double) (_bench_cycles_diff); \
_bench_cycles_delta = _bench_cycles_x - _bench_cycles_mean; \
_bench_cycles_mean += _bench_cycles_delta / (double) _bench_iterations; \
_bench_cycles_M2 += _bench_cycles_delta * (_bench_cycles_x - _bench_cycles_mean); \
_bench_time_x = (double) ((_bench_timeval_end.tv_sec * 1000000 + _bench_timeval_end.tv_usec) - (_bench_timeval_start.tv_sec * 1000000 + _bench_timeval_start.tv_usec)); \
_bench_time_delta = _bench_time_x - _bench_time_mean; \
_bench_time_mean += _bench_time_delta / (double) _bench_iterations; \
_bench_time_M2 += _bench_time_delta * (_bench_time_x - _bench_time_mean); \
_bench_time_cumulative += _bench_time_x;
#define FINALIZE_TIMER \
if (_bench_iterations == 2) { \
_bench_cycles_stdev = 0.0; \
} else { \
_bench_cycles_stdev = sqrt(_bench_cycles_M2 / (double) _bench_iterations); \
} \
if (_bench_iterations == 2) { \
_bench_time_stdev = 0.0; \
} else { \
_bench_time_stdev = sqrt(_bench_time_M2 / (double) _bench_iterations); \
}
#define PRINT_CURRENT_TIME \
{ \
char _bench_time_buff[20]; \
time_t _bench_time_now = time(0); \
strftime(_bench_time_buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&_bench_time_now)); \
printf("%s", _bench_time_buff); \
}
#define PRINT_TIMER_HEADER \
printf("Started at "); \
PRINT_CURRENT_TIME \
printf("\n"); \
printf("%-30s | %10s | %14s | %15s | %10s | %16s | %10s\n", "Operation ", "Iterations", "Total time (s)", "Time (us): mean", "pop. stdev", "CPU cycles: mean", "pop. stdev"); \
printf("%-30s | %10s:| %14s:| %15s:| %10s:| %16s:| %10s:\n", "------------------------------", "----------", "--------------", "---------------", "----------", "----------------", "----------");
/* colons are used in above to right-align cell contents in Markdown */
#define PRINT_TIMER_FOOTER \
printf("Ended at "); \
PRINT_CURRENT_TIME \
printf("\n");
#define PRINT_TIMER_AVG(op_name) \
printf("%-30s | %10" PRIu64 " | %14.3f | %15.3f | %10.3f | %16.0f | %10.0f\n", (op_name), _bench_iterations, ((double) _bench_time_cumulative) / 1000000.0, _bench_time_mean, _bench_time_stdev, ((double) _bench_cycles_cumulative) / (double) _bench_iterations, _bench_cycles_stdev);
#define TIME_OPERATION_ITERATIONS(op, op_name, it) \
{ \
DEFINE_TIMER_VARIABLES \
INITIALIZE_TIMER \
for (int i = 0; i < (it); i++) { \
START_TIMER { op; } \
STOP_TIMER \
} \
FINALIZE_TIMER \
PRINT_TIMER_AVG(op_name) \
}
#define TIME_OPERATION_SECONDS(op, op_name, secs) \
{ \
DEFINE_TIMER_VARIABLES \
INITIALIZE_TIMER \
uint64_t _bench_time_goal_usecs = 1000000 * secs; \
while (_bench_time_cumulative < _bench_time_goal_usecs) { \
START_TIMER { op; } \
STOP_TIMER \
} \
FINALIZE_TIMER \
PRINT_TIMER_AVG(op_name) \
}
#endif

8
vendor/liboqs/src/kex/Makefile.am vendored Normal file
View File

@@ -0,0 +1,8 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libkex.la
libkex_la_SOURCES = kex.c
libkex_la_CPPFLAGS = -I../../include
libkex_la_CPPFLAGS += $(AM_CPPFLAGS)

132
vendor/liboqs/src/kex/kex.c vendored Normal file
View File

@@ -0,0 +1,132 @@
#include <assert.h>
#include <oqs/kex.h>
#include <oqs/kex_lwe_frodo.h>
#include <oqs/kex_mlwe_kyber.h>
#include <oqs/kex_ntru.h>
#include <oqs/kex_rlwe_bcns15.h>
#include <oqs/kex_rlwe_msrln16.h>
#include <oqs/kex_rlwe_newhope.h>
#include <oqs/kex_sidh_cln16.h>
#ifdef ENABLE_CODE_MCBITS
#include <oqs/kex_code_mcbits.h>
#endif
#ifdef ENABLE_SIDH_IQC_REF
#include <oqs/kex_sidh_iqc_ref.h>
#endif
#define UNUSED(expr) \
do { \
(void) (expr); \
} while (0)
OQS_KEX *OQS_KEX_new(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters) {
//To disable warnings when the function arguments are not being used depending
//on which algorithm has been disabled
UNUSED(seed);
UNUSED(seed_len);
UNUSED(named_parameters);
switch (alg_name) {
case OQS_KEX_alg_default:
return OQS_KEX_rlwe_bcns15_new(rand);
#ifdef ENABLE_KEX_LWE_FRODO
case OQS_KEX_alg_lwe_frodo:
return OQS_KEX_lwe_frodo_new_recommended(rand, seed, seed_len, named_parameters);
#else
assert(0);
#endif
case OQS_KEX_alg_code_mcbits:
#ifdef ENABLE_CODE_MCBITS
return OQS_KEX_code_mcbits_new(rand);
#else
assert(0);
#endif
#ifdef ENABLE_KEX_MLWE_KYBER
case OQS_KEX_alg_mlwe_kyber:
return OQS_KEX_mlwe_kyber_new(rand);
#else
assert(0);
#endif
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
#ifdef ENABLE_KEX_NTRU
case OQS_KEX_alg_ntru:
return OQS_KEX_ntru_new(rand);
#else
assert(0);
#endif
#endif
case OQS_KEX_alg_rlwe_bcns15:
return OQS_KEX_rlwe_bcns15_new(rand);
#ifdef ENABLE_KEX_RLWE_MSRLN16
case OQS_KEX_alg_rlwe_msrln16:
return OQS_KEX_rlwe_msrln16_new(rand);
#else
assert(0);
#endif
#ifdef ENABLE_KEX_RLWE_NEWHOPE
case OQS_KEX_alg_rlwe_newhope:
return OQS_KEX_rlwe_newhope_new(rand);
#else
assert(0);
#endif
#ifdef ENABLE_KEX_SIDH_CLN16
case OQS_KEX_alg_sidh_cln16:
return OQS_KEX_sidh_cln16_new(rand, named_parameters);
case OQS_KEX_alg_sidh_cln16_compressed:
return OQS_KEX_sidh_cln16_new(rand, named_parameters);
#else
assert(0);
#endif
case OQS_KEX_alg_sidh_iqc_ref:
#ifdef ENABLE_SIDH_IQC_REF
return OQS_KEX_sidh_iqc_ref_new(rand);
#else
assert(0);
#endif
default:
assert(0);
return NULL;
}
}
int OQS_KEX_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
if (k == NULL) {
return 0;
} else {
return k->alice_0(k, alice_priv, alice_msg, alice_msg_len);
}
}
int OQS_KEX_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len) {
if (k == NULL) {
return 0;
} else {
return k->bob(k, alice_msg, alice_msg_len, bob_msg, bob_msg_len, key, key_len);
}
}
int OQS_KEX_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len) {
if (k == NULL) {
return 0;
} else {
return k->alice_1(k, alice_priv, bob_msg, bob_msg_len, key, key_len);
}
}
void OQS_KEX_alice_priv_free(OQS_KEX *k, void *alice_priv) {
if (k) {
k->alice_priv_free(k, alice_priv);
}
}
void OQS_KEX_free(OQS_KEX *k) {
if (k) {
k->free(k);
}
}

158
vendor/liboqs/src/kex/kex.h vendored Normal file
View File

@@ -0,0 +1,158 @@
/**
* \file kex.h
* \brief Header defining the API for generic OQS Key exchange
*/
#ifndef __OQS_KEX_H
#define __OQS_KEX_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/rand.h>
enum OQS_KEX_alg_name {
OQS_KEX_alg_default,
OQS_KEX_alg_rlwe_bcns15,
OQS_KEX_alg_rlwe_newhope,
OQS_KEX_alg_rlwe_msrln16,
OQS_KEX_alg_lwe_frodo,
OQS_KEX_alg_sidh_cln16,
OQS_KEX_alg_sidh_cln16_compressed,
OQS_KEX_alg_code_mcbits,
OQS_KEX_alg_ntru,
OQS_KEX_alg_sidh_iqc_ref,
OQS_KEX_alg_mlwe_kyber,
};
typedef struct OQS_KEX OQS_KEX;
/**
* OQS key exchange object
*/
typedef struct OQS_KEX {
/**
* PRNG
*/
OQS_RAND *rand;
/**
* Specifies the name of the key exchange method
*/
char *method_name;
/**
* Classical security in terms of the number of bits provided by the key
* exchange method.
*/
uint16_t estimated_classical_security;
/**
* Equivalent quantum security in terms of the number of bits provided by the key
* exchange method.
*/
uint16_t estimated_quantum_security;
/**
* An instance-specific seed, if any.
*/
uint8_t *seed;
/**
* Size of instance-specific seed, if any.
*/
size_t seed_len;
/**
* Named parameters for this key exchange method instance, if any.
*/
char *named_parameters;
/**
* Opaque pointer for passing around instance-specific data
*/
void *params;
/**
* Opaque pointer for passing around any computation context
*/
void *ctx;
/**
* Pointer to a function for public and private key generation by Alice.
*
* @param k Key exchange structure
* @param alice_priv Alice's private key
* @param alice_msg Alice's message (public key + optional additional data)
* @param alice_msg_len Alice's message length
* @return 1 on success, or 0 on failure
*/
int (*alice_0)(OQS_KEX *k, void **alive_priv, uint8_t **alice_msg, size_t *alice_msg_len);
/**
* Pointer to a function for shared key generation by Bob.
*
* @param k Key exchange structure
* @param alice_msg Alice's message (public key + optional additional data)
* @param alice_msg_len Alice's message length
* @param bob_msg Bob's message (public key / encryption of shared key + optional additional data)
* @param bob_msg_len Bob's message length
* @param key Shared key
* @param key_len Shared key length
* @return 1 on success, or 0 on failure
*/
int (*bob)(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
/**
* Pointer to a function for shared key generation by Alice.
*
* @param k Key exchange structure
* @param alice_priv Alice's private key
* @param bob_msg Bob's message (public key / encryption of shared key + optional additional data)
* @param bob_msg_len Bob's message length
* @param key Shared key
* @param key_len Shared key length
* @return 1 on success, or 0 on failure
*/
int (*alice_1)(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
/**
* Pointer to a function for freeing Alice's private key
*
* @param k Key exchange structure
* @param alice_priv Alice's private key
*/
void (*alice_priv_free)(OQS_KEX *k, void *alice_priv);
/**
* Pointer to a function for freeing the allocated key exchange structure
*
* @param k Key exchange structure
*/
void (*free)(OQS_KEX *k);
} OQS_KEX;
/**
* Allocate a new key exchange object.
*
* @param rand Random number generator.
* @param alg_name Algorithm to be instantiated
* @param seed An instance-specific seed, if any, or NULL.
* @param seed_len The length of seed, or 0.
* @param named_parameters Name or description of method-specific parameters
* to use for this instance (as a NULL-terminated C string),
* if any, or NULL.
* @return The object on success, or NULL on failure.
*/
OQS_KEX *OQS_KEX_new(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters);
int OQS_KEX_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
int OQS_KEX_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
int OQS_KEX_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
void OQS_KEX_alice_priv_free(OQS_KEX *k, void *alice_priv);
void OQS_KEX_free(OQS_KEX *k);
#endif

434
vendor/liboqs/src/kex/test_kex.c vendored Normal file
View File

@@ -0,0 +1,434 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
#include "../ds_benchmark.h"
#include "../common/common.h"
struct kex_testcase {
enum OQS_KEX_alg_name alg_name;
unsigned char *seed;
size_t seed_len;
char *named_parameters;
char *id;
int run;
int iter;
};
/* Add new testcases here */
struct kex_testcase kex_testcases[] = {
#ifdef ENABLE_KEX_LWE_FRODO
{OQS_KEX_alg_lwe_frodo, (unsigned char *) "01234567890123456", 16, "recommended", "lwe_frodo_recommended", 0, 100},
#endif
#ifdef ENABLE_CODE_MCBITS
{OQS_KEX_alg_code_mcbits, NULL, 0, NULL, "code_mcbits", 0, 25},
#endif
#ifdef ENABLE_KEX_MLWE_KYBER
{OQS_KEX_alg_mlwe_kyber, NULL, 0, NULL, "mlwe_kyber", 0, 100},
#endif
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
#ifdef ENABLE_KEX_NTRU
{OQS_KEX_alg_ntru, NULL, 0, NULL, "ntru", 0, 25},
#endif
#endif
{OQS_KEX_alg_rlwe_bcns15, NULL, 0, NULL, "rlwe_bcns15", 0, 100},
#ifdef ENABLE_KEX_RLWE_MSRLN16
{OQS_KEX_alg_rlwe_msrln16, NULL, 0, NULL, "rlwe_msrln16", 0, 100},
#endif
#ifdef ENABLE_KEX_RLWE_NEWHOPE
{OQS_KEX_alg_rlwe_newhope, NULL, 0, NULL, "rlwe_newhope", 0, 100},
#endif
#ifdef ENABLE_KEX_SIDH_CLN16
{OQS_KEX_alg_sidh_cln16, NULL, 0, "p751", "sidh_cln16", 0, 10},
{OQS_KEX_alg_sidh_cln16_compressed, NULL, 0, "compressedp751", "sidh_cln16_compressed", 0, 10},
#endif
#ifdef ENABLE_SIDH_IQC_REF
{OQS_KEX_alg_sidh_iqc_ref, NULL, 0, NULL, "sidh_iqc_ref", 0, 10},
#endif
};
#define KEX_TEST_ITERATIONS 100
#define KEX_BENCH_SECONDS_DEFAULT 1
#define PRINT_HEX_STRING(label, str, len) \
{ \
printf("%-20s (%4zu bytes): ", (label), (size_t)(len)); \
for (size_t i = 0; i < (len); i++) { \
printf("%02X", ((unsigned char *) (str))[i]); \
} \
printf("\n"); \
}
static int kex_test_correctness(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, const int print, unsigned long occurrences[256]) {
OQS_KEX *kex = NULL;
int rc;
void *alice_priv = NULL;
uint8_t *alice_msg = NULL;
size_t alice_msg_len;
uint8_t *alice_key = NULL;
size_t alice_key_len;
uint8_t *bob_msg = NULL;
size_t bob_msg_len;
uint8_t *bob_key = NULL;
size_t bob_key_len;
/* setup KEX */
kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
if (kex == NULL) {
eprintf("new_method failed\n");
goto err;
}
if (print) {
printf("================================================================================\n");
printf("Sample computation for key exchange method %s\n", kex->method_name);
printf("================================================================================\n");
}
/* Alice's initial message */
rc = OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
if (rc != 1) {
eprintf("OQS_KEX_alice_0 failed\n");
goto err;
}
if (print) {
PRINT_HEX_STRING("Alice message", alice_msg, alice_msg_len)
}
/* Bob's response */
rc = OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
if (rc != 1) {
eprintf("OQS_KEX_bob failed\n");
goto err;
}
if (print) {
PRINT_HEX_STRING("Bob message", bob_msg, bob_msg_len)
PRINT_HEX_STRING("Bob session key", bob_key, bob_key_len)
}
/* Alice processes Bob's response */
rc = OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len);
if (rc != 1) {
eprintf("OQS_KEX_alice_1 failed\n");
goto err;
}
if (print) {
PRINT_HEX_STRING("Alice session key", alice_key, alice_key_len)
}
/* compare session key lengths and values */
if (alice_key_len != bob_key_len) {
eprintf("ERROR: Alice's session key and Bob's session key are different lengths (%zu vs %zu)\n", alice_key_len, bob_key_len);
goto err;
}
rc = memcmp(alice_key, bob_key, alice_key_len);
if (rc != 0) {
eprintf("ERROR: Alice's session key and Bob's session key are not equal\n");
PRINT_HEX_STRING("Alice session key", alice_key, alice_key_len)
PRINT_HEX_STRING("Bob session key", bob_key, bob_key_len)
goto err;
}
if (print) {
printf("Alice and Bob's session keys match.\n");
printf("\n\n");
}
/* record generated bytes for statistical analysis */
for (size_t i = 0; i < alice_key_len; i++) {
OQS_RAND_test_record_occurrence(alice_key[i], occurrences);
}
rc = 1;
goto cleanup;
err:
rc = 0;
cleanup:
free(alice_msg);
free(alice_key);
free(bob_msg);
free(bob_key);
OQS_KEX_alice_priv_free(kex, alice_priv);
OQS_KEX_free(kex);
return rc;
}
static int kex_test_correctness_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, int iterations, bool quiet) {
OQS_KEX *kex = NULL;
int ret;
unsigned long occurrences[256];
for (int i = 0; i < 256; i++) {
occurrences[i] = 0;
}
ret = kex_test_correctness(rand, alg_name, seed, seed_len, named_parameters, quiet ? 0 : 1, occurrences);
if (ret != 1) {
goto err;
}
/* setup KEX */
kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
if (kex == NULL) {
goto err;
}
printf("================================================================================\n");
printf("Testing correctness and randomness of key exchange method %s (params=%s) for %d iterations\n",
kex->method_name, named_parameters, iterations);
printf("================================================================================\n");
for (int i = 0; i < iterations; i++) {
ret = kex_test_correctness(rand, alg_name, seed, seed_len, named_parameters, 0, occurrences);
if (ret != 1) {
goto err;
}
}
printf("All session keys matched.\n");
OQS_RAND_report_statistics(occurrences, "");
printf("\n\n");
ret = 1;
goto cleanup;
err:
ret = 0;
cleanup:
OQS_KEX_free(kex);
return ret;
}
static void cleanup_alice_0(OQS_KEX *kex, void *alice_priv, uint8_t *alice_msg) {
free(alice_msg);
OQS_KEX_alice_priv_free(kex, alice_priv);
}
static void cleanup_bob(uint8_t *bob_msg, uint8_t *bob_key) {
free(bob_msg);
free(bob_key);
}
static int kex_bench_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, const int seconds) {
OQS_KEX *kex = NULL;
int rc;
void *alice_priv = NULL;
uint8_t *alice_msg = NULL;
size_t alice_msg_len;
uint8_t *alice_key = NULL;
size_t alice_key_len;
uint8_t *bob_msg = NULL;
size_t bob_msg_len;
uint8_t *bob_key = NULL;
size_t bob_key_len;
/* setup KEX */
kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
if (kex == NULL) {
eprintf("new_method failed\n");
goto err;
}
printf("%-30s | %10s | %14s | %15s | %10s | %16s | %10s\n", kex->method_name, "", "", "", "", "", "");
TIME_OPERATION_SECONDS({ OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len); cleanup_alice_0(kex, alice_priv, alice_msg); }, "alice 0", seconds);
OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
TIME_OPERATION_SECONDS({ OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len); cleanup_bob(bob_msg, bob_key); }, "bob", seconds);
OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
TIME_OPERATION_SECONDS({ OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len); free(alice_key); }, "alice 1", seconds);
alice_key = NULL;
printf("Communication (bytes): A->B: %zu, B->A: %zu, total: %zu; classical/quantum security bits [%u:%u] \n", alice_msg_len, bob_msg_len, alice_msg_len + bob_msg_len, kex->estimated_classical_security, kex->estimated_quantum_security);
rc = 1;
goto cleanup;
err:
rc = 0;
cleanup:
free(alice_msg);
free(alice_key);
free(bob_msg);
free(bob_key);
OQS_KEX_alice_priv_free(kex, alice_priv);
OQS_KEX_free(kex);
return rc;
}
static int kex_mem_bench_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters) {
OQS_KEX *kex = NULL;
int rc;
void *alice_priv = NULL;
uint8_t *alice_msg = NULL;
size_t alice_msg_len;
uint8_t *alice_key = NULL;
size_t alice_key_len;
uint8_t *bob_msg = NULL;
size_t bob_msg_len;
uint8_t *bob_key = NULL;
size_t bob_key_len;
kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
if (kex == NULL) {
fprintf(stderr, "new_method failed\n");
goto err;
}
printf("running %s..\n", kex->method_name);
OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len);
rc = 1;
goto cleanup;
err:
rc = 0;
cleanup:
free(alice_msg);
free(alice_key);
free(bob_msg);
free(bob_key);
OQS_KEX_alice_priv_free(kex, alice_priv);
OQS_KEX_free(kex);
return rc;
}
void print_help() {
printf("Usage: ./test_kex [options] [algorithms]\n");
printf("\nOptions:\n");
printf(" --quiet, -q\n");
printf(" Less verbose output\n");
printf(" --bench, -b\n");
printf(" Run benchmarks\n");
printf(" --seconds -s [SECONDS]\n");
printf(" Number of seconds to run benchmarks (default==%d)\n", KEX_BENCH_SECONDS_DEFAULT);
printf(" --mem-bench\n");
printf(" Run memory benchmarks (run once and allocate only what is required)\n");
printf("\nalgorithms:\n");
size_t kex_testcases_len = sizeof(kex_testcases) / sizeof(struct kex_testcase);
for (size_t i = 0; i < kex_testcases_len; i++) {
printf(" %s\n", kex_testcases[i].id);
}
}
int main(int argc, char **argv) {
int success = 1;
bool run_all = true;
bool quiet = false;
bool bench = false;
bool mem_bench = false;
size_t kex_testcases_len = sizeof(kex_testcases) / sizeof(struct kex_testcase);
size_t kex_bench_seconds = KEX_BENCH_SECONDS_DEFAULT;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
print_help();
return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--quiet") == 0 || strcmp(argv[i], "-q") == 0) {
quiet = true;
} else if (strcmp(argv[i], "--bench") == 0 || strcmp(argv[i], "-b") == 0) {
bench = true;
} else if (strcmp(argv[i], "--seconds") == 0 || strcmp(argv[i], "-s") == 0) {
if (++i == argc) {
print_help();
return EXIT_SUCCESS;
}
char *end;
int kex_bench_seconds_input = strtol(argv[i], &end, 10);
if (kex_bench_seconds_input < 1) {
print_help();
return EXIT_SUCCESS;
}
kex_bench_seconds = kex_bench_seconds_input;
} else if ((strcmp(argv[i], "--mem-bench") == 0 || strcmp(argv[i], "-m") == 0)) {
mem_bench = true;
}
} else {
run_all = false;
for (size_t j = 0; j < kex_testcases_len; j++) {
if (strcmp(argv[i], kex_testcases[j].id) == 0) {
kex_testcases[j].run = 1;
}
}
}
}
/* setup RAND */
OQS_RAND *rand = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
if (rand == NULL) {
goto err;
}
if (mem_bench) {
for (size_t i = 0; i < kex_testcases_len; i++) {
if (run_all || kex_testcases[i].run == 1) {
success = kex_mem_bench_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters);
}
if (success != 1) {
goto err;
}
}
printf("memory benchmarks done, exiting..\n");
success = 1;
goto cleanup;
}
for (size_t i = 0; i < kex_testcases_len; i++) {
if (run_all || kex_testcases[i].run == 1) {
int num_iter = kex_testcases[i].iter;
success = kex_test_correctness_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters, num_iter, quiet);
}
if (success != 1) {
goto err;
}
}
if (bench) {
PRINT_TIMER_HEADER
for (size_t i = 0; i < kex_testcases_len; i++) {
if (run_all || kex_testcases[i].run == 1) {
kex_bench_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters, kex_bench_seconds);
}
}
PRINT_TIMER_FOOTER
}
success = 1;
goto cleanup;
err:
success = 0;
eprintf("ERROR!\n");
cleanup:
OQS_RAND_free(rand);
return (success == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@@ -0,0 +1,7 @@
The files in this directory and its subdirectories (except kex_code_mcbits.*)
were originally written by Daniel J. Bernstein, Tung Chou, and Peter Schwabe
(https://www.win.tue.nl/~tchou/mcbits/).
According to the distribution website (https://www.win.tue.nl/~tchou/mcbits/):
"The software is in the public domain."

View File

@@ -0,0 +1,9 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libmcbits.la
libmcbits_la_SOURCES = external/operations.c kex_code_mcbits.c
libmcbits_la_CPPFLAGS = -I../../include -I${SODIUM_DIR}/include
libmcbits_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@@ -0,0 +1,144 @@
#if defined(WINDOWS)
#define UNUSED
// __attribute__ not supported in VS, is there something else I should define?
#else
#define UNUSED __attribute__((unused))
#endif
#include <stdlib.h>
#include <string.h>
#if !defined(WINDOWS)
#include <strings.h>
#include <unistd.h>
#endif
#include <oqs/kex.h>
#include <oqs/rand.h>
#include "kex_code_mcbits.h"
#include "mcbits.h"
OQS_KEX *OQS_KEX_code_mcbits_new(OQS_RAND *rand) {
OQS_KEX *k = malloc(sizeof(OQS_KEX));
if (k == NULL) {
return NULL;
}
k->method_name = strdup("Code Mcbits");
k->estimated_classical_security = 0; //TODO : Add these
k->estimated_quantum_security = 0;
k->seed = NULL;
k->seed_len = 0;
k->named_parameters = 0;
k->rand = rand;
k->params = NULL;
k->alice_0 = &OQS_KEX_code_mcbits_alice_0;
k->bob = &OQS_KEX_code_mcbits_bob;
k->alice_1 = &OQS_KEX_code_mcbits_alice_1;
k->alice_priv_free = &OQS_KEX_code_mcbits_alice_priv_free;
k->free = &OQS_KEX_code_mcbits_free;
return k;
}
int OQS_KEX_code_mcbits_alice_0(UNUSED OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
int ret;
/* allocate public/private key pair */
*alice_msg = malloc(CRYPTO_PUBLICKEYBYTES);
*alice_msg_len = CRYPTO_PUBLICKEYBYTES;
if (*alice_msg == NULL) {
goto err;
}
*alice_priv = malloc(CRYPTO_SECRETKEYBYTES);
if (*alice_priv == NULL) {
goto err;
}
/* generate public/private key pair */
oqs_kex_mcbits_gen_keypair(*alice_msg, *alice_priv, k->rand);
ret = 1;
goto cleanup;
err:
ret = 0;
free(*alice_msg);
*alice_msg = NULL;
free(*alice_priv);
*alice_priv = NULL;
cleanup:
return ret;
}
int OQS_KEX_code_mcbits_bob(UNUSED OQS_KEX *k, const uint8_t *alice_msg, UNUSED const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
/* allocate message and session key */
*bob_msg = malloc(CRYPTO_BYTES + 32);
if (*bob_msg == NULL) {
goto err;
}
*key = malloc(32);
if (*key == NULL) {
goto err;
}
OQS_RAND_n(k->rand, *key, 32);
oqs_kex_mcbits_encrypt(*bob_msg, bob_msg_len, *key, 32, alice_msg, k->rand);
*key_len = 32;
ret = 1;
goto cleanup;
err:
ret = 0;
free(*bob_msg);
*bob_msg = NULL;
free(*key);
*key = NULL;
cleanup:
return ret;
}
int OQS_KEX_code_mcbits_alice_1(UNUSED OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, UNUSED const size_t bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
/* allocate session key */
*key = malloc(32);
if (*key == NULL) {
goto err;
}
oqs_kex_mcbits_decrypt(*key, key_len, bob_msg, CRYPTO_BYTES + 32, alice_priv);
ret = 1;
goto cleanup;
err:
ret = 0;
free(*key);
*key = NULL;
cleanup:
return ret;
}
void OQS_KEX_code_mcbits_alice_priv_free(UNUSED OQS_KEX *k, void *alice_priv) {
if (alice_priv) {
free(alice_priv);
}
}
void OQS_KEX_code_mcbits_free(OQS_KEX *k) {
if (k) {
free(k->named_parameters);
k->named_parameters = NULL;
free(k->method_name);
k->method_name = NULL;
}
free(k);
}

View File

@@ -0,0 +1,24 @@
/**
* \file kex_code_mcbits.h
* \brief Header for code-based key exchange protocol McBits
*/
#ifndef __OQS_KEX_CODE_MCBITS_H
#define __OQS_KEX_CODE_MCBITS_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
OQS_KEX *OQS_KEX_code_mcbits_new(OQS_RAND *rand);
int OQS_KEX_code_mcbits_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
int OQS_KEX_code_mcbits_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
int OQS_KEX_code_mcbits_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
void OQS_KEX_code_mcbits_alice_priv_free(OQS_KEX *k, void *alice_priv);
void OQS_KEX_code_mcbits_free(OQS_KEX *k);
#endif

View File

@@ -0,0 +1,27 @@
/**
* \file mcbits.h
* \brief Header for internal functions of the code-based key exchange protocol McBits
*/
#ifndef __OQS_MCBITS_H
#define __OQS_MCBITS_H
#include "external/api.h"
int oqs_kex_mcbits_encrypt(
unsigned char *c, size_t *clen,
const unsigned char *m, unsigned long long mlen,
const unsigned char *pk,
OQS_RAND *r);
int oqs_kex_mcbits_decrypt(
unsigned char *m, size_t *mlen,
const unsigned char *c, unsigned long long clen,
const unsigned char *sk);
int oqs_kex_mcbits_gen_keypair(
unsigned char *pk,
unsigned char *sk,
OQS_RAND *r);
#endif

View File

@@ -0,0 +1,7 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libfrodo.la
libfrodo_la_SOURCES = kex_lwe_frodo.c lwe.c lwe_noise.c
libfrodo_la_CPPFLAGS = -I../../include -I.
libfrodo_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@@ -0,0 +1,57 @@
#if defined(WINDOWS)
#define UNUSED
#else
#define UNUSED __attribute__((unused))
#endif
#include <stdlib.h>
#include <string.h>
#if !defined(WINDOWS)
#include <strings.h>
#include <unistd.h>
#endif
#include <oqs/common.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
#include "kex_lwe_frodo.h"
#include "local.h"
#define LWE_DIV_ROUNDUP(x, y) (((x) + (y) -1) / y)
#include <stdio.h>
// pre-process code to obtain "recommended" functions
#include "recommended.h"
#define MACRIFY(NAME) NAME##_recommended
#include "kex_lwe_frodo_macrify.c"
// undefine macros to avoid any confusion later
#include "recommended.h"
#undef MACRIFY
void OQS_KEX_lwe_frodo_alice_priv_free(UNUSED OQS_KEX *k, void *alice_priv) {
free(alice_priv);
}
void OQS_KEX_lwe_frodo_free(OQS_KEX *k) {
if (!k) {
return;
}
if (k->params) {
struct oqs_kex_lwe_frodo_params *params = (struct oqs_kex_lwe_frodo_params *) k->params;
free(params->cdf_table);
params->cdf_table = NULL;
free(params->seed);
params->seed = NULL;
free(params->param_name);
params->param_name = NULL;
free(k->params);
k->params = NULL;
}
free(k->named_parameters);
k->named_parameters = NULL;
free(k->method_name);
k->method_name = NULL;
free(k);
}

View File

@@ -0,0 +1,24 @@
/**
* \file kex_lwe_frodo.h
* \brief Header for LWE key exchange protocol Frodo.
*/
#ifndef __OQS_KEX_LWE_FRODO_H
#define __OQS_KEX_LWE_FRODO_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
OQS_KEX *OQS_KEX_lwe_frodo_new_recommended(OQS_RAND *rand, const uint8_t *seed, const size_t seed_len, const char *named_parameters);
int OQS_KEX_lwe_frodo_alice_0_recommended(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
int OQS_KEX_lwe_frodo_bob_recommended(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
int OQS_KEX_lwe_frodo_alice_1_recommended(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
void OQS_KEX_lwe_frodo_alice_priv_free(OQS_KEX *k, void *alice_priv);
void OQS_KEX_lwe_frodo_free(OQS_KEX *k);
#endif

View File

@@ -0,0 +1,256 @@
OQS_KEX *MACRIFY(OQS_KEX_lwe_frodo_new)(OQS_RAND *rand, const uint8_t *seed, const size_t seed_len, const char *named_parameters) {
OQS_KEX *k;
struct oqs_kex_lwe_frodo_params *params;
if ((seed_len == 0) || (seed == NULL)) {
return NULL;
}
k = malloc(sizeof(OQS_KEX));
if (k == NULL) {
goto err;
}
k->named_parameters = NULL;
k->method_name = NULL;
k->params = malloc(sizeof(struct oqs_kex_lwe_frodo_params));
if (NULL == k->params) {
goto err;
}
params = (struct oqs_kex_lwe_frodo_params *) k->params;
params->cdf_table = NULL;
params->seed = NULL;
params->param_name = NULL;
k->rand = rand;
k->ctx = NULL;
k->alice_priv_free = &OQS_KEX_lwe_frodo_alice_priv_free;
k->free = &OQS_KEX_lwe_frodo_free;
if (strcmp(named_parameters, "recommended") == 0) {
k->alice_0 = &OQS_KEX_lwe_frodo_alice_0_recommended;
k->bob = &OQS_KEX_lwe_frodo_bob_recommended;
k->alice_1 = &OQS_KEX_lwe_frodo_alice_1_recommended;
k->method_name = strdup("LWE Frodo recommended");
if (NULL == k->method_name) {
goto err;
}
k->estimated_classical_security = 144;
k->estimated_quantum_security = 130;
k->named_parameters = strdup(named_parameters);
if (k->named_parameters == NULL) {
goto err;
}
params->seed = malloc(seed_len);
if (NULL == params->seed) {
goto err;
}
memcpy(params->seed, seed, seed_len);
params->seed_len = seed_len;
params->param_name = strdup("recommended");
if (NULL == params->param_name) {
goto err;
}
params->log2_q = PARAMS_LOG2Q;
params->q = PARAMS_Q;
params->n = PARAMS_N;
params->extracted_bits = PARAMS_EXTRACTED_BITS;
params->nbar = PARAMS_NBAR;
params->key_bits = PARAMS_KEY_BITS;
params->rec_hint_len = PARAMS_REC_HINT_LENGTH;
params->pub_len = PARAMS_REC_PUB_LENGTH;
params->stripe_step = PARAMS_STRIPE_STEP;
params->sampler_num = 12;
params->cdf_table_len = 6;
params->cdf_table = malloc(params->cdf_table_len * sizeof(uint16_t));
if (NULL == params->cdf_table) {
goto err;
}
uint16_t cdf_table_tmp[6] = {602, 1521, 1927, 2031, 2046, 2047};
memcpy(params->cdf_table, cdf_table_tmp, sizeof(cdf_table_tmp));
} else {
goto err;
}
return k;
err:
OQS_KEX_lwe_frodo_free(k);
return NULL;
}
int MACRIFY(OQS_KEX_lwe_frodo_alice_0)(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
int ret;
struct oqs_kex_lwe_frodo_params *params = (struct oqs_kex_lwe_frodo_params *) k->params;
*alice_priv = NULL;
*alice_msg = NULL;
/* allocate private key, error, and outgoing message */
*alice_priv = malloc(PARAMS_N * PARAMS_NBAR * sizeof(uint16_t));
if (*alice_priv == NULL) {
goto err;
}
uint16_t b[PARAMS_N * PARAMS_NBAR];
uint16_t e[PARAMS_N * PARAMS_NBAR];
*alice_msg = malloc(PARAMS_REC_PUB_LENGTH);
*alice_msg_len = PARAMS_REC_PUB_LENGTH;
if (*alice_msg == NULL) {
goto err;
}
/* generate S and E */
oqs_kex_lwe_frodo_sample_n(*alice_priv, PARAMS_N * PARAMS_NBAR, params, k->rand);
oqs_kex_lwe_frodo_sample_n(e, PARAMS_N * PARAMS_NBAR, params, k->rand);
/* compute B = AS + E */
MACRIFY(oqs_kex_lwe_frodo_mul_add_as_plus_e_on_the_fly)
(b, *alice_priv, e, params);
oqs_kex_lwe_frodo_pack(*alice_msg, PARAMS_REC_PUB_LENGTH, b, PARAMS_N * PARAMS_NBAR, PARAMS_LOG2Q);
ret = 1;
goto cleanup;
err:
OQS_MEM_cleanse(e, sizeof(e));
free(*alice_msg);
*alice_msg = NULL;
free(*alice_priv);
*alice_priv = NULL;
ret = 0;
cleanup:
return ret;
}
int MACRIFY(OQS_KEX_lwe_frodo_bob)(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
struct oqs_kex_lwe_frodo_params *params = (struct oqs_kex_lwe_frodo_params *) k->params;
uint8_t *bob_rec = NULL;
*bob_msg = NULL;
*key = NULL;
/* check length of other party's public key */
if (alice_msg_len != PARAMS_REC_PUB_LENGTH) {
goto err;
}
/* allocate private key, errors, outgoing message, and key */
uint16_t bob_priv[PARAMS_N * PARAMS_NBAR];
uint16_t bprime[PARAMS_N * PARAMS_NBAR];
uint16_t eprime[PARAMS_N * PARAMS_NBAR];
uint16_t eprimeprime[PARAMS_N * PARAMS_NBAR];
uint16_t b[PARAMS_N * PARAMS_NBAR];
uint16_t v[PARAMS_N * PARAMS_NBAR];
*bob_msg = malloc(PARAMS_REC_PUB_LENGTH + PARAMS_REC_HINT_LENGTH);
if (*bob_msg == NULL) {
goto err;
}
bob_rec = *bob_msg + PARAMS_REC_PUB_LENGTH;
*key = malloc(PARAMS_KEY_BYTES);
if (*key == NULL) {
goto err;
}
/* generate S' and E' */
oqs_kex_lwe_frodo_sample_n(bob_priv, PARAMS_N * PARAMS_NBAR, params, k->rand);
oqs_kex_lwe_frodo_sample_n(eprime, PARAMS_N * PARAMS_NBAR, params, k->rand);
/* compute B' = S'A + E' */
MACRIFY(oqs_kex_lwe_frodo_mul_add_sa_plus_e_on_the_fly)
(bprime, bob_priv, eprime, params);
oqs_kex_lwe_frodo_pack(*bob_msg, PARAMS_REC_PUB_LENGTH, bprime, PARAMS_N * PARAMS_NBAR, PARAMS_LOG2Q);
/* generate E'' */
oqs_kex_lwe_frodo_sample_n(eprimeprime, PARAMS_NBAR * PARAMS_NBAR, params, k->rand);
/* unpack B */
oqs_kex_lwe_frodo_unpack(b, PARAMS_N * PARAMS_NBAR, alice_msg, alice_msg_len, PARAMS_LOG2Q);
/* compute V = S'B + E'' */
MACRIFY(oqs_kex_lwe_frodo_mul_add_sb_plus_e)
(v, b, bob_priv, eprimeprime);
/* compute C = <V>_{2^B} */
MACRIFY(oqs_kex_lwe_frodo_crossround2)
(bob_rec, v);
/* compute K = round(V)_{2^B} */
MACRIFY(oqs_kex_lwe_frodo_round2)
(*key, v);
*bob_msg_len = PARAMS_REC_PUB_LENGTH + PARAMS_REC_HINT_LENGTH;
*key_len = PARAMS_KEY_BYTES;
ret = 1;
goto cleanup;
err:
ret = 0;
free(*bob_msg);
*bob_msg = NULL;
OQS_MEM_secure_free(*key, PARAMS_KEY_BYTES);
*key = NULL;
cleanup:
OQS_MEM_cleanse(eprime, sizeof(eprime));
OQS_MEM_cleanse(eprimeprime, sizeof(eprimeprime));
OQS_MEM_cleanse(v, sizeof(v));
return ret;
}
int MACRIFY(OQS_KEX_lwe_frodo_alice_1)(UNUSED OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
*key = NULL;
/* check length of other party's public key */
if (bob_msg_len != PARAMS_REC_PUB_LENGTH + PARAMS_REC_HINT_LENGTH) {
goto err;
}
/* allocate working values and session key */
uint16_t bprime[PARAMS_N * PARAMS_NBAR];
uint16_t w[PARAMS_N * PARAMS_NBAR];
*key = malloc(PARAMS_KEY_BYTES);
if (*key == NULL) {
goto err;
}
/* unpack B' */
oqs_kex_lwe_frodo_unpack(bprime, PARAMS_N * PARAMS_NBAR, bob_msg, PARAMS_REC_PUB_LENGTH, PARAMS_LOG2Q);
/* compute W = B'S */
MACRIFY(oqs_kex_lwe_frodo_mul_bs)
(w, bprime, (uint16_t *) alice_priv);
/* compute K = rec(B'S, C) */
const uint8_t *bob_rec = bob_msg + PARAMS_REC_PUB_LENGTH;
MACRIFY(oqs_kex_lwe_frodo_reconcile)
(*key, w, bob_rec);
*key_len = PARAMS_KEY_BYTES;
ret = 1;
goto cleanup;
err:
ret = 0;
OQS_MEM_secure_free(*key, PARAMS_KEY_BYTES);
*key = NULL;
cleanup:
return ret;
}

42
vendor/liboqs/src/kex_lwe_frodo/local.h vendored Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _OQS_KEX_LWE_FRODO_LOCAL_H_
#define _OQS_KEX_LWE_FRODO_LOCAL_H_
#include <stdint.h>
#include <oqs/rand.h>
struct oqs_kex_lwe_frodo_params {
uint8_t *seed;
size_t seed_len;
char *param_name;
uint16_t log2_q;
uint16_t q;
uint16_t n;
uint16_t extracted_bits;
uint16_t nbar;
uint16_t key_bits;
uint16_t rec_hint_len;
uint32_t pub_len;
uint16_t stripe_step;
int sampler_num;
uint16_t *cdf_table;
size_t cdf_table_len;
};
void oqs_kex_lwe_frodo_crossround2_recommended(unsigned char *out, const uint16_t *in);
void oqs_kex_lwe_frodo_round2_recommended(unsigned char *out, uint16_t *in);
void oqs_kex_lwe_frodo_reconcile_recommended(unsigned char *out, uint16_t *w, const unsigned char *hint);
void oqs_kex_lwe_frodo_key_round(uint16_t *vec, const size_t length, const int b);
void oqs_kex_lwe_frodo_key_round_hints(uint16_t *vec, const size_t length, const int b, const unsigned char *hint);
void oqs_kex_lwe_frodo_pack(unsigned char *out, const size_t outlen, const uint16_t *in, const size_t inlen, const unsigned char lsb);
void oqs_kex_lwe_frodo_unpack(uint16_t *out, const size_t outlen, const unsigned char *in, const size_t inlen, const unsigned char lsb);
void oqs_kex_lwe_frodo_sample_n(uint16_t *s, const size_t n, struct oqs_kex_lwe_frodo_params *params, OQS_RAND *rand);
void oqs_kex_lwe_frodo_mul_add_as_plus_e_on_the_fly_recommended(uint16_t *b, const uint16_t *s, const uint16_t *e, struct oqs_kex_lwe_frodo_params *params);
void oqs_kex_lwe_frodo_mul_add_sa_plus_e_on_the_fly_recommended(uint16_t *b, const uint16_t *s, const uint16_t *e, struct oqs_kex_lwe_frodo_params *params);
void oqs_kex_lwe_frodo_mul_add_sb_plus_e_recommended(uint16_t *out, const uint16_t *b, const uint16_t *s, const uint16_t *e);
void oqs_kex_lwe_frodo_mul_bs_recommended(uint16_t *out, const uint16_t *b, const uint16_t *s);
#endif /* _OQS_KEX_RLWE_BCNS15_LOCAL_H_ */

150
vendor/liboqs/src/kex_lwe_frodo/lwe.c vendored Normal file
View File

@@ -0,0 +1,150 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "local.h"
#include <oqs/aes.h>
#define min(x, y) (((x) < (y)) ? (x) : (y))
// round all elements of a vector to the nearest multiple of 2^b
void oqs_kex_lwe_frodo_key_round(uint16_t *vec, const size_t length, const int b) {
size_t i;
uint16_t negmask = ~((1 << b) - 1);
uint16_t half = b > 0 ? 1 << (b - 1) : 0;
for (i = 0; i < length; i++) {
vec[i] = (vec[i] + half) & negmask;
}
}
// Round all elements of a vector to the multiple of 2^b, with a hint for the
// direction of rounding when close to the boundary.
void oqs_kex_lwe_frodo_key_round_hints(uint16_t *vec, const size_t length, const int b, const unsigned char *hint) {
size_t i;
uint16_t whole = 1 << b;
uint16_t mask = whole - 1;
uint16_t negmask = ~mask;
uint16_t half = 1 << (b - 1);
uint16_t quarter = 1 << (b - 2);
for (i = 0; i < length; i++) {
uint16_t remainder = vec[i] & mask;
uint16_t use_hint = ((remainder + quarter) >> (b - 1)) & 0x1;
unsigned char h = (hint[i / 8] >> (i % 8)) % 2; // the hint
uint16_t shift = use_hint * (2 * h - 1) * quarter;
// if use_hint = 1 and h = 0, adding -quarter forces rounding down
// h = 1, adding quarter forces rounding up
vec[i] = (vec[i] + half + shift) & negmask;
}
}
// Pack the input uint16 vector into a char output vector, copying lsb bits
// from each input element. If inlen * lsb / 8 > outlen, only outlen * 8 bits
// are copied.
void oqs_kex_lwe_frodo_pack(unsigned char *out, const size_t outlen, const uint16_t *in, const size_t inlen, const unsigned char lsb) {
memset(out, 0, outlen);
size_t i = 0; // whole bytes already filled in
size_t j = 0; // whole uint16_t already copied
uint16_t w = 0; // the leftover, not yet copied
unsigned char bits = 0; // the number of lsb in w
while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
/*
in: | | |********|********|
^
j
w : | ****|
^
bits
out:|**|**|**|**|**|**|**|**|* |
^^
ib
*/
unsigned char b = 0; // bits in out[i] already filled in
while (b < 8) {
int nbits = min(8 - b, bits);
uint16_t mask = (1 << nbits) - 1;
unsigned char t = (w >> (bits - nbits)) & mask; // the bits to copy from w to out
out[i] += t << (8 - b - nbits);
b += nbits;
bits -= nbits;
w &= ~(mask << bits); // not strictly necessary; mostly for debugging
if (bits == 0) {
if (j < inlen) {
w = in[j];
bits = lsb;
j++;
} else {
break; // the input vector is exhausted
}
}
}
if (b == 8) { // out[i] is filled in
i++;
}
}
}
// Unpack the input char vector into a uint16_t output vector, copying lsb bits
// for each output element from input. outlen must be at least ceil(inlen * 8 /
// lsb).
void oqs_kex_lwe_frodo_unpack(uint16_t *out, const size_t outlen, const unsigned char *in, const size_t inlen, const unsigned char lsb) {
memset(out, 0, outlen * sizeof(uint16_t));
size_t i = 0; // whole uint16_t already filled in
size_t j = 0; // whole bytes already copied
unsigned char w = 0; // the leftover, not yet copied
unsigned char bits = 0; // the number of lsb bits of w
while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
/*
in: | | | | | | |**|**|...
^
j
w : | *|
^
bits
out:| *****| *****| *** | |...
^ ^
i b
*/
unsigned char b = 0; // bits in out[i] already filled in
while (b < lsb) {
int nbits = min(lsb - b, bits);
uint16_t mask = (1 << nbits) - 1;
unsigned char t = (w >> (bits - nbits)) & mask; // the bits to copy from w to out
out[i] += t << (lsb - b - nbits);
b += nbits;
bits -= nbits;
w &= ~(mask << bits); // not strictly necessary; mostly for debugging
if (bits == 0) {
if (j < inlen) {
w = in[j];
bits = 8;
j++;
} else {
break; // the input vector is exhausted
}
}
}
if (b == lsb) { // out[i] is filled in
i++;
}
}
}
// define parameters for "recommended" parameter set
#include "recommended.h"
// pre-process code to obtain "recommended" functions
#define MACRIFY(NAME) NAME##_recommended
#include "lwe_macrify.c"
// undefine macros to avoid any confusion later
#include "recommended.h"
#undef MACRIFY

View File

@@ -0,0 +1,160 @@
// [.]_2
void MACRIFY(oqs_kex_lwe_frodo_round2)(unsigned char *out, uint16_t *in) {
oqs_kex_lwe_frodo_key_round(in, PARAMS_NBAR * PARAMS_NBAR, PARAMS_LOG2Q - PARAMS_EXTRACTED_BITS);
for (int i = 0; i < PARAMS_NBAR * PARAMS_NBAR; i++) {
in[i] >>= PARAMS_LOG2Q - PARAMS_EXTRACTED_BITS; // drop bits that were zeroed out
}
// out should have enough space for the key
oqs_kex_lwe_frodo_pack(out, PARAMS_KEY_BITS / 8, in, PARAMS_NBAR * PARAMS_NBAR, PARAMS_EXTRACTED_BITS);
}
void MACRIFY(oqs_kex_lwe_frodo_crossround2)(unsigned char *out, const uint16_t *in) {
// out should have enough space for N_BAR * N_BAR bits
memset((unsigned char *) out, 0, PARAMS_REC_HINT_LENGTH);
uint16_t whole = 1 << (PARAMS_LOG2Q - PARAMS_EXTRACTED_BITS);
uint16_t half = whole >> 1;
uint16_t mask = whole - 1;
for (int i = 0; i < PARAMS_NBAR * PARAMS_NBAR; i++) {
uint16_t remainder = in[i] & mask;
out[i / 8] += (remainder >= half) << (i % 8);
}
}
void MACRIFY(oqs_kex_lwe_frodo_reconcile)(unsigned char *out, uint16_t *w, const unsigned char *hint) {
oqs_kex_lwe_frodo_key_round_hints(w, PARAMS_NBAR * PARAMS_NBAR, PARAMS_LOG2Q - PARAMS_EXTRACTED_BITS, hint);
for (int i = 0; i < PARAMS_NBAR * PARAMS_NBAR; i++) {
w[i] >>= PARAMS_LOG2Q - PARAMS_EXTRACTED_BITS; // drop bits that were zeroed out
}
oqs_kex_lwe_frodo_pack(out, PARAMS_KEY_BITS / 8, w, PARAMS_NBAR * PARAMS_NBAR, PARAMS_EXTRACTED_BITS);
}
// Generate-and-multiply: generate A row-wise, multiply by s on the right.
void MACRIFY(oqs_kex_lwe_frodo_mul_add_as_plus_e_on_the_fly)(uint16_t *out, const uint16_t *s, const uint16_t *e, struct oqs_kex_lwe_frodo_params *params) {
// A (N x N)
// s,e (N x N_BAR)
// out = A * s + e (N x N_BAR)
memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t));
// transpose s to store it in the column-major order
uint16_t s_transpose[PARAMS_NBAR * PARAMS_N];
for (int j = 0; j < PARAMS_N; j++) {
for (int k = 0; k < PARAMS_NBAR; k++) {
s_transpose[k * PARAMS_N + j] = s[j * PARAMS_NBAR + k];
}
}
assert(params->seed_len == 16);
void *aes_key_schedule = NULL;
OQS_AES128_load_schedule(params->seed, &aes_key_schedule, 1);
for (int i = 0; i < PARAMS_N; i++) {
uint16_t a_row[PARAMS_N] = {0};
// go through A's rows
for (int j = 0; j < PARAMS_N; j += PARAMS_STRIPE_STEP) {
// Loading values in the little-endian order!
a_row[j] = i;
a_row[j + 1] = j;
}
OQS_AES128_ECB_enc_sch((uint8_t *) a_row, sizeof(a_row), aes_key_schedule, (uint8_t *) a_row);
for (int k = 0; k < PARAMS_NBAR; k++) {
uint16_t sum = 0;
for (int j = 0; j < PARAMS_N; j++) {
// matrix-vector multiplication happens here
sum += a_row[j] * s_transpose[k * PARAMS_N + j];
}
out[i * PARAMS_NBAR + k] += sum;
//Equivalent to %= PARAMS_Q if PARAMS_Q is a power of 2
out[i * PARAMS_NBAR + k] &= PARAMS_Q - 1;
}
}
OQS_AES128_free_schedule(aes_key_schedule);
}
// Generate-and-multiply: generate A column-wise, multiply by s' on the left.
void MACRIFY(oqs_kex_lwe_frodo_mul_add_sa_plus_e_on_the_fly)(uint16_t *out, const uint16_t *s, const uint16_t *e, struct oqs_kex_lwe_frodo_params *params) {
// a (N x N)
// s',e' (N_BAR x N)
// out = s'a + e' (N_BAR x N)
memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t));
assert(params->seed_len == 16);
void *aes_key_schedule = NULL;
OQS_AES128_load_schedule(params->seed, &aes_key_schedule, 1);
for (int kk = 0; kk < PARAMS_N; kk += PARAMS_STRIPE_STEP) {
// Go through A's columns, 8 (== PARAMS_STRIPE_STEP) columns at a time.
// a_cols stores 8 columns of A at a time.
uint16_t a_cols[PARAMS_N * PARAMS_STRIPE_STEP] = {0};
for (int i = 0; i < PARAMS_N; i++) {
// Loading values in the little-endian order!
a_cols[i * PARAMS_STRIPE_STEP] = i;
a_cols[i * PARAMS_STRIPE_STEP + 1] = kk;
}
OQS_AES128_ECB_enc_sch((uint8_t *) a_cols, sizeof(a_cols), aes_key_schedule, (uint8_t *) a_cols);
// transpose a_cols to have access to it in the column-major order.
uint16_t a_cols_t[PARAMS_N * PARAMS_STRIPE_STEP];
for (int i = 0; i < PARAMS_N; i++) {
for (int k = 0; k < PARAMS_STRIPE_STEP; k++) {
a_cols_t[k * PARAMS_N + i] = a_cols[i * PARAMS_STRIPE_STEP + k];
}
}
for (int i = 0; i < PARAMS_NBAR; i++) {
for (int k = 0; k < PARAMS_STRIPE_STEP; k++) {
uint16_t sum = 0;
for (int j = 0; j < PARAMS_N; j++) {
sum += s[i * PARAMS_N + j] * a_cols_t[k * PARAMS_N + j];
}
out[i * PARAMS_N + kk + k] += sum;
out[i * PARAMS_N + kk + k] &= PARAMS_Q - 1; //Works as long as PARAMS_Q is a power of 2
}
}
}
OQS_AES128_free_schedule(aes_key_schedule);
}
// multiply by s on the right
void MACRIFY(oqs_kex_lwe_frodo_mul_bs)(uint16_t *out, const uint16_t *b, const uint16_t *s) {
// b (N_BAR x N)
// s (N x N_BAR)
// out = bs
for (int i = 0; i < PARAMS_NBAR; i++) {
for (int j = 0; j < PARAMS_NBAR; j++) {
uint16_t sum = 0;
for (int k = 0; k < PARAMS_N; k++) {
sum += b[i * PARAMS_N + k] * s[k * PARAMS_NBAR + j];
}
out[i * PARAMS_NBAR + j] = sum & (PARAMS_Q - 1);
}
}
}
// multiply by s on the left
void MACRIFY(oqs_kex_lwe_frodo_mul_add_sb_plus_e)(uint16_t *out, const uint16_t *b, const uint16_t *s, const uint16_t *e) {
// b (N x N_BAR)
// s (N_BAR x N)
// e (N_BAR x N_BAR)
// out = sb + e
memcpy(out, e, PARAMS_NBAR * PARAMS_NBAR * sizeof(uint16_t));
for (int k = 0; k < PARAMS_NBAR; k++) {
for (int i = 0; i < PARAMS_NBAR; i++) {
uint16_t sum = 0;
for (int j = 0; j < PARAMS_N; j++) {
sum += s[k * PARAMS_N + j] * b[j * PARAMS_NBAR + i];
}
out[k * PARAMS_NBAR + i] += sum;
out[k * PARAMS_NBAR + i] &= PARAMS_Q - 1; // not really necessary since LWE_Q is a power of 2.
}
}
}

View File

@@ -0,0 +1,136 @@
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <oqs/common.h>
#include <oqs/rand.h>
#include "local.h"
#define RECOMMENDED_N_ARRAY_SIZE (752 * 8)
#define RECOMMENDED_CDF_TABLE_LEN 6
#if defined(WINDOWS)
// VS complains about arrays initialized with const param. On Windows,
// we use directly the recommended value passed down from calling functions.
// Currently there is only one set of params, so that works. Need to fix this
// in a more general setting (TODO).
#define IS_WINDOWS(windows, nix) (windows)
#else
#define IS_WINDOWS(windows, nix) (nix)
#endif
static void lwe_sample_n_inverse_8(uint16_t *s, const size_t n, const uint8_t *cdf_table, const size_t cdf_table_len, OQS_RAND *rand) {
/* Fills vector s with n samples from the noise distribution which requires
* 8 bits to sample. The distribution is specified by its CDF. Super-constant
* timing: the CDF table is ingested for every sample.
*/
uint8_t rndvec[IS_WINDOWS(RECOMMENDED_N_ARRAY_SIZE, n)];
OQS_RAND_n(rand, rndvec, sizeof(rndvec));
for (size_t i = 0; i < n; ++i) {
uint8_t sample = 0;
uint8_t rnd = rndvec[i] >> 1; // drop the least significant bit
uint8_t sign = rndvec[i] & 0x1; // pick the least significant bit
// No need to compare with the last value.
for (size_t j = 0; j < cdf_table_len - 1; j++) {
// Constant time comparison: 1 if cdf_table[j] < rnd, 0 otherwise.
// Critically uses the fact that cdf_table[j] and rnd fit in 7 bits.
sample += (uint8_t)(cdf_table[j] - rnd) >> 7;
}
// Assuming that sign is either 0 or 1, flips sample iff sign = 1
s[i] = ((-sign) ^ sample) + sign;
}
OQS_MEM_cleanse(rndvec, sizeof(rndvec));
}
static void lwe_sample_n_inverse_12(uint16_t *s, const size_t n, const uint16_t *cdf_table, const size_t cdf_table_len, OQS_RAND *rand) {
/* Fills vector s with n samples from the noise distribution which requires
* 12 bits to sample. The distribution is specified by its CDF. Super-constant
* timing: the CDF table is ingested for every sample.
*/
uint8_t rnd[3 * ((IS_WINDOWS(RECOMMENDED_N_ARRAY_SIZE, n) + 1) / 2)]; // 12 bits of unif randomness per output element
OQS_RAND_n(rand, rnd, sizeof(rnd));
for (size_t i = 0; i < n; i += 2) { // two output elements at a time
uint8_t *pRnd = (rnd + 3 * i / 2);
uint16_t rnd1 = (((pRnd[0] << 8) + pRnd[1]) & 0xFFE0) >> 5; // first 11 bits (0..10)
uint16_t rnd2 = (((pRnd[1] << 8) + pRnd[2]) & 0x1FFC) >> 2; // next 11 bits (11..21)
uint8_t sample1 = 0;
uint8_t sample2 = 0;
// No need to compare with the last value.
for (size_t j = 0; j < cdf_table_len - 1; j++) {
// Constant time comparison: 1 if LWE_CDF_TABLE[j] < rnd1, 0 otherwise.
// Critically uses the fact that LWE_CDF_TABLE[j] and rnd1 fit in 15 bits.
sample1 += (uint16_t)(cdf_table[j] - rnd1) >> 15;
sample2 += (uint16_t)(cdf_table[j] - rnd2) >> 15;
}
uint8_t sign1 = (pRnd[2] & 0x02) >> 1; // 22nd bit
uint8_t sign2 = pRnd[2] & 0x01; // 23rd bit
// Assuming that sign1 is either 0 or 1, flips sample1 iff sign1 = 1
s[i] = ((-sign1) ^ sample1) + sign1;
if (i + 1 < n) {
s[i + 1] = ((-sign2) ^ sample2) + sign2;
}
}
OQS_MEM_cleanse(rnd, sizeof(rnd));
}
static void lwe_sample_n_inverse_16(uint16_t *s, const size_t n, const uint16_t *cdf_table, const size_t cdf_table_len, OQS_RAND *rand) {
/* Fills vector s with n samples from the noise distribution which requires
* 16 bits to sample. The distribution is specified by its CDF. Super-constant
* timing: the CDF table is ingested for every sample.
*/
uint16_t rndvec[IS_WINDOWS(RECOMMENDED_N_ARRAY_SIZE, n)];
OQS_RAND_n(rand, (uint8_t *) rndvec, sizeof(rndvec));
for (size_t i = 0; i < n; ++i) {
uint8_t sample = 0;
uint16_t rnd = rndvec[i] >> 1; // drop the least significant bit
uint8_t sign = rndvec[i] & 0x1; // pick the least significant bit
// No need to compare with the last value.
for (size_t j = 0; j < cdf_table_len - 1; j++) {
// Constant time comparison: 1 if LWE_CDF_TABLE[j] < rnd, 0 otherwise.
// Critically uses the fact that LWE_CDF_TABLE[j] and rnd fit in 15 bits.
sample += (uint16_t)(cdf_table[j] - rnd) >> 15;
}
// Assuming that sign is either 0 or 1, flips sample iff sign = 1
s[i] = ((-sign) ^ sample) + sign;
}
OQS_MEM_cleanse(rndvec, sizeof(rndvec));
}
void oqs_kex_lwe_frodo_sample_n(uint16_t *s, const size_t n, struct oqs_kex_lwe_frodo_params *params, OQS_RAND *rand) {
switch (params->sampler_num) {
case 8: {
// have to copy cdf_table from uint16_t to uint8_t
uint8_t cdf_table_8[IS_WINDOWS(RECOMMENDED_CDF_TABLE_LEN, params->cdf_table_len) * sizeof(uint8_t)];
for (size_t i = 0; i < params->cdf_table_len; i++) {
cdf_table_8[i] = (uint8_t) params->cdf_table[i];
}
lwe_sample_n_inverse_8(s, n, cdf_table_8, params->cdf_table_len, rand);
} break;
case 12:
lwe_sample_n_inverse_12(s, n, params->cdf_table, params->cdf_table_len, rand);
break;
case 16:
lwe_sample_n_inverse_16(s, n, params->cdf_table, params->cdf_table_len, rand);
break;
default:
assert(0); //ERROR
break;
}
}

View File

@@ -0,0 +1,29 @@
//Recommended parameter set. Include twice to undefine
#ifndef OQS_LWE_FRODO_RECOMMENDED_H
#define OQS_LWE_FRODO_RECOMMENDED_H
#define PARAMS_N 752
#define PARAMS_NBAR 8
#define PARAMS_LOG2Q 15
#define PARAMS_Q (1 << PARAMS_LOG2Q)
#define PARAMS_EXTRACTED_BITS 4
#define PARAMS_KEY_BITS 256
#define PARAMS_KEY_BYTES (PARAMS_KEY_BITS >> 3)
#define PARAMS_STRIPE_STEP 8
#define LWE_DIV_ROUNDUP(x, y) (((x) + (y) -1) / y)
#define PARAMS_REC_HINT_LENGTH LWE_DIV_ROUNDUP(PARAMS_NBAR *PARAMS_NBAR, 8)
#define PARAMS_REC_PUB_LENGTH LWE_DIV_ROUNDUP(PARAMS_N *PARAMS_NBAR *PARAMS_LOG2Q, 8)
#else
#undef OQS_LWE_FRODO_RECOMMENDED_H
#undef PARAMS_N
#undef PARAMS_NBAR
#undef PARAMS_LOG2Q
#undef PARAMS_Q
#undef PARAMS_EXTRACTED_BITS
#undef PARAMS_KEY_BITS
#undef PARAMS_STRIPE_STEP
#undef LWE_DIV_ROUNDUP
#undef PARAMS_REC_HINT_LENGTH
#endif

View File

@@ -0,0 +1,7 @@
The files in this directory (except kex_mlwe_kyber.*) were originally published in https://github.com/pq-crystals/kyber
The following license applies to all files in the src/kex_mlwe_kyber directory.
Public domain.

View File

@@ -0,0 +1,8 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libkyber.la
libkyber_la_SOURCES = kex_mlwe_kyber.c
libkyber_la_CPPFLAGS = -I../../include -I.
libkyber_la_CPPFLAGS += $(AM_CPPFLAGS)

View File

@@ -0,0 +1,179 @@
#include "params.h"
#include <oqs/rand.h>
#include <oqs/sha3.h>
static void pack_pk(unsigned char *r, const polyvec *pk, const unsigned char *seed) {
int i;
polyvec_compress(r, pk);
for (i = 0; i < KYBER_SEEDBYTES; i++)
r[i + KYBER_POLYVECCOMPRESSEDBYTES] = seed[i];
}
static void unpack_pk(polyvec *pk, unsigned char *seed, const unsigned char *packedpk) {
int i;
polyvec_decompress(pk, packedpk);
for (i = 0; i < KYBER_SEEDBYTES; i++)
seed[i] = packedpk[i + KYBER_POLYVECCOMPRESSEDBYTES];
}
static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) {
polyvec_compress(r, b);
poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v);
}
static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) {
polyvec_decompress(b, c);
poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES);
}
static void pack_sk(unsigned char *r, const polyvec *sk) {
polyvec_tobytes(r, sk);
}
static void unpack_sk(polyvec *sk, const unsigned char *packedsk) {
polyvec_frombytes(sk, packedsk);
}
#define gen_a(A, B) gen_matrix(A, B, 0)
#define gen_at(A, B) gen_matrix(A, B, 1)
/* Generate entry a_{i,j} of matrix A as Parse(SHAKE128(seed|i|j)) */
static void gen_matrix(polyvec *a, const unsigned char *seed, int transposed) //XXX: Not static for benchmarking
{
unsigned int pos = 0, ctr;
uint16_t val;
unsigned int nblocks = 4;
uint8_t buf[OQS_SHA3_SHAKE128_RATE * 4]; // was * nblocks, but VS doesn't like this buf init
int i, j;
uint16_t dsep;
uint64_t state[25]; // CSHAKE state
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_D; j++) {
ctr = pos = 0;
if (transposed)
dsep = j + (i << 8);
else
dsep = i + (j << 8);
OQS_SHA3_cshake128_simple_absorb(state, dsep, seed, KYBER_SEEDBYTES);
OQS_SHA3_cshake128_simple_squeezeblocks(buf, nblocks, state);
while (ctr < KYBER_N) {
val = (buf[pos] | ((uint16_t) buf[pos + 1] << 8)) & 0x1fff;
if (val < KYBER_Q) {
a[i].vec[j].coeffs[ctr++] = val;
}
pos += 2;
if (pos > OQS_SHA3_SHAKE128_RATE * nblocks - 2) {
nblocks = 1;
OQS_SHA3_cshake128_simple_squeezeblocks(buf, nblocks, state);
pos = 0;
}
}
}
}
}
static void indcpa_keypair(unsigned char *pk,
unsigned char *sk, OQS_RAND *rand) {
polyvec a[KYBER_D], e, pkpv, skpv;
unsigned char seed[KYBER_SEEDBYTES];
unsigned char noiseseed[KYBER_COINBYTES];
int i;
unsigned char nonce = 0;
rand->rand_n(rand, seed, KYBER_SEEDBYTES);
OQS_SHA3_shake128(seed, KYBER_SEEDBYTES, seed, KYBER_SEEDBYTES); /* Don't send output of system RNG */
rand->rand_n(rand, noiseseed, KYBER_COINBYTES);
gen_a(a, seed);
for (i = 0; i < KYBER_D; i++)
poly_getnoise(skpv.vec + i, noiseseed, nonce++);
polyvec_ntt(&skpv);
for (i = 0; i < KYBER_D; i++)
poly_getnoise(e.vec + i, noiseseed, nonce++);
// matrix-vector multiplication
for (i = 0; i < KYBER_D; i++)
polyvec_pointwise_acc(&pkpv.vec[i], &skpv, a + i);
polyvec_invntt(&pkpv);
polyvec_add(&pkpv, &pkpv, &e);
pack_sk(sk, &skpv);
pack_pk(pk, &pkpv, seed);
}
static void indcpa_enc(unsigned char *c,
const unsigned char *m,
const unsigned char *pk,
const unsigned char *coins) {
polyvec sp, pkpv, ep, at[KYBER_D], bp;
poly v, k, epp;
unsigned char seed[KYBER_SEEDBYTES];
int i;
unsigned char nonce = 0;
unpack_pk(&pkpv, seed, pk);
poly_frommsg(&k, m);
for (i = 0; i < KYBER_D; i++)
bitrev_vector(pkpv.vec[i].coeffs);
polyvec_ntt(&pkpv);
gen_at(at, seed);
for (i = 0; i < KYBER_D; i++)
poly_getnoise(sp.vec + i, coins, nonce++);
polyvec_ntt(&sp);
for (i = 0; i < KYBER_D; i++)
poly_getnoise(ep.vec + i, coins, nonce++);
// matrix-vector multiplication
for (i = 0; i < KYBER_D; i++)
polyvec_pointwise_acc(&bp.vec[i], &sp, at + i);
polyvec_invntt(&bp);
polyvec_add(&bp, &bp, &ep);
polyvec_pointwise_acc(&v, &pkpv, &sp);
poly_invntt(&v);
poly_getnoise(&epp, coins, nonce++);
poly_add(&v, &v, &epp);
poly_add(&v, &v, &k);
pack_ciphertext(c, &bp, &v);
}
static void indcpa_dec(unsigned char *m,
const unsigned char *c,
const unsigned char *sk) {
polyvec bp, skpv;
poly v, mp;
size_t i;
unpack_ciphertext(&bp, &v, c);
unpack_sk(&skpv, sk);
for (i = 0; i < KYBER_D; i++)
bitrev_vector(bp.vec[i].coeffs);
polyvec_ntt(&bp);
polyvec_pointwise_acc(&mp, &skpv, &bp);
poly_invntt(&mp);
poly_sub(&mp, &mp, &v);
poly_tomsg(m, &mp);
}

View File

@@ -0,0 +1,159 @@
#if defined(WINDOWS)
#define UNUSED
// __attribute__ not supported in VS, is there something else I should define?
#else
#define UNUSED __attribute__((unused))
#endif
#include <stdlib.h>
#include <string.h>
#if !defined(WINDOWS)
#include <strings.h>
#include <unistd.h>
#endif
#include <oqs/kex.h>
#include <oqs/rand.h>
#include "kex_mlwe_kyber.h"
#include "kyber.c"
#include "params.h"
OQS_KEX *OQS_KEX_mlwe_kyber_new(OQS_RAND *rand) {
OQS_KEX *k = malloc(sizeof(OQS_KEX));
if (k == NULL) {
return NULL;
}
k->method_name = strdup("MLWE Kyber");
k->estimated_classical_security = 178; // using https://github.com/pq-crystals/kyber/blob/master/scripts/Kyber.py
k->estimated_quantum_security = 161; // using https://github.com/pq-crystals/kyber/blob/master/scripts/Kyber.py
k->seed = NULL;
k->seed_len = 0;
k->named_parameters = 0;
k->rand = rand;
k->params = NULL;
k->alice_0 = &OQS_KEX_mlwe_kyber_alice_0;
k->bob = &OQS_KEX_mlwe_kyber_bob;
k->alice_1 = &OQS_KEX_mlwe_kyber_alice_1;
k->alice_priv_free = &OQS_KEX_mlwe_kyber_alice_priv_free;
k->free = &OQS_KEX_mlwe_kyber_free;
return k;
}
int OQS_KEX_mlwe_kyber_alice_0(UNUSED OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
int ret;
/* allocate public/private key pair */
*alice_msg = malloc(KYBER_PUBLICKEYBYTES);
if (*alice_msg == NULL) {
goto err;
}
*alice_priv = malloc(KYBER_SECRETKEYBYTES);
if (*alice_priv == NULL) {
goto err;
}
/* generate public/private key pair */
keygen(*alice_msg, (unsigned char *) *alice_priv, k->rand);
*alice_msg_len = KYBER_PUBLICKEYBYTES;
ret = 1;
goto cleanup;
err:
ret = 0;
free(*alice_msg);
*alice_msg = NULL;
free(*alice_priv);
*alice_priv = NULL;
cleanup:
return ret;
}
int OQS_KEX_mlwe_kyber_bob(UNUSED OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
if (alice_msg_len != KYBER_PUBLICKEYBYTES) {
goto err;
}
/* allocate message and session key */
*bob_msg = malloc(KYBER_BYTES);
if (*bob_msg == NULL) {
goto err;
}
*key = malloc(32);
if (*key == NULL) {
goto err;
}
/* generate Bob's response */
sharedb(*key, *bob_msg, alice_msg, k->rand);
*bob_msg_len = KYBER_BYTES;
*key_len = 32;
ret = 1;
goto cleanup;
err:
ret = 0;
free(*bob_msg);
*bob_msg = NULL;
free(*key);
*key = NULL;
cleanup:
return ret;
}
int OQS_KEX_mlwe_kyber_alice_1(UNUSED OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
if (bob_msg_len != KYBER_BYTES) {
goto err;
}
/* allocate session key */
*key = malloc(32);
if (*key == NULL) {
goto err;
}
/* generate Alice's session key */
shareda(*key, (unsigned char *) alice_priv, bob_msg);
*key_len = 32;
ret = 1;
goto cleanup;
err:
ret = 0;
free(*key);
*key = NULL;
cleanup:
return ret;
}
void OQS_KEX_mlwe_kyber_alice_priv_free(UNUSED OQS_KEX *k, void *alice_priv) {
if (alice_priv) {
free(alice_priv);
}
}
void OQS_KEX_mlwe_kyber_free(OQS_KEX *k) {
if (k) {
free(k->named_parameters);
k->named_parameters = NULL;
free(k->method_name);
k->method_name = NULL;
}
free(k);
}

View File

@@ -0,0 +1,24 @@
/**
* \file kex_mlwe_kyber.h
* \brief Header for module-LWE key exchange protocol Kyber
*/
#ifndef __OQS_KEX_MLWE_KYBER_H
#define __OQS_KEX_MLWE_KYBER_H
#include <stddef.h>
#include <stdint.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
OQS_KEX *OQS_KEX_mlwe_kyber_new(OQS_RAND *rand);
int OQS_KEX_mlwe_kyber_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
int OQS_KEX_mlwe_kyber_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
int OQS_KEX_mlwe_kyber_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
void OQS_KEX_mlwe_kyber_alice_priv_free(OQS_KEX *k, void *alice_priv);
void OQS_KEX_mlwe_kyber_free(OQS_KEX *k);
#endif

View File

@@ -0,0 +1,86 @@
#include <stdint.h>
#include <oqs/sha3.h>
#include <oqs/rand.h>
// clang-format off
// (order of include matters)
#include "precomp.c"
#include "reduce.c"
#include "verify.c"
#include "ntt.c"
#include "poly.c"
#include "polyvec.c"
#include "indcpa.c"
// clang-format on
// API FUNCTIONS
/* Build a CCA-secure KEM from an IND-CPA-secure encryption scheme */
static void keygen(unsigned char *pk, unsigned char *sk, OQS_RAND *rand) {
size_t i;
indcpa_keypair(pk, sk, rand);
for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++)
sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i];
OQS_SHA3_shake128(sk + KYBER_SECRETKEYBYTES - 64, 32, pk, KYBER_PUBLICKEYBYTES);
rand->rand_n(rand, sk + KYBER_SECRETKEYBYTES - KYBER_SHAREDKEYBYTES, KYBER_SHAREDKEYBYTES); /* Value z for pseudo-random output on reject */
}
static void sharedb(unsigned char *sharedkey, unsigned char *send,
const unsigned char *received, OQS_RAND *rand) {
unsigned char krq[96]; /* Will contain key, coins, qrom-hash */
unsigned char buf[64];
int i;
rand->rand_n(rand, buf, 32);
OQS_SHA3_shake128(buf, 32, buf, 32); /* Don't release system RNG output */
OQS_SHA3_shake128(buf + 32, 32, received, KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + contributory KEM */
OQS_SHA3_shake128(krq, 96, buf, 64);
indcpa_enc(send, buf, received, krq + 32); /* coins are in krq+32 */
for (i = 0; i < 32; i++)
send[i + KYBER_INDCPA_BYTES] = krq[i + 64];
OQS_SHA3_shake128(krq + 32, 32, send, KYBER_BYTES); /* overwrite coins in krq with h(c) */
OQS_SHA3_shake128(sharedkey, 32, krq, 64); /* hash concatenation of pre-k and h(c) to k */
#ifndef STATISTICAL_TEST
OQS_SHA3_sha3256(sharedkey, sharedkey, 32);
#endif
}
static void shareda(unsigned char *sharedkey, const unsigned char *sk,
const unsigned char *received) {
int i, fail;
unsigned char cmp[KYBER_BYTES];
unsigned char buf[64];
unsigned char krq[96]; /* Will contain key, coins, qrom-hash */
const unsigned char *pk = sk + KYBER_INDCPA_SECRETKEYBYTES;
indcpa_dec(buf, received, sk);
// shake128(buf+32, 32, pk, KYBER_PUBLICKEYBYTES); /* Multitarget countermeasure for coins + contributory KEM */
for (i = 0; i < 32; i++) /* Save hash by storing h(pk) in sk */
buf[32 + i] = sk[KYBER_SECRETKEYBYTES - 64 + i];
OQS_SHA3_shake128(krq, 96, buf, 64);
indcpa_enc(cmp, buf, pk, krq + 32); /* coins are in krq+32 */
for (i = 0; i < 32; i++)
cmp[i + KYBER_INDCPA_BYTES] = krq[i + 64];
fail = verify(received, cmp, KYBER_BYTES);
OQS_SHA3_shake128(krq + 32, 32, received, KYBER_BYTES); /* overwrite coins in krq with h(c) */
cmov(krq, sk + KYBER_SECRETKEYBYTES - KYBER_SHAREDKEYBYTES, KYBER_SHAREDKEYBYTES, fail); /* Overwrite pre-k with z on re-encryption failure */
OQS_SHA3_shake128(sharedkey, 32, krq, 64); /* hash concatenation of pre-k and h(c) to k */
#ifndef STATISTICAL_TEST
OQS_SHA3_sha3256(sharedkey, sharedkey, 32);
#endif
}

67
vendor/liboqs/src/kex_mlwe_kyber/ntt.c vendored Normal file
View File

@@ -0,0 +1,67 @@
#include "params.h"
static uint16_t bitrev_table[KYBER_N] = {
0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255,
};
static void bitrev_vector(uint16_t *poly) {
unsigned int i, r;
uint16_t tmp;
for (i = 0; i < KYBER_N; i++) {
r = bitrev_table[i];
if (i < r) {
tmp = poly[i];
poly[i] = poly[r];
poly[r] = tmp;
}
}
}
static void mul_coefficients(uint16_t *poly, const uint16_t *factors) {
unsigned int i;
for (i = 0; i < KYBER_N; i++)
poly[i] = montgomery_reduce((poly[i] * factors[i]));
}
/* GS_bo_to_no; omegas need to be in Montgomery domain */
static void ntt(uint16_t *a, const uint16_t *omega) {
int start, j, jTwiddle, level;
uint16_t temp, W;
uint32_t t;
for (level = 0; level < 8; level++) {
for (start = 0; start < (1 << level); start++) {
jTwiddle = 0;
for (j = start; j < KYBER_N - 1; j += 2 * (1 << level)) {
W = omega[jTwiddle++];
temp = a[j];
if (level & 1) // odd level
a[j] = barrett_reduce((temp + a[j + (1 << level)]));
else
a[j] = (temp + a[j + (1 << level)]); // Omit reduction (be lazy)
t = (W * ((uint32_t) temp + 4 * KYBER_Q - a[j + (1 << level)]));
a[j + (1 << level)] = montgomery_reduce(t);
}
}
}
}

View File

@@ -0,0 +1,37 @@
#ifndef PARAMS_H
#define PARAMS_H
#define KYBER_N 256
#define KYBER_D 3
#define KYBER_K 4 /* used in sampler */
#define KYBER_Q 7681
#define KYBER_SEEDBYTES 32
#define KYBER_NOISESEEDBYTES 32
#define KYBER_COINBYTES 32
#define KYBER_SHAREDKEYBYTES 32
#define KYBER_POLYBYTES 416
#define KYBER_POLYCOMPRESSEDBYTES 96
#define KYBER_POLYVECBYTES (KYBER_D * KYBER_POLYBYTES)
#define KYBER_POLYVECCOMPRESSEDBYTES (KYBER_D * 352)
#define KYBER_INDCPA_MSGBYTES 32
#define KYBER_INDCPA_PUBLICKEYBYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_SEEDBYTES)
#define KYBER_INDCPA_SECRETKEYBYTES (KYBER_POLYVECBYTES)
#define KYBER_INDCPA_BYTES (KYBER_POLYVECCOMPRESSEDBYTES + KYBER_POLYCOMPRESSEDBYTES)
#define KYBER_PUBLICKEYBYTES (KYBER_INDCPA_PUBLICKEYBYTES)
#define KYBER_SECRETKEYBYTES (KYBER_INDCPA_SECRETKEYBYTES + KYBER_INDCPA_PUBLICKEYBYTES + 32 + KYBER_SHAREDKEYBYTES)
#define KYBER_BYTES (KYBER_INDCPA_BYTES + KYBER_INDCPA_MSGBYTES) /* Second part is for Targhi-Unruh */
extern uint16_t oqs_kex_mlwe_kyber_omegas_montgomery[];
extern uint16_t oqs_kex_mlwe_kyber_omegas_inv_bitrev_montgomery[];
extern uint16_t oqs_kex_mlwe_kyber_psis_inv_montgomery[];
extern uint16_t oqs_kex_mlwe_kyber_psis_bitrev_montgomery[];
#if defined(WINDOWS)
typedef unsigned __int16 uint16_t;
#endif
#endif

169
vendor/liboqs/src/kex_mlwe_kyber/poly.c vendored Normal file
View File

@@ -0,0 +1,169 @@
#include "params.h"
#include <oqs/sha3.h>
typedef struct {
uint16_t coeffs[KYBER_N];
#if defined(WINDOWS)
} poly;
#else
} poly __attribute__((aligned(32)));
#endif
/* include cbd.c */
static uint32_t load_littleendian(const unsigned char *x) {
return x[0] | (((uint32_t) x[1]) << 8) | (((uint32_t) x[2]) << 16) | (((uint32_t) x[3]) << 24);
}
static void cbd(poly *r, const unsigned char *buf) {
#if KYBER_K != 4
#error "poly_getnoise in poly.c only supports k=4"
#endif
uint32_t t, d, a[4], b[4];
int i, j;
for (i = 0; i < KYBER_N / 4; i++) {
t = load_littleendian(buf + 4 * i);
d = 0;
for (j = 0; j < 4; j++)
d += (t >> j) & 0x11111111;
a[0] = d & 0xf;
b[0] = (d >> 4) & 0xf;
a[1] = (d >> 8) & 0xf;
b[1] = (d >> 12) & 0xf;
a[2] = (d >> 16) & 0xf;
b[2] = (d >> 20) & 0xf;
a[3] = (d >> 24) & 0xf;
b[3] = (d >> 28);
r->coeffs[4 * i + 0] = a[0] + KYBER_Q - b[0];
r->coeffs[4 * i + 1] = a[1] + KYBER_Q - b[1];
r->coeffs[4 * i + 2] = a[2] + KYBER_Q - b[2];
r->coeffs[4 * i + 3] = a[3] + KYBER_Q - b[3];
}
}
/* end cbd.c */
static void poly_compress(unsigned char *r, const poly *a) {
uint32_t t[8];
unsigned int i, j, k = 0;
for (i = 0; i < KYBER_N; i += 8) {
for (j = 0; j < 8; j++)
t[j] = (((freeze(a->coeffs[i + j]) << 3) + KYBER_Q / 2) / KYBER_Q) & 7;
r[k] = t[0] | (t[1] << 3) | (t[2] << 6);
r[k + 1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
r[k + 2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
k += 3;
}
}
static void poly_decompress(poly *r, const unsigned char *a) {
unsigned int i;
for (i = 0; i < KYBER_N; i += 8) {
r->coeffs[i + 0] = (((a[0] & 7) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 1] = ((((a[0] >> 3) & 7) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 2] = ((((a[0] >> 6) | ((a[1] << 2) & 4)) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 3] = ((((a[1] >> 1) & 7) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 4] = ((((a[1] >> 4) & 7) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 5] = ((((a[1] >> 7) | ((a[2] << 1) & 6)) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 6] = ((((a[2] >> 2) & 7) * KYBER_Q) + 4) >> 3;
r->coeffs[i + 7] = ((((a[2] >> 5)) * KYBER_Q) + 4) >> 3;
a += 3;
}
}
static void poly_tobytes(unsigned char *r, const poly *a) {
int i, j;
uint16_t t[8];
for (i = 0; i < KYBER_N / 8; i++) {
for (j = 0; j < 8; j++)
t[j] = freeze(a->coeffs[8 * i + j]);
r[13 * i + 0] = t[0] & 0xff;
r[13 * i + 1] = (t[0] >> 8) | ((t[1] & 0x07) << 5);
r[13 * i + 2] = (t[1] >> 3) & 0xff;
r[13 * i + 3] = (t[1] >> 11) | ((t[2] & 0x3f) << 2);
r[13 * i + 4] = (t[2] >> 6) | ((t[3] & 0x01) << 7);
r[13 * i + 5] = (t[3] >> 1) & 0xff;
r[13 * i + 6] = (t[3] >> 9) | ((t[4] & 0x0f) << 4);
r[13 * i + 7] = (t[4] >> 4) & 0xff;
r[13 * i + 8] = (t[4] >> 12) | ((t[5] & 0x7f) << 1);
r[13 * i + 9] = (t[5] >> 7) | ((t[6] & 0x03) << 6);
r[13 * i + 10] = (t[6] >> 2) & 0xff;
r[13 * i + 11] = (t[6] >> 10) | ((t[7] & 0x1f) << 3);
r[13 * i + 12] = (t[7] >> 5);
}
}
static void poly_frombytes(poly *r, const unsigned char *a) {
int i;
for (i = 0; i < KYBER_N / 8; i++) {
r->coeffs[8 * i + 0] = a[13 * i + 0] | (((uint16_t) a[13 * i + 1] & 0x1f) << 8);
r->coeffs[8 * i + 1] = (a[13 * i + 1] >> 5) | (((uint16_t) a[13 * i + 2]) << 3) | (((uint16_t) a[13 * i + 3] & 0x03) << 11);
r->coeffs[8 * i + 2] = (a[13 * i + 3] >> 2) | (((uint16_t) a[13 * i + 4] & 0x7f) << 6);
r->coeffs[8 * i + 3] = (a[13 * i + 4] >> 7) | (((uint16_t) a[13 * i + 5]) << 1) | (((uint16_t) a[13 * i + 6] & 0x0f) << 9);
r->coeffs[8 * i + 4] = (a[13 * i + 6] >> 4) | (((uint16_t) a[13 * i + 7]) << 4) | (((uint16_t) a[13 * i + 8] & 0x01) << 12);
r->coeffs[8 * i + 5] = (a[13 * i + 8] >> 1) | (((uint16_t) a[13 * i + 9] & 0x3f) << 7);
r->coeffs[8 * i + 6] = (a[13 * i + 9] >> 6) | (((uint16_t) a[13 * i + 10]) << 2) | (((uint16_t) a[13 * i + 11] & 0x07) << 10);
r->coeffs[8 * i + 7] = (a[13 * i + 11] >> 3) | (((uint16_t) a[13 * i + 12]) << 5);
}
}
static void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce) {
unsigned char buf[KYBER_N];
OQS_SHA3_cshake128_simple(buf, KYBER_N, nonce, seed, KYBER_NOISESEEDBYTES);
cbd(r, buf);
}
static void poly_ntt(poly *r) {
mul_coefficients(r->coeffs, oqs_kex_mlwe_kyber_psis_bitrev_montgomery);
ntt(r->coeffs, oqs_kex_mlwe_kyber_omegas_montgomery);
}
static void poly_invntt(poly *r) {
bitrev_vector(r->coeffs);
ntt(r->coeffs, oqs_kex_mlwe_kyber_omegas_inv_bitrev_montgomery);
mul_coefficients(r->coeffs, oqs_kex_mlwe_kyber_psis_inv_montgomery);
}
static void poly_add(poly *r, const poly *a, const poly *b) {
int i;
for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = barrett_reduce(a->coeffs[i] + b->coeffs[i]);
}
static void poly_sub(poly *r, const poly *a, const poly *b) {
int i;
for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = barrett_reduce(a->coeffs[i] + 3 * KYBER_Q - b->coeffs[i]);
}
static void poly_frommsg(poly *r, const unsigned char msg[KYBER_SHAREDKEYBYTES]) {
uint16_t i, j, mask;
for (i = 0; i < KYBER_SHAREDKEYBYTES; i++) {
for (j = 0; j < 8; j++) {
mask = -((msg[i] >> j) & 1);
r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2);
}
}
}
static void poly_tomsg(unsigned char msg[KYBER_SHAREDKEYBYTES], const poly *a) {
uint16_t t;
int i, j;
for (i = 0; i < KYBER_SHAREDKEYBYTES; i++) {
msg[i] = 0;
for (j = 0; j < 8; j++) {
t = (((freeze(a->coeffs[8 * i + j]) << 1) + KYBER_Q / 2) / KYBER_Q) & 1;
msg[i] |= t << j;
}
}
}

View File

@@ -0,0 +1,196 @@
#include "params.h"
typedef struct {
poly vec[KYBER_D];
#if defined(WINDOWS)
} polyvec;
#else
} polyvec __attribute__((aligned(32)));
#endif
#if (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_D * 352))
static void polyvec_compress(unsigned char *r, const polyvec *a) {
int i, j, k;
uint16_t t[8];
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 8; j++) {
for (k = 0; k < 8; k++)
t[k] = ((((uint32_t) freeze(a->vec[i].coeffs[8 * j + k]) << 11) + KYBER_Q / 2) / KYBER_Q) & 0x7ff;
r[11 * j + 0] = t[0] & 0xff;
r[11 * j + 1] = (t[0] >> 8) | ((t[1] & 0x1f) << 3);
r[11 * j + 2] = (t[1] >> 5) | ((t[2] & 0x03) << 6);
r[11 * j + 3] = (t[2] >> 2) & 0xff;
r[11 * j + 4] = (t[2] >> 10) | ((t[3] & 0x7f) << 1);
r[11 * j + 5] = (t[3] >> 7) | ((t[4] & 0x0f) << 4);
r[11 * j + 6] = (t[4] >> 4) | ((t[5] & 0x01) << 7);
r[11 * j + 7] = (t[5] >> 1) & 0xff;
r[11 * j + 8] = (t[5] >> 9) | ((t[6] & 0x3f) << 2);
r[11 * j + 9] = (t[6] >> 6) | ((t[7] & 0x07) << 5);
r[11 * j + 10] = (t[7] >> 3);
}
r += 352;
}
}
static void polyvec_decompress(polyvec *r, const unsigned char *a) {
int i, j;
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 8; j++) {
r->vec[i].coeffs[8 * j + 0] = (((a[11 * j + 0] | (((uint32_t) a[11 * j + 1] & 0x07) << 8)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 1] = ((((a[11 * j + 1] >> 3) | (((uint32_t) a[11 * j + 2] & 0x3f) << 5)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 2] = ((((a[11 * j + 2] >> 6) | (((uint32_t) a[11 * j + 3] & 0xff) << 2) | (((uint32_t) a[11 * j + 4] & 0x01) << 10)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 3] = ((((a[11 * j + 4] >> 1) | (((uint32_t) a[11 * j + 5] & 0x0f) << 7)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 4] = ((((a[11 * j + 5] >> 4) | (((uint32_t) a[11 * j + 6] & 0x7f) << 4)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 5] = ((((a[11 * j + 6] >> 7) | (((uint32_t) a[11 * j + 7] & 0xff) << 1) | (((uint32_t) a[11 * j + 8] & 0x03) << 9)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 6] = ((((a[11 * j + 8] >> 2) | (((uint32_t) a[11 * j + 9] & 0x1f) << 6)) * KYBER_Q) + 1024) >> 11;
r->vec[i].coeffs[8 * j + 7] = ((((a[11 * j + 9] >> 5) | (((uint32_t) a[11 * j + 10] & 0xff) << 3)) * KYBER_Q) + 1024) >> 11;
}
a += 352;
}
}
#elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_D * 320))
static void polyvec_compress(unsigned char *r, const polyvec *a) {
int i, j, k;
uint16_t t[4];
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 4; j++) {
for (k = 0; k < 4; k++)
t[k] = ((((uint32_t) freeze(a->vec[i].coeffs[4 * j + k]) << 10) + KYBER_Q / 2) / KYBER_Q) & 0x3ff;
r[5 * j + 0] = t[0] & 0xff;
r[5 * j + 1] = (t[0] >> 8) | ((t[1] & 0x3f) << 2);
r[5 * j + 2] = (t[1] >> 6) | ((t[2] & 0x0f) << 4);
r[5 * j + 3] = (t[2] >> 4) | ((t[3] & 0x03) << 6);
r[5 * j + 4] = (t[3] >> 2);
}
r += 320;
}
}
static void polyvec_decompress(polyvec *r, const unsigned char *a) {
int i, j;
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 4; j++) {
r->vec[i].coeffs[4 * j + 0] = (((a[5 * j + 0] | (((uint32_t) a[5 * j + 1] & 0x03) << 8)) * KYBER_Q) + 512) >> 10;
r->vec[i].coeffs[4 * j + 1] = ((((a[5 * j + 1] >> 2) | (((uint32_t) a[5 * j + 2] & 0x0f) << 6)) * KYBER_Q) + 512) >> 10;
r->vec[i].coeffs[4 * j + 2] = ((((a[5 * j + 2] >> 4) | (((uint32_t) a[5 * j + 3] & 0x3f) << 4)) * KYBER_Q) + 512) >> 10;
r->vec[i].coeffs[4 * j + 3] = ((((a[5 * j + 3] >> 6) | (((uint32_t) a[5 * j + 4] & 0xff) << 2)) * KYBER_Q) + 512) >> 10;
}
a += 320;
}
}
#elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_D * 288))
static void polyvec_compress(unsigned char *r, const polyvec *a) {
int i, j, k;
uint16_t t[8];
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 8; j++) {
for (k = 0; k < 8; k++)
t[k] = ((((uint32_t) freeze(a->vec[i].coeffs[8 * j + k]) << 9) + KYBER_Q / 2) / KYBER_Q) & 0x1ff;
r[9 * j + 0] = t[0] & 0xff;
r[9 * j + 1] = (t[0] >> 8) | ((t[1] & 0x7f) << 1);
r[9 * j + 2] = (t[1] >> 7) | ((t[2] & 0x3f) << 2);
r[9 * j + 3] = (t[2] >> 6) | ((t[3] & 0x1f) << 3);
r[9 * j + 4] = (t[3] >> 5) | ((t[4] & 0x0f) << 4);
r[9 * j + 5] = (t[4] >> 4) | ((t[5] & 0x07) << 5);
r[9 * j + 6] = (t[5] >> 3) | ((t[6] & 0x03) << 6);
r[9 * j + 7] = (t[6] >> 2) | ((t[7] & 0x01) << 7);
r[9 * j + 8] = (t[7] >> 1);
}
r += 288;
}
}
static void polyvec_decompress(polyvec *r, const unsigned char *a) {
int i, j;
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N / 8; j++) {
r->vec[i].coeffs[8 * j + 0] = (((a[9 * j + 0] | (((uint32_t) a[9 * j + 1] & 0x01) << 8)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 1] = ((((a[9 * j + 1] >> 1) | (((uint32_t) a[9 * j + 2] & 0x03) << 7)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 2] = ((((a[9 * j + 2] >> 2) | (((uint32_t) a[9 * j + 3] & 0x07) << 6)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 3] = ((((a[9 * j + 3] >> 3) | (((uint32_t) a[9 * j + 4] & 0x0f) << 5)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 4] = ((((a[9 * j + 4] >> 4) | (((uint32_t) a[9 * j + 5] & 0x1f) << 4)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 5] = ((((a[9 * j + 5] >> 5) | (((uint32_t) a[9 * j + 6] & 0x3f) << 3)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 6] = ((((a[9 * j + 6] >> 6) | (((uint32_t) a[9 * j + 7] & 0x7f) << 2)) * KYBER_Q) + 256) >> 9;
r->vec[i].coeffs[8 * j + 7] = ((((a[9 * j + 7] >> 7) | (((uint32_t) a[9 * j + 8] & 0xff) << 1)) * KYBER_Q) + 256) >> 9;
}
a += 288;
}
}
#elif (KYBER_POLYVECCOMPRESSEDBYTES == (KYBER_D * 256))
static void polyvec_compress(unsigned char *r, const polyvec *a) {
int i, j, k;
uint16_t t;
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N; j++) {
r[j] = ((((uint32_t) freeze(a->vec[i].coeffs[j]) << 8) + KYBER_Q / 2) / KYBER_Q) & 0xff;
}
r += 256;
}
}
static void polyvec_decompress(polyvec *r, const unsigned char *a) {
int i, j;
for (i = 0; i < KYBER_D; i++) {
for (j = 0; j < KYBER_N; j++) {
r->vec[i].coeffs[j] = ((a[j] * KYBER_Q) + 128) >> 8;
}
a += 256;
}
}
#else
#error "Unsupported compression of polyvec"
#endif
static void polyvec_tobytes(unsigned char *r, const polyvec *a) {
int i;
for (i = 0; i < KYBER_D; i++)
poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
}
static void polyvec_frombytes(polyvec *r, const unsigned char *a) {
int i;
for (i = 0; i < KYBER_D; i++)
poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
}
static void polyvec_ntt(polyvec *r) {
int i;
for (i = 0; i < KYBER_D; i++)
poly_ntt(&r->vec[i]);
}
static void polyvec_invntt(polyvec *r) {
int i;
for (i = 0; i < KYBER_D; i++)
poly_invntt(&r->vec[i]);
}
static void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) {
int i, j;
uint16_t t;
for (j = 0; j < KYBER_N; j++) {
t = montgomery_reduce(4613 * (uint32_t) b->vec[0].coeffs[j]); // 4613 = 2^{2*18} % q
r->coeffs[j] = montgomery_reduce(a->vec[0].coeffs[j] * t);
for (i = 1; i < KYBER_D; i++) {
t = montgomery_reduce(4613 * (uint32_t) b->vec[i].coeffs[j]);
r->coeffs[j] += montgomery_reduce(a->vec[i].coeffs[j] * t);
}
r->coeffs[j] = barrett_reduce(r->coeffs[j]);
}
}
static void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) {
int i;
for (i = 0; i < KYBER_D; i++)
poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
}

View File

@@ -0,0 +1,9 @@
#include "params.h"
uint16_t oqs_kex_mlwe_kyber_omegas_montgomery[KYBER_N / 2] = {990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382, 6086, 3823, 877, 5656, 3583, 7010, 6414, 263, 1285, 291, 7143, 7338, 1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, 606, 729, 5383, 962, 3240, 7548, 5129, 7653, 5929, 4965, 2461, 641, 1584, 2666, 1142, 157, 7407, 5222, 5602, 5142, 6140, 5485, 4931, 1559, 2085, 5284, 2056, 3538, 7269, 3535, 7190, 1957, 3465, 6792, 1538, 4664, 2023, 7643, 3660, 7673, 1694, 6905, 3995, 3475, 5939, 1859, 6910, 4434, 1019, 1492, 7087, 4761, 657, 4859, 5798, 2640, 1693, 2607, 2782, 5400, 6466, 1010, 957, 3851, 2121, 6392, 7319, 3367, 3659, 3375, 6430, 7583, 1549, 5856, 4773, 6084, 5544, 1650, 3997, 4390, 6722, 2915, 4245, 2635, 6128, 7676, 5737, 1616, 3457, 3132, 7196, 4702, 6239, 851, 2122, 3009};
uint16_t oqs_kex_mlwe_kyber_omegas_inv_bitrev_montgomery[KYBER_N / 2] = {990, 254, 862, 5047, 6586, 5538, 4400, 7103, 2025, 6804, 3858, 1595, 2299, 4345, 1319, 7197, 7678, 5213, 1906, 3639, 1749, 2497, 2547, 6100, 343, 538, 7390, 6396, 7418, 1267, 671, 4098, 5724, 491, 4146, 412, 4143, 5625, 2397, 5596, 6122, 2750, 2196, 1541, 2539, 2079, 2459, 274, 7524, 6539, 5015, 6097, 7040, 5220, 2716, 1752, 28, 2552, 133, 4441, 6719, 2298, 6952, 7075, 4672, 5559, 6830, 1442, 2979, 485, 4549, 4224, 6065, 1944, 5, 1553, 5046, 3436, 4766, 959, 3291, 3684, 6031, 2137, 1597, 2908, 1825, 6132, 98, 1251, 4306, 4022, 4314, 362, 1289, 5560, 3830, 6724, 6671, 1215, 2281, 4899, 5074, 5988, 5041, 1883, 2822, 7024, 2920, 594, 6189, 6662, 3247, 771, 5822, 1742, 4206, 3686, 776, 5987, 8, 4021, 38, 5658, 3017, 6143, 889, 4216};
uint16_t oqs_kex_mlwe_kyber_psis_bitrev_montgomery[KYBER_N] = {990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382, 6086, 3823, 877, 5656, 3583, 7010, 6414, 263, 1285, 291, 7143, 7338, 1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, 606, 729, 5383, 962, 3240, 7548, 5129, 7653, 5929, 4965, 2461, 641, 1584, 2666, 1142, 157, 7407, 5222, 5602, 5142, 6140, 5485, 4931, 1559, 2085, 5284, 2056, 3538, 7269, 3535, 7190, 1957, 3465, 6792, 1538, 4664, 2023, 7643, 3660, 7673, 1694, 6905, 3995, 3475, 5939, 1859, 6910, 4434, 1019, 1492, 7087, 4761, 657, 4859, 5798, 2640, 1693, 2607, 2782, 5400, 6466, 1010, 957, 3851, 2121, 6392, 7319, 3367, 3659, 3375, 6430, 7583, 1549, 5856, 4773, 6084, 5544, 1650, 3997, 4390, 6722, 2915, 4245, 2635, 6128, 7676, 5737, 1616, 3457, 3132, 7196, 4702, 6239, 851, 2122, 3009, 7613, 7295, 2007, 323, 5112, 3716, 2289, 6442, 6965, 2713, 7126, 3401, 963, 6596, 607, 5027, 7078, 4484, 5937, 944, 2860, 2680, 5049, 1777, 5850, 3387, 6487, 6777, 4812, 4724, 7077, 186, 6848, 6793, 3463, 5877, 1174, 7116, 3077, 5945, 6591, 590, 6643, 1337, 6036, 3991, 1675, 2053, 6055, 1162, 1679, 3883, 4311, 2106, 6163, 4486, 6374, 5006, 4576, 4288, 5180, 4102, 282, 6119, 7443, 6330, 3184, 4971, 2530, 5325, 4171, 7185, 5175, 5655, 1898, 382, 7211, 43, 5965, 6073, 1730, 332, 1577, 3304, 2329, 1699, 6150, 2379, 5113, 333, 3502, 4517, 1480, 1172, 5567, 651, 925, 4573, 599, 1367, 4109, 1863, 6929, 1605, 3866, 2065, 4048, 839, 5764, 2447, 2022, 3345, 1990, 4067, 2036, 2069, 3567, 7371, 2368, 339, 6947, 2159, 654, 7327, 2768, 6676, 987, 2214};
uint16_t oqs_kex_mlwe_kyber_psis_inv_montgomery[KYBER_N] = {1024, 4972, 5779, 6907, 4943, 4168, 315, 5580, 90, 497, 1123, 142, 4710, 5527, 2443, 4871, 698, 2489, 2394, 4003, 684, 2241, 2390, 7224, 5072, 2064, 4741, 1687, 6841, 482, 7441, 1235, 2126, 4742, 2802, 5744, 6287, 4933, 699, 3604, 1297, 2127, 5857, 1705, 3868, 3779, 4397, 2177, 159, 622, 2240, 1275, 640, 6948, 4572, 5277, 209, 2605, 1157, 7328, 5817, 3191, 1662, 2009, 4864, 574, 2487, 164, 6197, 4436, 7257, 3462, 4268, 4281, 3414, 4515, 3170, 1290, 2003, 5855, 7156, 6062, 7531, 1732, 3249, 4884, 7512, 3590, 1049, 2123, 1397, 6093, 3691, 6130, 6541, 3946, 6258, 3322, 1788, 4241, 4900, 2309, 1400, 1757, 400, 502, 6698, 2338, 3011, 668, 7444, 4580, 6516, 6795, 2959, 4136, 3040, 2279, 6355, 3943, 2913, 6613, 7416, 4084, 6508, 5556, 4054, 3782, 61, 6567, 2212, 779, 632, 5709, 5667, 4923, 4911, 6893, 4695, 4164, 3536, 2287, 7594, 2848, 3267, 1911, 3128, 546, 1991, 156, 4958, 5531, 6903, 483, 875, 138, 250, 2234, 2266, 7222, 2842, 4258, 812, 6703, 232, 5207, 6650, 2585, 1900, 6225, 4932, 7265, 4701, 3173, 4635, 6393, 227, 7313, 4454, 4284, 6759, 1224, 5223, 1447, 395, 2608, 4502, 4037, 189, 3348, 54, 6443, 2210, 6230, 2826, 1780, 3002, 5995, 1955, 6102, 6045, 3938, 5019, 4417, 1434, 1262, 1507, 5847, 5917, 7157, 7177, 6434, 7537, 741, 4348, 1309, 145, 374, 2236, 4496, 5028, 6771, 6923, 7421, 1978, 1023, 3857, 6876, 1102, 7451, 4704, 6518, 1344, 765, 384, 5705, 1207, 1630, 4734, 1563, 6839, 5933, 1954, 4987, 7142, 5814, 7527, 4953, 7637, 4707, 2182, 5734, 2818, 541, 4097, 5641};

View File

@@ -0,0 +1,36 @@
#include "params.h"
static const uint32_t qinv = 7679; // -inverse_mod(q,2^18)
static const uint32_t rlog = 18;
static uint16_t montgomery_reduce(uint32_t a) {
uint32_t u;
u = (a * qinv);
u &= ((1 << rlog) - 1);
u *= KYBER_Q;
a = a + u;
return a >> rlog;
}
static uint16_t barrett_reduce(uint16_t a) {
uint32_t u;
u = a >> 13;
u *= KYBER_Q;
a -= u;
return a;
}
static uint16_t freeze(uint16_t x) {
uint16_t m, r;
int16_t c;
r = barrett_reduce(x);
m = r - KYBER_Q;
c = m;
c >>= 15;
r = m ^ ((r ^ m) & c);
return r;
}

View File

@@ -0,0 +1,24 @@
#include <string.h>
#include <stdint.h>
/* returns 0 for equal strings, 1 for non-equal strings */
static int verify(const unsigned char *a, const unsigned char *b, size_t len) {
uint64_t r;
size_t i;
r = 0;
for (i = 0; i < len; i++)
r |= a[i] ^ b[i];
r = (-r) >> 63;
return r;
}
/* b = 1 means mov, b = 0 means don't mov*/
static void cmov(unsigned char *r, const unsigned char *x, size_t len, unsigned char b) {
size_t i;
b = -b;
for (i = 0; i < len; i++)
r[i] ^= b & (x[i] ^ r[i]);
}

25
vendor/liboqs/src/kex_ntru/Makefile.am vendored Normal file
View File

@@ -0,0 +1,25 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libntru.la
libntru_la_SOURCES = kex_ntru.c \
ntru_crypto_drbg.c \
ntru_crypto_hash.c \
ntru_crypto_hmac.c \
ntru_crypto_msbyte_uint32.c \
ntru_crypto_ntru_convert.c \
ntru_crypto_ntru_encrypt.c \
ntru_crypto_ntru_encrypt_key.c \
ntru_crypto_ntru_encrypt_param_sets.c \
ntru_crypto_ntru_mgf1.c \
ntru_crypto_ntru_poly.c \
ntru_crypto_sha256.c \
ntru_crypto_sha1.c \
ntru_crypto_sha2.c \
ntru_crypto_ntru_mult_indices.c \
ntru_crypto_ntru_mult_coeffs_karat.c
libntru_la_CPPFLAGS = -I../../include
libntru_la_CPPFLAGS += $(AM_CPPFLAGS)

229
vendor/liboqs/src/kex_ntru/kex_ntru.c vendored Normal file
View File

@@ -0,0 +1,229 @@
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
#if defined(WINDOWS)
#define UNUSED
// __attribute__ not supported in VS
#else
#define UNUSED __attribute__((unused))
#endif
#include <fcntl.h>
#if defined(WINDOWS)
#include <windows.h>
#include <Wincrypt.h>
#else
#include <unistd.h>
#endif
#include <oqs/kex.h>
#include <oqs/kex_ntru.h>
#include <oqs/rand.h>
#include <ntru_crypto.h>
#define NTRU_PARAMETER_SELECTION NTRU_EES743EP1
#define NTRU_PARAMETER_SELECTION_NAME "EES743EP1"
OQS_KEX *OQS_KEX_ntru_new(OQS_RAND *rand) {
OQS_KEX *k = malloc(sizeof(OQS_KEX));
if (k == NULL)
return NULL;
k->method_name = strdup("ntru " NTRU_PARAMETER_SELECTION_NAME);
k->estimated_classical_security = 256; // http://eprint.iacr.org/2015/708.pdf Table 3 N=743 product form search cost
k->estimated_quantum_security = 128; // need justification
k->rand = rand;
k->params = NULL;
k->alice_0 = &OQS_KEX_ntru_alice_0;
k->bob = &OQS_KEX_ntru_bob;
k->alice_1 = &OQS_KEX_ntru_alice_1;
k->alice_priv_free = &OQS_KEX_ntru_alice_priv_free;
k->free = &OQS_KEX_ntru_free;
return k;
}
static uint8_t get_entropy_from_dev_urandom(ENTROPY_CMD cmd, uint8_t *out) {
if (cmd == INIT) {
return 1;
}
if (out == NULL) {
return 0;
}
if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
*out = 1;
return 1;
}
if (cmd == GET_BYTE_OF_ENTROPY) {
// TODO: why is this called to get entropy bytes one by one?
if (!OQS_RAND_get_system_entropy(out, 1)) {
return 0;
}
return 1;
}
return 0;
}
typedef struct OQS_KEX_ntru_alice_priv {
uint16_t priv_key_len;
uint8_t *priv_key;
} OQS_KEX_ntru_alice_priv;
int OQS_KEX_ntru_alice_0(UNUSED OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
int ret = 0;
uint32_t rc;
DRBG_HANDLE drbg;
OQS_KEX_ntru_alice_priv *ntru_alice_priv = NULL;
/* initialize NTRU DRBG */
rc = ntru_crypto_drbg_instantiate(256, (uint8_t *) "OQS Alice", strlen("OQS Alice"), (ENTROPY_FN) &get_entropy_from_dev_urandom, &drbg);
if (rc != DRBG_OK)
goto err;
/* allocate private key */
ntru_alice_priv = malloc(sizeof(OQS_KEX_ntru_alice_priv));
if (ntru_alice_priv == NULL)
goto err;
*alice_priv = ntru_alice_priv;
/* calculate length of public/private keys */
uint16_t ntru_alice_msg_len;
rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_PARAMETER_SELECTION, &ntru_alice_msg_len, NULL, &(ntru_alice_priv->priv_key_len), NULL);
if (rc != NTRU_OK)
goto err;
*alice_msg_len = (size_t) ntru_alice_msg_len;
/* allocate private key bytes */
ntru_alice_priv->priv_key = malloc(ntru_alice_priv->priv_key_len);
if (ntru_alice_priv->priv_key == NULL)
goto err;
/* allocate public key */
*alice_msg = malloc(*alice_msg_len);
if (*alice_msg == NULL)
goto err;
/* generate public/private key pair */
rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_PARAMETER_SELECTION, &ntru_alice_msg_len, *alice_msg, &(ntru_alice_priv->priv_key_len), ntru_alice_priv->priv_key);
if (rc != NTRU_OK)
goto err;
*alice_msg_len = (size_t) ntru_alice_msg_len;
ret = 1;
goto cleanup;
err:
ret = 0;
if (ntru_alice_priv != NULL)
free(ntru_alice_priv->priv_key);
free(ntru_alice_priv);
free(*alice_msg);
cleanup:
ntru_crypto_drbg_uninstantiate(drbg);
return ret;
}
int OQS_KEX_ntru_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
uint32_t rc;
DRBG_HANDLE drbg;
*bob_msg = NULL;
*key = NULL;
/* initialize NTRU DRBG */
rc = ntru_crypto_drbg_instantiate(256, (uint8_t *) "OQS Bob", strlen("OQS Bob"), (ENTROPY_FN) &get_entropy_from_dev_urandom, &drbg);
if (rc != DRBG_OK)
goto err;
/* generate random session key */
*key_len = 256 / 8;
*key = malloc(*key_len);
if (*key == NULL)
goto err;
OQS_RAND_n(k->rand, *key, *key_len);
/* calculate length of ciphertext */
uint16_t ntru_bob_msg_len;
rc = ntru_crypto_ntru_encrypt(drbg, alice_msg_len, alice_msg, *key_len, *key, &ntru_bob_msg_len, NULL);
if (rc != NTRU_OK)
goto err;
*bob_msg_len = (size_t) ntru_bob_msg_len;
/* allocate ciphertext */
*bob_msg = malloc(*bob_msg_len);
if (*bob_msg == NULL)
goto err;
/* encrypt session key */
rc = ntru_crypto_ntru_encrypt(drbg, alice_msg_len, alice_msg, *key_len, *key, &ntru_bob_msg_len, *bob_msg);
if (rc != NTRU_OK)
goto err;
*bob_msg_len = (size_t) ntru_bob_msg_len;
ret = 1;
goto cleanup;
err:
ret = 0;
free(key);
free(bob_msg);
cleanup:
ntru_crypto_drbg_uninstantiate(drbg);
return ret;
}
int OQS_KEX_ntru_alice_1(UNUSED OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len) {
int ret;
uint32_t rc;
*key = NULL;
OQS_KEX_ntru_alice_priv *ntru_alice_priv = (OQS_KEX_ntru_alice_priv *) alice_priv;
/* calculate session key length */
uint16_t ntru_key_len;
rc = ntru_crypto_ntru_decrypt(ntru_alice_priv->priv_key_len, ntru_alice_priv->priv_key, bob_msg_len, bob_msg, &ntru_key_len, NULL);
if (rc != NTRU_OK)
goto err;
*key_len = (size_t) ntru_key_len;
/* allocate session key */
*key = malloc(*key_len);
if (*key == NULL)
goto err;
/* decrypt session key */
rc = ntru_crypto_ntru_decrypt(ntru_alice_priv->priv_key_len, ntru_alice_priv->priv_key, bob_msg_len, bob_msg, &ntru_key_len, *key);
if (rc != NTRU_OK)
goto err;
*key_len = (size_t) ntru_key_len;
ret = 1;
goto cleanup;
err:
ret = 0;
free(key);
cleanup:
return ret;
}
void OQS_KEX_ntru_alice_priv_free(UNUSED OQS_KEX *k, void *alice_priv) {
if (alice_priv) {
OQS_KEX_ntru_alice_priv *ntru_alice_priv = (OQS_KEX_ntru_alice_priv *) alice_priv;
free(ntru_alice_priv->priv_key);
}
free(alice_priv);
}
void OQS_KEX_ntru_free(OQS_KEX *k) {
if (k)
free(k->method_name);
free(k);
}
#endif

28
vendor/liboqs/src/kex_ntru/kex_ntru.h vendored Executable file
View File

@@ -0,0 +1,28 @@
/**
* \file kex_ntru.h
* \brief Header for the NTRU implementation of OQS_KEX
*/
#ifndef __OQS_KEX_NTRU_H
#define __OQS_KEX_NTRU_H
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
#include <stddef.h>
#include <stdint.h>
#include <oqs/kex.h>
#include <oqs/rand.h>
OQS_KEX *OQS_KEX_ntru_new(OQS_RAND *rand);
int OQS_KEX_ntru_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
int OQS_KEX_ntru_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
int OQS_KEX_ntru_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
void OQS_KEX_ntru_alice_priv_free(OQS_KEX *k, void *alice_priv);
void OQS_KEX_ntru_free(OQS_KEX *k);
#endif
#endif

340
vendor/liboqs/src/kex_ntru/ntru_crypto.h vendored Normal file
View File

@@ -0,0 +1,340 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto.h
*
* Contents: Public header file for NTRUEncrypt.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_H
#define NTRU_CRYPTO_H
#include "ntru_crypto_platform.h"
#include "ntru_crypto_drbg.h"
#include "ntru_crypto_error.h"
#if !defined(NTRUCALL)
#if !defined(WIN32) || defined(NTRUCRYPTO_STATIC)
// Linux, or a Win32 static library
#define NTRUCALL extern uint32_t
#elif defined(NTRUCRYPTO_EXPORTS)
// Win32 DLL build
#define NTRUCALL extern __declspec(dllexport) uint32_t
#else
// Win32 DLL import
#define NTRUCALL extern __declspec(dllimport) uint32_t
#endif
#endif /* NTRUCALL */
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/* parameter set ID list */
typedef enum _NTRU_ENCRYPT_PARAM_SET_ID {
NTRU_EES401EP1,
NTRU_EES449EP1,
NTRU_EES677EP1,
NTRU_EES1087EP2,
NTRU_EES541EP1,
NTRU_EES613EP1,
NTRU_EES887EP1,
NTRU_EES1171EP1,
NTRU_EES659EP1,
NTRU_EES761EP1,
NTRU_EES1087EP1,
NTRU_EES1499EP1,
NTRU_EES401EP2,
NTRU_EES439EP1,
NTRU_EES593EP1,
NTRU_EES743EP1,
NTRU_EES443EP1,
NTRU_EES587EP1,
} NTRU_ENCRYPT_PARAM_SET_ID;
/* error codes */
#define NTRU_OK 0
#define NTRU_FAIL 1
#define NTRU_BAD_PARAMETER 2
#define NTRU_BAD_LENGTH 3
#define NTRU_BUFFER_TOO_SMALL 4
#define NTRU_INVALID_PARAMETER_SET 5
#define NTRU_BAD_PUBLIC_KEY 6
#define NTRU_BAD_PRIVATE_KEY 7
#define NTRU_OUT_OF_MEMORY 8
#define NTRU_BAD_ENCODING 9
#define NTRU_OID_NOT_RECOGNIZED 10
#define NTRU_UNSUPPORTED_PARAM_SET 11
#define NTRU_RESULT(r) ((uint32_t)((r) ? NTRU_ERROR_BASE + (r) : (r)))
#define NTRU_RET(r) return NTRU_RESULT((r))
/* function declarations */
/* ntru_crypto_ntru_encrypt
*
* Implements NTRU encryption (SVES) for the parameter set specified in
* the public key blob.
*
* Before invoking this function, a DRBG must be instantiated using
* ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
* instantiation the requested security strength must be at least as large
* as the security strength of the NTRU parameter set being used.
* Failure to instantiate the DRBG with the proper security strength will
* result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
*
* The required minimum size of the output ciphertext buffer (ct) may be
* queried by invoking this function with ct = NULL. In this case, no
* encryption is performed, NTRU_OK is returned, and the required minimum
* size for ct is returned in ct_len.
*
* When ct != NULL, at invocation *ct_len must be the size of the ct buffer.
* Upon return it is the actual size of the ciphertext.
*
* Returns NTRU_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if the DRBG handle is invalid.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PARAMETER if an argument pointer
* (other than ct) is NULL.
* Returns NTRU_ERROR_BASE + NTRU_BAD_LENGTH if a length argument
* (pubkey_blob_len or pt_len) is zero, or if pt_len exceeds the
* maximum plaintext length for the parameter set.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PUBLIC_KEY if the public-key blob is
* invalid (unknown format, corrupt, bad length).
* Returns NTRU_ERROR_BASE + NTRU_BUFFER_TOO_SMALL if the ciphertext buffer
* is too small.
* Returns NTRU_ERROR_BASE + NTRU_NO_MEMORY if memory needed cannot be
* allocated from the heap.
*/
NTRUCALL
ntru_crypto_ntru_encrypt(
DRBG_HANDLE drbg_handle, /* in - handle for DRBG */
uint16_t pubkey_blob_len, /* in - no. of octets in public key
blob */
uint8_t const *pubkey_blob, /* in - pointer to public key */
uint16_t pt_len, /* in - no. of octets in plaintext */
uint8_t const *pt, /* in - pointer to plaintext */
uint16_t *ct_len, /* in/out - no. of octets in ct, addr for
no. of octets in ciphertext */
uint8_t *ct); /* out - address for ciphertext */
/* ntru_crypto_ntru_decrypt
*
* Implements NTRU decryption (SVES) for the parameter set specified in
* the private key blob.
*
* The maximum size of the output plaintext may be queried by invoking
* this function with pt = NULL. In this case, no decryption is performed,
* NTRU_OK is returned, and the maximum size the plaintext could be is
* returned in pt_len.
* Note that until the decryption is performed successfully, the actual size
* of the resulting plaintext cannot be known.
*
* When pt != NULL, at invocation *pt_len must be the size of the pt buffer.
* Upon return it is the actual size of the plaintext.
*
* Returns NTRU_OK if successful.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PARAMETER if an argument pointer
* (other than pt) is NULL.
* Returns NTRU_ERROR_BASE + NTRU_BAD_LENGTH if a length argument
* (privkey_blob) is zero, or if ct_len is invalid for the parameter set.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PRIVATE_KEY if the private-key blob is
* invalid (unknown format, corrupt, bad length).
* Returns NTRU_ERROR_BASE + NTRU_BUFFER_TOO_SMALL if the plaintext buffer
* is too small.
* Returns NTRU_ERROR_BASE + NTRU_NO_MEMORY if memory needed cannot be
* allocated from the heap.
* Returns NTRU_ERROR_BASE + NTRU_FAIL if a decryption error occurs.
*/
NTRUCALL
ntru_crypto_ntru_decrypt(
uint16_t privkey_blob_len, /* in - no. of octets in private key
blob */
uint8_t const *privkey_blob, /* in - pointer to private key */
uint16_t ct_len, /* in - no. of octets in ciphertext */
uint8_t const *ct, /* in - pointer to ciphertext */
uint16_t *pt_len, /* in/out - no. of octets in pt, addr for
no. of octets in plaintext */
uint8_t *pt); /* out - address for plaintext */
/* ntru_crypto_ntru_encrypt_keygen
*
* Implements key generation for NTRUEncrypt for the parameter set specified.
*
* Before invoking this function, a DRBG must be instantiated using
* ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
* instantiation the requested security strength must be at least as large
* as the security strength of the NTRU parameter set being used.
* Failure to instantiate the DRBG with the proper security strength will
* result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
*
* The required minimum size of the output public-key buffer (pubkey_blob)
* may be queried by invoking this function with pubkey_blob = NULL.
* In this case, no key generation is performed, NTRU_OK is returned, and
* the required minimum size for pubkey_blob is returned in pubkey_blob_len.
*
* The required minimum size of the output private-key buffer (privkey_blob)
* may be queried by invoking this function with privkey_blob = NULL.
* In this case, no key generation is performed, NTRU_OK is returned, and
* the required minimum size for privkey_blob is returned in privkey_blob_len.
*
* The required minimum sizes of both pubkey_blob and privkey_blob may be
* queried as described above, in a single invocation of this function.
*
* When pubkey_blob != NULL and privkey_blob != NULL, at invocation
* *pubkey_blob_len must be the size of the pubkey_blob buffer and
* *privkey_blob_len must be the size of the privkey_blob buffer.
* Upon return, *pubkey_blob_len is the actual size of the public-key blob
* and *privkey_blob_len is the actual size of the private-key blob.
*
* Returns NTRU_OK if successful.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PARAMETER if an argument pointer
* (other than pubkey_blob or privkey_blob) is NULL.
* Returns NTRU_ERROR_BASE + NTRU_INVALID_PARAMETER_SET if the parameter-set
* ID is invalid.
* Returns NTRU_ERROR_BASE + NTRU_BAD_LENGTH if a length argument is invalid.
* Returns NTRU_ERROR_BASE + NTRU_BUFFER_TOO_SMALL if either the pubkey_blob
* buffer or the privkey_blob buffer is too small.
* Returns NTRU_ERROR_BASE + NTRU_NO_MEMORY if memory needed cannot be
* allocated from the heap.
* Returns NTRU_ERROR_BASE + NTRU_FAIL if the polynomial generated for f is
* not invertible in (Z/qZ)[X]/(X^N - 1), which is extremely unlikely.
* Should this occur, this function should simply be invoked again.
*/
NTRUCALL
ntru_crypto_ntru_encrypt_keygen(
DRBG_HANDLE drbg_handle, /* in - handle of DRBG */
NTRU_ENCRYPT_PARAM_SET_ID param_set_id, /* in - parameter set ID */
uint16_t *pubkey_blob_len, /* in/out - no. of octets in
pubkey_blob, addr
for no. of octets
in pubkey_blob */
uint8_t *pubkey_blob, /* out - address for
public key blob */
uint16_t *privkey_blob_len, /* in/out - no. of octets in
privkey_blob, addr
for no. of octets
in privkey_blob */
uint8_t *privkey_blob); /* out - address for
private key blob */
/* ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo
*
* DER-encodes an NTRUEncrypt public-key from a public-key blob into a
* SubjectPublicKeyInfo field for inclusion in an X.509 certificate.
*
* The required minimum size of the output SubjectPublicKeyInfo buffer
* (encoded_subjectPublicKeyInfo) may be queried by invoking this function
* with encoded_subjectPublicKeyInfo = NULL. In this case, no encoding is
* performed, NTRU_OK is returned, and the required minimum size for
* encoded_subjectPublicKeyInfo is returned in encoded_subjectPublicKeyInfo_len.
*
* When encoded_subjectPublicKeyInfo != NULL, at invocation
* *encoded_subjectPublicKeyInfo_len must be the size of the
* encoded_subjectPublicKeyInfo buffer.
* Upon return, it is the actual size of the encoded public key.
*
* Returns NTRU_OK if successful.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PARAMETER if an argument pointer
* (other than encoded_subjectPublicKeyInfo) is NULL.
* Returns NTRU_ERROR_BASE + NTRU_BAD_LENGTH if pubkey_blob_len is zero.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PUBLIC_KEY if the public-key blob is
* invalid (unknown format, corrupt, bad length).
* Returns NTRU_ERROR_BASE + NTRU_BUFFER_TOO_SMALL if the SubjectPublicKeyInfo
* buffer is too small.
*/
NTRUCALL
ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
uint16_t pubkey_blob_len, /* in - no. of octets in public-key
blob */
uint8_t const *pubkey_blob, /* in - ptr to public-key blob */
uint16_t *encoded_subjectPublicKeyInfo_len,
/* in/out - no. of octets in encoded info,
address for no. of octets in
encoded info */
uint8_t *encoded_subjectPublicKeyInfo);
/* out - address for encoded info */
/* ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey
*
* Decodes a DER-encoded NTRUEncrypt public-key from a
* SubjectPublicKeyInfo field in an X.509 certificate and returns the
* public-key blob itself.
*
* The required minimum size of the output public-key buffer (pubkey_blob)
* may be queried by invoking this function with pubkey_blob = NULL.
* In this case, no decoding is performed, NTRU_OK is returned, and the
* required minimum size for pubkey_blob is returned in pubkey_blob_len.
*
* When pubkey_blob != NULL, at invocation *pubkey_blob_len must be the
* size of the pubkey_blob buffer.
* Upon return, it is the actual size of the public-key blob.
*
* Returns NTRU_OK if successful.
* Returns NTRU_ERROR_BASE + NTRU_BAD_LENGTH if the encoded data buffer
* does not contain a full der prefix and public key.
* Returns NTRU_ERROR_BASE + NTRU_BAD_PARAMETER if an argument pointer
* (other than pubkey_blob) is NULL.
* Returns NTRU_ERROR_BASE + NTRU_BAD_ENCODING if the encoded data is
* an invalid encoding of an NTRU public key.
* Returns NTRU_ERROR_BASE + NTRU_OID_NOT_RECOGNIZED if the
* encoded data contains an OID that identifies an object other than
* an NTRU public key.
* Returns NTRU_ERROR_BASE + NTRU_BUFFER_TOO_SMALL if the pubkey_blob buffer
* is too small.
*/
NTRUCALL
ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(
uint8_t const *encoded_data, /* in - ptr to subjectPublicKeyInfo
in the encoded data */
uint16_t *pubkey_blob_len, /* in/out - no. of octets in pubkey blob,
address for no. of octets in
pubkey blob */
uint8_t *pubkey_blob, /* out - address for pubkey blob */
uint8_t **next, /* out - address for ptr to encoded
data following the
subjectPublicKeyInfo */
uint32_t *remaining_data_len); /* in/out - number of bytes remaining in
buffer *next */
/* ntru_encrypt_get_param_set_name
*
* Returns pointer to null terminated parameter set name
* or NULL if parameter set ID is not found.
*/
const char *
ntru_encrypt_get_param_set_name(
NTRU_ENCRYPT_PARAM_SET_ID id); /* in - parameter-set id */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* NTRU_CRYPTO_H */

View File

@@ -0,0 +1,849 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_drbg.c
*
* Contents: Implementation of a SHA-256 HMAC-based deterministic random byte
* generator (HMAC_DRBG) as defined in ANSI X9.82, Part 3 - 2007.
*
* This implementation:
* - allows for MAX_INSTANTIATIONS simultaneous drbg instantiations
* (may be overridden on compiler command line)
* - has a maximum security strength of 256 bits
* - automatically uses SHA-256 for all security strengths
* - allows a personalization string of length up to
* HMAC_DRBG_MAX_PERS_STR_BYTES bytes
* - implments reseeding
* - does not implement additional input for reseeding or generation
* - does not implement predictive resistance
* - limits the number of bytes requested in one invocation of generate to
* MAX_BYTES_PER_REQUEST
* - uses a callback function to allow the caller to supply the
* Get_entropy_input routine (entropy function)
* - limits the number of bytes returned from the entropy function to
* MAX_ENTROPY_NONCE_BYTES
* - gets the nonce bytes along with the entropy input from the entropy
* function
* - automatically reseeds an instantitation after MAX_REQUESTS calls to
* generate
*
*****************************************************************************/
#include "ntru_crypto.h"
#include "ntru_crypto_drbg.h"
#include "ntru_crypto_hmac.h"
/************************
* HMAC_DRBG parameters *
************************/
/* Note: Combined entropy input and nonce are a total of 2 * sec_strength_bits
* of randomness to provide quantum resistance */
#define HMAC_DRBG_MAX_MIN_ENTROPY_NONCE_BYTES \
(2 * DRBG_MAX_SEC_STRENGTH_BITS) / 8
#define HMAC_DRBG_MAX_ENTROPY_NONCE_BYTES \
HMAC_DRBG_MAX_MIN_ENTROPY_NONCE_BYTES *DRBG_MAX_BYTES_PER_BYTE_OF_ENTROPY
#define HMAC_DRBG_MAX_REQUESTS 0xffffffff
/*******************
* DRBG structures *
*******************/
/* SHA256_HMAC_DRBG state structure */
typedef struct {
uint32_t sec_strength; /* security strength in bits */
uint32_t requests_left; /* generation requests remaining
before reseeding */
ENTROPY_FN entropy_fn; /* pointer to entropy function */
NTRU_CRYPTO_HMAC_CTX *hmac_ctx; /* pointer to HMAC context */
uint8_t V[33]; /* md_len size internal state + 1 */
} SHA256_HMAC_DRBG_STATE;
/* External DRBG state structure */
typedef struct {
RANDOM_BYTES_FN randombytesfn;
} EXTERNAL_DRBG_STATE;
/* DRBG state structure */
typedef struct {
uint32_t handle;
DRBG_TYPE type;
void *state;
} DRBG_STATE;
/*************
* DRBG DATA *
*************/
/* array of drbg states */
static DRBG_STATE drbg_state[DRBG_MAX_INSTANTIATIONS];
/******************************
* SHA256 HMAC_DRBG functions *
******************************/
/* sha256_hmac_drbg_update
*
* This routine is the SHA-256 HMAC_DRBG derivation function for
* instantiation, and reseeding, and it is used in generation as well.
* It updates the internal state.
*
* For instantiation, provided_data1 holds the entropy input and nonce;
* provided_data2 holds the optional personalization string. Combined, this
* is the seed material.
*
* For reseeding, provided_data1 holds the entropy input;
* provided_data2 is NULL (because this implementation does not support
* additional input).
*
* For byte generation, both provided_data1 and provided_data2 are NULL.
*
* Returns DRBG_OK if successful.
* Returns HMAC errors if they occur.
*/
static uint32_t
sha256_hmac_drbg_update(
SHA256_HMAC_DRBG_STATE *s,
uint8_t *key, /* md_len size array */
uint32_t md_len,
uint8_t const *provided_data1,
uint32_t provided_data1_bytes,
uint8_t const *provided_data2,
uint32_t provided_data2_bytes) {
uint32_t result;
/* new key = HMAC(K, V || 0x00 [|| provided data1 [|| provided data2]] */
if ((result = ntru_crypto_hmac_init(s->hmac_ctx)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
s->V[md_len] = 0x00;
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, s->V, md_len + 1)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if (provided_data1) {
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, provided_data1,
provided_data1_bytes)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
if (provided_data2) {
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, provided_data2,
provided_data2_bytes)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
}
}
if ((result = ntru_crypto_hmac_final(s->hmac_ctx, key)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_set_key(s->hmac_ctx, key)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
/* new V = HMAC(K, V) */
if ((result = ntru_crypto_hmac_init(s->hmac_ctx)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, s->V, md_len)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_final(s->hmac_ctx, s->V)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
/* if provided data exists, update K and V again */
if (provided_data1) {
/* new key = HMAC(K, V || 0x01 || provided data1 [|| provided data2] */
if ((result = ntru_crypto_hmac_init(s->hmac_ctx)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
s->V[md_len] = 0x01;
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, s->V, md_len + 1)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, provided_data1,
provided_data1_bytes)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
if (provided_data2) {
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, provided_data2,
provided_data2_bytes)) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
}
if ((result = ntru_crypto_hmac_final(s->hmac_ctx, key)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_set_key(s->hmac_ctx, key)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
/* new V = HMAC(K, V) */
if ((result = ntru_crypto_hmac_init(s->hmac_ctx)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, s->V, md_len)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_final(s->hmac_ctx, s->V)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
}
memset(key, 0, md_len);
DRBG_RET(DRBG_OK);
}
/* sha256_hmac_drbg_instantiate
*
* This routine allocates and initializes a SHA-256 HMAC_DRBG internal state.
*
* Returns DRBG_OK if successful.
* Returns DRBG_BAD_LENGTH if the personalization string is too long.
* Returns DRBG_OUT_OF_MEMORY if the internal state cannot be allocated.
* Returns errors from HASH or SHA256 if those errors occur.
*/
static uint32_t
sha256_hmac_drbg_instantiate(
uint32_t sec_strength_bits, /* strength to instantiate */
uint8_t const *pers_str,
uint32_t pers_str_bytes,
ENTROPY_FN entropy_fn,
SHA256_HMAC_DRBG_STATE **state) {
uint8_t entropy_nonce[HMAC_DRBG_MAX_ENTROPY_NONCE_BYTES];
uint32_t entropy_nonce_bytes;
uint32_t min_bytes_of_entropy;
uint8_t num_bytes_per_byte_of_entropy;
uint8_t key[32]; /* array of md_len size */
SHA256_HMAC_DRBG_STATE *s;
uint32_t result;
uint32_t i;
/* check arguments */
if (pers_str_bytes > HMAC_DRBG_MAX_PERS_STR_BYTES) {
DRBG_RET(DRBG_BAD_LENGTH);
}
/* calculate number of bytes needed for the entropy input and nonce
* for a SHA256_HMAC_DRBG, and get them from the entropy source
*/
if (entropy_fn(GET_NUM_BYTES_PER_BYTE_OF_ENTROPY,
&num_bytes_per_byte_of_entropy) == 0) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
if ((num_bytes_per_byte_of_entropy == 0) ||
(num_bytes_per_byte_of_entropy >
DRBG_MAX_BYTES_PER_BYTE_OF_ENTROPY)) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
min_bytes_of_entropy = (2 * sec_strength_bits) / 8;
entropy_nonce_bytes = min_bytes_of_entropy * num_bytes_per_byte_of_entropy;
for (i = 0; i < entropy_nonce_bytes; i++) {
if (entropy_fn(GET_BYTE_OF_ENTROPY, entropy_nonce + i) == 0) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
}
/* allocate SHA256_HMAC_DRBG state */
s = (SHA256_HMAC_DRBG_STATE *) MALLOC(sizeof(SHA256_HMAC_DRBG_STATE));
if (s == NULL) {
DRBG_RET(DRBG_OUT_OF_MEMORY);
}
/* allocate HMAC context */
memset(key, 0, sizeof(key));
if ((result = ntru_crypto_hmac_create_ctx(NTRU_CRYPTO_HASH_ALGID_SHA256,
key, sizeof(key), &s->hmac_ctx)) != NTRU_CRYPTO_HMAC_OK) {
FREE(s);
return result;
}
/* init and update internal state */
memset(s->V, 0x01, sizeof(s->V));
if ((result = sha256_hmac_drbg_update(s, key, sizeof(key),
entropy_nonce, entropy_nonce_bytes,
pers_str, pers_str_bytes)) != DRBG_OK) {
(void) ntru_crypto_hmac_destroy_ctx(s->hmac_ctx);
memset(s->V, 0, sizeof(s->V));
FREE(s);
memset(entropy_nonce, 0, sizeof(entropy_nonce));
return result;
}
memset(entropy_nonce, 0, sizeof(entropy_nonce));
/* init instantiation parameters */
s->sec_strength = sec_strength_bits;
s->requests_left = HMAC_DRBG_MAX_REQUESTS;
s->entropy_fn = entropy_fn;
*state = s;
return result;
}
/* sha256_hmac_drbg_free
*
* This routine frees a SHA-256 HMAC_DRBG internal state.
*
* Returns DRBG_OK if successful.
* Returns DRBG_BAD_PARAMETER if inappropriate NULL pointers are passed.
*/
static void
sha256_hmac_drbg_free(
SHA256_HMAC_DRBG_STATE *s) {
if (s->hmac_ctx) {
(void) ntru_crypto_hmac_destroy_ctx(s->hmac_ctx);
}
memset(s->V, 0, sizeof(s->V));
s->sec_strength = 0;
s->requests_left = 0;
s->entropy_fn = NULL;
FREE(s);
}
/* sha256_hmac_drbg_reseed
*
* This function reseeds an instantiated SHA256_HMAC DRBG.
*
* Returns DRBG_OK if successful.
* Returns HMAC errors if they occur.
*/
static uint32_t
sha256_hmac_drbg_reseed(
SHA256_HMAC_DRBG_STATE *s) {
uint8_t entropy[HMAC_DRBG_MAX_ENTROPY_NONCE_BYTES];
uint32_t entropy_bytes;
uint32_t min_bytes_of_entropy;
uint8_t num_bytes_per_byte_of_entropy;
uint8_t key[32]; /* array of md_len size for sha256_hmac_drbg_update() */
uint32_t result;
uint32_t i;
/* calculate number of bytes needed for the entropy input
* for a SHA256_HMAC_DRBG, and get them from the entropy source
*/
if (s->entropy_fn(GET_NUM_BYTES_PER_BYTE_OF_ENTROPY,
&num_bytes_per_byte_of_entropy) == 0) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
if ((num_bytes_per_byte_of_entropy == 0) ||
(num_bytes_per_byte_of_entropy >
DRBG_MAX_BYTES_PER_BYTE_OF_ENTROPY)) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
/* note: factor of 2 here is probably unnecessary, but ensures quantum
* resistance even if internal state is leaked prior to reseed */
min_bytes_of_entropy = (2 * s->sec_strength) / 8;
entropy_bytes = min_bytes_of_entropy * num_bytes_per_byte_of_entropy;
for (i = 0; i < entropy_bytes; i++) {
if (s->entropy_fn(GET_BYTE_OF_ENTROPY, entropy + i) == 0) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
}
/* update internal state */
if ((result = sha256_hmac_drbg_update(s, key, sizeof(key),
entropy, entropy_bytes, NULL, 0)) != DRBG_OK) {
return result;
}
/* reset request counter */
s->requests_left = HMAC_DRBG_MAX_REQUESTS;
DRBG_RET(DRBG_OK);
}
/* sha256_hmac_drbg_generate
*
* This routine generates pseudorandom bytes from a SHA256_HMAC DRBG.
*
* Returns DRBG_OK if successful.
* Returns DRBG_BAD_LENGTH if too many bytes are requested or the requested
* security strength is too large.
* Returns HMAC errors if they occur.
*/
static uint32_t
sha256_hmac_drbg_generate(
SHA256_HMAC_DRBG_STATE *s,
uint32_t sec_strength_bits,
uint32_t num_bytes,
uint8_t *out) {
uint8_t key[32]; /* array of md_len size for sha256_hmac_drbg_update() */
uint32_t result;
/* check if number of bytes requested exceeds the maximum allowed */
if (num_bytes > HMAC_DRBG_MAX_BYTES_PER_REQUEST) {
DRBG_RET(DRBG_BAD_LENGTH);
}
/* check if drbg has adequate security strength */
if (sec_strength_bits > s->sec_strength) {
DRBG_RET(DRBG_BAD_LENGTH);
}
/* check if max requests have been exceeded */
if (s->requests_left == 0) {
if ((result = sha256_hmac_drbg_reseed(s)) != DRBG_OK) {
return result;
}
}
/* generate pseudorandom bytes */
while (num_bytes > 0) {
/* generate md_len bytes = V = HMAC(K, V) */
if ((result = ntru_crypto_hmac_init(s->hmac_ctx)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_update(s->hmac_ctx, s->V,
sizeof(key))) != NTRU_CRYPTO_HMAC_OK) {
return result;
}
if ((result = ntru_crypto_hmac_final(s->hmac_ctx, s->V)) !=
NTRU_CRYPTO_HMAC_OK) {
return result;
}
/* copy generated bytes to output buffer */
if (num_bytes < sizeof(key)) {
memcpy(out, s->V, num_bytes);
num_bytes = 0;
} else {
memcpy(out, s->V, sizeof(key));
out += sizeof(key);
num_bytes -= sizeof(key);
}
}
/* update internal state */
if ((result = sha256_hmac_drbg_update(s, key, sizeof(key),
NULL, 0, NULL, 0)) != DRBG_OK) {
return result;
}
s->requests_left--;
DRBG_RET(DRBG_OK);
}
/******************
* DRBG functions *
******************/
/* drbg_get_new_drbg
*
* This routine finds an uninstantiated drbg state and returns a pointer to it.
*
* Returns a pointer to an uninstantiated drbg state if found.
* Returns NULL if all drbg states are instantiated.
*/
static DRBG_STATE *
drbg_get_new_drbg() {
int i;
for (i = 0; i < DRBG_MAX_INSTANTIATIONS; i++) {
if (drbg_state[i].state == NULL) {
return drbg_state + i;
}
}
return NULL;
}
/* drbg_get_drbg
*
* This routine finds an instantiated drbg state given its handle, and returns
* a pointer to it.
*
* Returns a pointer to the drbg state if found.
* Returns NULL if the drbg state is not found.
*/
static DRBG_STATE *
drbg_get_drbg(
DRBG_HANDLE handle) /* in/out - drbg handle */
{
int i;
for (i = 0; i < DRBG_MAX_INSTANTIATIONS; i++) {
if ((drbg_state[i].handle == handle) && drbg_state[i].state) {
return drbg_state + i;
}
}
return NULL;
}
/* drbg_get_new_handle
*
* This routine gets a new, unique 32-bit handle.
*
* Returns the new DRBG handle.
*/
static DRBG_HANDLE
drbg_get_new_handle(void) {
DRBG_HANDLE h = 0;
/* ensure the new handle is unique:
* if it already exists, increment it
*/
while (drbg_get_drbg(h) != NULL) {
++h;
}
return h;
}
/********************
* Public functions *
********************/
/* ntru_crypto_drbg_instantiate
*
* This routine instantiates a drbg with the requested security strength.
* See ANS X9.82: Part 3-2007. This routine currently returns an instance
* of SHA-256 HMAC_DRBG for all requested security strengths.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if an argument pointer is NULL.
* Returns DRBG_ERROR_BASE + DRBG_BAD_LENGTH if the security strength requested
* or the personalization string is too large.
* Returns DRBG_ERROR_BASE + DRBG_NOT_AVAILABLE if there are no instantiation
* slots available
* Returns DRBG_ERROR_BASE + DRBG_OUT_OF_MEMORY if the internal state cannot be
* allocated from the heap.
*/
uint32_t
ntru_crypto_drbg_instantiate(
uint32_t sec_strength_bits, /* in - requested sec strength in bits */
uint8_t const *pers_str, /* in - ptr to personalization string */
uint32_t pers_str_bytes, /* in - no. personalization str bytes */
ENTROPY_FN entropy_fn, /* in - pointer to entropy function */
DRBG_HANDLE *handle) /* out - address for drbg handle */
{
DRBG_STATE *drbg = NULL;
SHA256_HMAC_DRBG_STATE *state = NULL;
uint32_t result;
/* check arguments */
if ((!pers_str && pers_str_bytes) || !entropy_fn || !handle) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
if (sec_strength_bits > DRBG_MAX_SEC_STRENGTH_BITS) {
DRBG_RET(DRBG_BAD_LENGTH);
}
if (pers_str && (pers_str_bytes == 0)) {
pers_str = NULL;
}
/* set security strength */
if (sec_strength_bits <= 112) {
sec_strength_bits = 112;
} else if (sec_strength_bits <= 128) {
sec_strength_bits = 128;
} else if (sec_strength_bits <= 192) {
sec_strength_bits = 192;
} else {
sec_strength_bits = 256;
}
/* get an uninstantiated drbg */
if ((drbg = drbg_get_new_drbg()) == NULL) {
DRBG_RET(DRBG_NOT_AVAILABLE);
}
/* init entropy function */
if (entropy_fn(INIT, NULL) == 0) {
DRBG_RET(DRBG_ENTROPY_FAIL);
}
/* instantiate a SHA-256 HMAC_DRBG */
if ((result = sha256_hmac_drbg_instantiate(sec_strength_bits,
pers_str, pers_str_bytes,
entropy_fn,
&state)) != DRBG_OK) {
return result;
}
/* init drbg state */
drbg->handle = drbg_get_new_handle();
drbg->type = SHA256_HMAC_DRBG;
drbg->state = state;
/* return drbg handle */
*handle = drbg->handle;
DRBG_RET(DRBG_OK);
}
/* ntru_crypto_drbg_external_instantiate
*
* This routine instruments an external DRBG so that ntru_crypto routines
* can call it. randombytesfn must be of type
* uint32_t (randombytesfn*)(unsigned char *out, unsigned long long num_bytes);
* and should return DRBG_OK on success.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_NOT_AVAILABLE if there are no instantiation
* slots available
* Returns DRBG_ERROR_BASE + DRBG_OUT_OF_MEMORY if the internal state cannot be
* allocated from the heap.
*/
uint32_t
ntru_crypto_drbg_external_instantiate(
RANDOM_BYTES_FN randombytesfn, /* in - pointer to random bytes function */
DRBG_HANDLE *handle) /* out - address for drbg handle */
{
DRBG_STATE *drbg = NULL;
EXTERNAL_DRBG_STATE *state = NULL;
if (!randombytesfn || !handle) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
/* get an uninstantiated drbg */
if ((drbg = drbg_get_new_drbg()) == NULL) {
DRBG_RET(DRBG_NOT_AVAILABLE);
}
/* instantiate an External DRBG */
state = (EXTERNAL_DRBG_STATE *) MALLOC(sizeof(EXTERNAL_DRBG_STATE));
if (state == NULL) {
DRBG_RET(DRBG_OUT_OF_MEMORY);
}
state->randombytesfn = randombytesfn;
/* init drbg state */
drbg->handle = drbg_get_new_handle();
drbg->type = EXTERNAL_DRBG;
drbg->state = state;
/* return drbg handle */
*handle = drbg->handle;
DRBG_RET(DRBG_OK);
}
/* ntru_crypto_drbg_uninstantiate
*
* This routine frees a drbg given its handle.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid.
*/
uint32_t
ntru_crypto_drbg_uninstantiate(
DRBG_HANDLE handle) /* in - drbg handle */
{
DRBG_STATE *drbg = NULL;
/* find the instantiated drbg */
if ((drbg = drbg_get_drbg(handle)) == NULL) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
/* zero and free drbg state */
if (drbg->state) {
switch (drbg->type) {
case EXTERNAL_DRBG:
FREE(drbg->state);
break;
case SHA256_HMAC_DRBG:
sha256_hmac_drbg_free((SHA256_HMAC_DRBG_STATE *) drbg->state);
break;
}
drbg->state = NULL;
}
drbg->handle = 0;
DRBG_RET(DRBG_OK);
}
/* ntru_crypto_drbg_reseed
*
* This routine reseeds an instantiated drbg.
* See ANS X9.82: Part 3-2007.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid.
* Returns HMAC errors if they occur.
*/
uint32_t
ntru_crypto_drbg_reseed(
DRBG_HANDLE handle) /* in - drbg handle */
{
DRBG_STATE *drbg = NULL;
/* find the instantiated drbg */
if ((drbg = drbg_get_drbg(handle)) == NULL) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
if (drbg->type == EXTERNAL_DRBG) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
/* reseed the SHA-256 HMAC_DRBG */
return sha256_hmac_drbg_reseed((SHA256_HMAC_DRBG_STATE *) drbg->state);
}
/* ntru_crypto_drbg_generate
*
* This routine generates pseudorandom bytes using an instantiated drbg.
* If the maximum number of requests has been reached, reseeding will occur.
* See ANS X9.82: Part 3-2007.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid or if
* an argument pointer is NULL.
* Returns DRBG_ERROR_BASE + DRBG_BAD_LENGTH if the security strength requested
* is too large or the number of bytes requested is zero or too large.
* Returns HMAC errors if they occur.
*/
uint32_t
ntru_crypto_drbg_generate(
DRBG_HANDLE handle, /* in - drbg handle */
uint32_t sec_strength_bits, /* in - requested sec strength in bits */
uint32_t num_bytes, /* in - number of octets to generate */
uint8_t *out) /* out - address for generated octets */
{
DRBG_STATE *drbg = NULL;
/* find the instantiated drbg */
if ((drbg = drbg_get_drbg(handle)) == NULL) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
/* check arguments */
if (!out) {
DRBG_RET(DRBG_BAD_PARAMETER);
}
if (num_bytes == 0) {
DRBG_RET(DRBG_BAD_LENGTH);
}
/* generate pseudorandom output from the SHA256_HMAC_DRBG */
switch (drbg->type) {
case EXTERNAL_DRBG:
return ((EXTERNAL_DRBG_STATE *) drbg->state)->randombytesfn(out, num_bytes);
case SHA256_HMAC_DRBG:
return sha256_hmac_drbg_generate(
(SHA256_HMAC_DRBG_STATE *) drbg->state,
sec_strength_bits, num_bytes, out);
default:
DRBG_RET(DRBG_BAD_PARAMETER);
}
}

View File

@@ -0,0 +1,208 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_drbg.h
*
* Contents: Public header file for ntru_crypto_drbg.c.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_DRBG_H
#define NTRU_CRYPTO_DRBG_H
#include "ntru_crypto_platform.h"
#include "ntru_crypto_error.h"
#if !defined(NTRUCALL)
#if !defined(WIN32) || defined(NTRUCRYPTO_STATIC)
/* Linux, or a Win32 static library */
#define NTRUCALL extern uint32_t
#elif defined(NTRUCRYPTO_EXPORTS)
/* Win32 DLL build */
#define NTRUCALL extern __declspec(dllexport) uint32_t
#else
/* Win32 DLL import */
#define NTRUCALL extern __declspec(dllimport) uint32_t
#endif
#endif /* NTRUCALL */
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/*******************
* DRBG parameters *
*******************/
#if !defined(DRBG_MAX_INSTANTIATIONS)
#define DRBG_MAX_INSTANTIATIONS 4
#endif
#define DRBG_MAX_SEC_STRENGTH_BITS 256
#define DRBG_MAX_BYTES_PER_BYTE_OF_ENTROPY 8
/************************
* HMAC_DRBG parameters *
************************/
#define HMAC_DRBG_MAX_PERS_STR_BYTES 32
#define HMAC_DRBG_MAX_BYTES_PER_REQUEST 1024
/********************
* type definitions *
********************/
typedef uint32_t DRBG_HANDLE; /* drbg handle */
typedef enum { /* drbg types */
EXTERNAL_DRBG,
SHA256_HMAC_DRBG,
} DRBG_TYPE;
typedef enum { /* entropy-function commands */
GET_NUM_BYTES_PER_BYTE_OF_ENTROPY = 0,
INIT,
GET_BYTE_OF_ENTROPY,
} ENTROPY_CMD;
typedef uint8_t (*ENTROPY_FN)( /* get entropy function */
ENTROPY_CMD cmd, /* command */
uint8_t *out); /* address for output */
/* Type for external PRNG functions. Must return DRBG_OK on success */
typedef uint32_t (*RANDOM_BYTES_FN)( /* random bytes function */
uint8_t *out, /* output buffer */
uint32_t num_bytes); /* number of bytes */
/***************
* error codes *
***************/
#define DRBG_OK 0x00000000 /* no errors */
#define DRBG_OUT_OF_MEMORY 0x00000001 /* can't allocate memory */
#define DRBG_BAD_PARAMETER 0x00000002 /* null pointer */
#define DRBG_BAD_LENGTH 0x00000003 /* invalid no. of bytes */
#define DRBG_NOT_AVAILABLE 0x00000004 /* no instantiation slot available */
#define DRBG_ENTROPY_FAIL 0x00000005 /* entropy function failure */
/***************
* error macro *
***************/
#define DRBG_RESULT(r) ((uint32_t)((r) ? DRBG_ERROR_BASE + (r) : (r)))
#define DRBG_RET(r) return DRBG_RESULT(r);
/*************************
* function declarations *
*************************/
/* ntru_crypto_drbg_instantiate
*
* This routine instantiates a drbg with the requested security strength.
* See ANS X9.82: Part 3-2007.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if an argument pointer is NULL.
* Returns DRBG_ERROR_BASE + DRBG_BAD_LENGTH if the security strength requested
* or the personalization string is too large.
* Returns DRBG_ERROR_BASE + DRBG_OUT_OF_MEMORY if the internal state cannot be
* allocated from the heap.
*/
NTRUCALL
ntru_crypto_drbg_instantiate(
uint32_t sec_strength_bits, /* in - requested sec strength in bits */
uint8_t const *pers_str, /* in - ptr to personalization string */
uint32_t pers_str_bytes, /* in - no. personalization str bytes */
ENTROPY_FN entropy_fn, /* in - pointer to entropy function */
DRBG_HANDLE *handle); /* out - address for drbg handle */
/* ntru_crypto_drbg_external_instantiate
*
* This routine instruments an external DRBG so that ntru_crypto routines
* can call it. randombytesfn must be of type
* uint32_t (randombytesfn*)(unsigned char *out, unsigned long long num_bytes);
* and should return DRBG_OK on success.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_NOT_AVAILABLE if there are no instantiation
* slots available
* Returns DRBG_ERROR_BASE + DRBG_OUT_OF_MEMORY if the internal state cannot be
* allocated from the heap.
*/
NTRUCALL
ntru_crypto_drbg_external_instantiate(
RANDOM_BYTES_FN randombytesfn, /* in - pointer to random bytes function */
DRBG_HANDLE *handle); /* out - address for drbg handle */
/* ntru_crypto_drbg_uninstantiate
*
* This routine frees a drbg given its handle.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid.
*/
NTRUCALL
ntru_crypto_drbg_uninstantiate(
DRBG_HANDLE handle); /* in - drbg handle */
/* ntru_crypto_drbg_reseed
*
* This routine reseeds an instantiated drbg.
* See ANS X9.82: Part 3-2007.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid.
* Returns NTRU_CRYPTO_HMAC errors if they occur.
*/
NTRUCALL
ntru_crypto_drbg_reseed(
DRBG_HANDLE handle); /* in - drbg handle */
/* ntru_crypto_drbg_generate
*
* This routine generates pseudorandom bytes using an instantiated drbg.
* If the maximum number of requests has been reached, reseeding will occur.
* See ANS X9.82: Part 3-2007.
*
* Returns DRBG_OK if successful.
* Returns DRBG_ERROR_BASE + DRBG_BAD_PARAMETER if handle is not valid or if
* an argument pointer is NULL.
* Returns DRBG_ERROR_BASE + DRBG_BAD_LENGTH if the security strength requested
* is too large or the number of bytes requested is zero or too large.
* Returns NTRU_CRYPTO_HMAC errors if they occur.
*/
NTRUCALL
ntru_crypto_drbg_generate(
DRBG_HANDLE handle, /* in - drbg handle */
uint32_t sec_strength_bits, /* in - requested sec strength in bits */
uint32_t num_bytes, /* in - number of octets to generate */
uint8_t *out); /* out - address for generated octets */
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* NTRU_CRYPTO_DRBG_H */

View File

@@ -0,0 +1,42 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_error.h
*
* Contents: Contains base values for crypto error codes.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_ERROR_H
#define NTRU_CRYPTO_ERROR_H
/* define base values for crypto error codes */
#define HASH_ERROR_BASE ((uint32_t) 0x00000100)
#define HMAC_ERROR_BASE ((uint32_t) 0x00000200)
#define SHA_ERROR_BASE ((uint32_t) 0x00000400)
#define DRBG_ERROR_BASE ((uint32_t) 0x00000a00)
#define NTRU_ERROR_BASE ((uint32_t) 0x00003000)
#define MGF1_ERROR_BASE ((uint32_t) 0x00004100)
#endif /* NTRU_CRYPTO_ERROR_H */

View File

@@ -0,0 +1,307 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hash.c
*
* Contents: Routines implementing the hash object abstraction.
*
*****************************************************************************/
#include "ntru_crypto.h"
#include "ntru_crypto_hash.h"
typedef uint32_t (*NTRU_CRYPTO_HASH_INIT_FN)(
void *c);
typedef uint32_t (*NTRU_CRYPTO_HASH_UPDATE_FN)(
void *c,
void const *data,
uint32_t len);
typedef uint32_t (*NTRU_CRYPTO_HASH_FINAL_FN)(
void *c,
void *md);
typedef uint32_t (*NTRU_CRYPTO_HASH_DIGEST_FN)(
void const *data,
uint32_t len,
void *md);
typedef struct _NTRU_CRYPTO_HASH_ALG_PARAMS {
uint8_t algid;
uint16_t block_length;
uint16_t digest_length;
NTRU_CRYPTO_HASH_INIT_FN init;
NTRU_CRYPTO_HASH_UPDATE_FN update;
NTRU_CRYPTO_HASH_FINAL_FN final;
NTRU_CRYPTO_HASH_DIGEST_FN digest;
} NTRU_CRYPTO_HASH_ALG_PARAMS;
static NTRU_CRYPTO_HASH_ALG_PARAMS const algs_params[] = {
{
NTRU_CRYPTO_HASH_ALGID_SHA1,
SHA_1_BLK_LEN,
SHA_1_MD_LEN,
(NTRU_CRYPTO_HASH_INIT_FN) SHA_1_INIT_FN,
(NTRU_CRYPTO_HASH_UPDATE_FN) SHA_1_UPDATE_FN,
(NTRU_CRYPTO_HASH_FINAL_FN) SHA_1_FINAL_FN,
(NTRU_CRYPTO_HASH_DIGEST_FN) SHA_1_DIGEST_FN,
},
{
NTRU_CRYPTO_HASH_ALGID_SHA256,
SHA_256_BLK_LEN,
SHA_256_MD_LEN,
(NTRU_CRYPTO_HASH_INIT_FN) SHA_256_INIT_FN,
(NTRU_CRYPTO_HASH_UPDATE_FN) SHA_256_UPDATE_FN,
(NTRU_CRYPTO_HASH_FINAL_FN) SHA_256_FINAL_FN,
(NTRU_CRYPTO_HASH_DIGEST_FN) SHA_256_DIGEST_FN,
},
};
static int const numalgs = (sizeof(algs_params) / sizeof(algs_params[0]));
/* get_alg_params
*
* Return a pointer to the hash algorithm parameters for the hash algorithm
* specified, by looking for algid in the global algs_params table.
* If not found, return NULL.
*/
static NTRU_CRYPTO_HASH_ALG_PARAMS const *
get_alg_params(
NTRU_CRYPTO_HASH_ALGID algid) /* in - the hash algorithm to find */
{
int i;
for (i = 0; i < numalgs; i++) {
if (algs_params[i].algid == algid) {
return &algs_params[i];
}
}
return NULL;
}
/* ntru_crypto_hash_set_alg
*
* Sets the hash algorithm for the hash context. This must be called before
* any calls to ntru_crypto_hash_block_length(),
* ntru_crypto_hash_digest_length(), or ntru_crypto_hash_init() are made.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
uint32_t
ntru_crypto_hash_set_alg(
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm to be used */
NTRU_CRYPTO_HASH_CTX *c) /* in/out - pointer to the hash context */
{
if (!c) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
c->alg_params = get_alg_params(algid);
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_block_length
*
* Gets the number of bytes in an input block for the hash algorithm
* specified in the hash context. The hash algorithm must have been set
* in the hash context with a call to ntru_crypto_hash_set_alg() prior to
* calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_block_length(
NTRU_CRYPTO_HASH_CTX *c, /* in - pointer to the hash context */
uint16_t *blk_len) /* out - address for block length in bytes */
{
if (!c || !blk_len) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
*blk_len = c->alg_params->block_length;
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_digest_length
*
* Gets the number of bytes needed to hold the message digest for the
* hash algorithm specified in the hash context. The algorithm must have
* been set in the hash context with a call to ntru_crypto_hash_set_alg() prior
* to calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_digest_length(
NTRU_CRYPTO_HASH_CTX const *c, /* in - pointer to the hash context */
uint16_t *md_len) /* out - addr for digest length in bytes */
{
if (!c || !md_len) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
*md_len = c->alg_params->digest_length;
HASH_RET(NTRU_CRYPTO_HASH_OK);
}
/* ntru_crypto_hash_init
*
* This routine performs standard initialization of the hash state.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_init(
NTRU_CRYPTO_HASH_CTX *c) /* in/out - pointer to hash context */
{
if (!c) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->init(&c->alg_ctx);
}
/* ntru_crypto_hash_update
*
* This routine processes input data and updates the hash calculation.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_update(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len) /* in - number of bytes of input data */
{
if (!c || (data_len && !data)) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->update(&c->alg_ctx, data, data_len);
}
/* ntru_crypto_hash_final
*
* This routine completes the hash calculation and returns the message digest.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
uint32_t
ntru_crypto_hash_final(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t *md) /* out - address for message digest */
{
if (!c || !md) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
if (!c->alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
return c->alg_params->final(&c->alg_ctx, md);
}
/* ntru_crypto_hash_digest
*
* This routine computes a message digest. It is assumed that the
* output buffer md is large enough to hold the output (see
* ntru_crypto_hash_digest_length)
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
uint32_t
ntru_crypto_hash_digest(
NTRU_CRYPTO_HASH_ALGID algid, /* in - the hash algorithm to use */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len, /* in - number of bytes of input data */
uint8_t *md) /* out - address for message digest */
{
NTRU_CRYPTO_HASH_ALG_PARAMS const *alg_params = get_alg_params(algid);
if (!alg_params) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_ALG);
}
if ((data_len && !data) || !md) {
HASH_RET(NTRU_CRYPTO_HASH_BAD_PARAMETER);
}
return alg_params->digest(data, data_len, md);
}

View File

@@ -0,0 +1,201 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hash.h
*
* Contents: Definitions and declarations for the hash object abstraction.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_HASH_H
#define NTRU_CRYPTO_HASH_H
#include "ntru_crypto_platform.h"
#include "ntru_crypto_error.h"
#include "ntru_crypto_hash_basics.h"
#include "ntru_crypto_sha1.h"
#include "ntru_crypto_sha256.h"
/***************
* error macro *
***************/
#define HASH_RESULT(r) ((uint32_t)((r) ? HASH_ERROR_BASE + (r) : (r)))
#define HASH_RET(r) return HASH_RESULT(r);
/*************************
* structure definitions *
*************************/
/* _NTRU_CRYPTO_HASH_ALG_PARAMS
*
* An opaque forward declaration for a private structure used
* internally by the hash object interface.
*/
struct _NTRU_CRYPTO_HASH_ALG_PARAMS;
/* NTRU_CRYPTO_HASH_CTX
*
* Hash object context information.
*/
typedef struct {
struct _NTRU_CRYPTO_HASH_ALG_PARAMS const *alg_params;
union {
NTRU_CRYPTO_SHA1_CTX sha1;
NTRU_CRYPTO_SHA2_CTX sha256;
} alg_ctx;
} NTRU_CRYPTO_HASH_CTX;
/*************************
* function declarations *
*************************/
/* ntru_crypto_hash_set_alg
*
* Sets the hash algorithm for the hash context. This must be called before
* any calls to crypto_hash_block_length(), crypto_hash_digest_length(), or
* crypto_hash_init() are made.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
extern uint32_t
ntru_crypto_hash_set_alg(
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algoirithm to be used */
NTRU_CRYPTO_HASH_CTX *c); /* in/out - pointer to the hash context */
/* ntru_crypto_hash_block_length
*
* Gets the number of bytes in an input block for the hash algorithm
* specified in the hash context. The hash algorithm must have been set
* in the hash context with a call to crypto_hash_set_alg() prior to
* calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
extern uint32_t
ntru_crypto_hash_block_length(
NTRU_CRYPTO_HASH_CTX *c, /* in - pointer to the hash context */
uint16_t *blk_len); /* out - address for block length in bytes */
/* ntru_crypto_hash_digest_length
*
* Gets the number of bytes needed to hold the message digest for the
* hash algorithm specified in the hash context. The algorithm must have
* been set in the hash context with a call to crypto_hash_set_alg() prior
* to calling this function.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
extern uint32_t
ntru_crypto_hash_digest_length(
NTRU_CRYPTO_HASH_CTX const *c, /* in - pointer to the hash context */
uint16_t *md_len); /*out - addr for digest length in bytes*/
/* ntru_crypto_hash_init
*
* This routine initializes the hash state.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
extern uint32_t
ntru_crypto_hash_init(
NTRU_CRYPTO_HASH_CTX *c); /* in/out - pointer to hash context */
/* ntru_crypto_hash_update
*
* This routine processes input data and updates the hash calculation.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
extern uint32_t
ntru_crypto_hash_update(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len); /* in - number of bytes of input data */
/* ntru_crypto_hash_final
*
* This routine completes the hash calculation and returns the message digest.
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the algorithm has not been set.
*/
extern uint32_t
ntru_crypto_hash_final(
NTRU_CRYPTO_HASH_CTX *c, /* in/out - pointer to hash context */
uint8_t *md); /* out - address for message digest */
/* ntru_crypto_hash_digest
*
* This routine computes a message digest. It is assumed that the
* output buffer md is large enough to hold the output (see
* crypto_hash_digest_length)
*
* Returns NTRU_CRYPTO_HASH_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HASH_BAD_PARAMETER if inappropriate NULL pointers are passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if too much text has been fed to the
* hash algorithm. The size limit is dependent on the hash algorithm,
* and not all algorithms have this limit.
* Returns NTRU_CRYPTO_HASH_BAD_ALG if the specified algorithm is not supported.
*/
extern uint32_t
ntru_crypto_hash_digest(
NTRU_CRYPTO_HASH_ALGID algid, /* in - the hash algorithm to use */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len, /* in - number of bytes of input data */
uint8_t *md); /* out - address for message digest */
#endif /* NTRU_CRYPTO_HASH_H */

View File

@@ -0,0 +1,67 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hash_basics.h
*
* Contents: Common definitions for all hash algorithms.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_HASH_BASICS_H
#define NTRU_CRYPTO_HASH_BASICS_H
#include "ntru_crypto_platform.h"
/**************
* algorithms *
**************/
typedef enum {
NTRU_CRYPTO_HASH_ALGID_NONE = 0,
NTRU_CRYPTO_HASH_ALGID_SHA1,
NTRU_CRYPTO_HASH_ALGID_SHA256,
} NTRU_CRYPTO_HASH_ALGID;
/***************
* error codes *
***************/
#define NTRU_CRYPTO_HASH_OK ((uint32_t) 0x00)
#define NTRU_CRYPTO_HASH_FAIL ((uint32_t) 0x01)
#define NTRU_CRYPTO_HASH_BAD_PARAMETER ((uint32_t) 0x02)
#define NTRU_CRYPTO_HASH_OVERFLOW ((uint32_t) 0x03)
#define NTRU_CRYPTO_HASH_BAD_ALG ((uint32_t) 0x20)
#define NTRU_CRYPTO_HASH_OUT_OF_MEMORY ((uint32_t) 0x21)
/* For backward-compatibility */
typedef uint32_t NTRU_CRYPTO_HASH_ERROR;
/*********
* flags *
*********/
#define HASH_DATA_ONLY 0
#define HASH_INIT (1 << 0)
#define HASH_FINISH (1 << 1)
#endif /* NTRU_CRYPTO_HASH_BASICS_H */

View File

@@ -0,0 +1,319 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hmac.c
*
* Contents: Routines implementing the HMAC hash calculation.
*
*****************************************************************************/
#include "ntru_crypto.h"
#include "ntru_crypto_hmac.h"
/* HMAC context */
struct _NTRU_CRYPTO_HMAC_CTX {
NTRU_CRYPTO_HASH_CTX hash_ctx;
uint8_t *k0;
uint16_t blk_len;
uint16_t md_len;
};
/* ntru_crypto_hmac_create_ctx
*
* This routine creates an HMAC context, setting the hash algorithm and
* the key to be used.
*
* Returns NTRU_CRYPTO_HMAC_OK if successful.
* Returns NTRU_CRYPTO_HMAC_BAD_ALG if the specified algorithm is not supported.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HMAC_OUT_OF_MEMORY if memory cannot be allocated.
*/
uint32_t
ntru_crypto_hmac_create_ctx(
NTRU_CRYPTO_HASH_ALGID algid, /* in - the hash algorithm to be used */
uint8_t const *key, /* in - pointer to the HMAC key */
uint32_t key_len, /* in - number of bytes in HMAC key */
NTRU_CRYPTO_HMAC_CTX **c) /* out - address for pointer to HMAC
context */
{
NTRU_CRYPTO_HMAC_CTX *ctx = NULL;
uint32_t result;
/* check parameters */
if (!c || !key) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
*c = NULL;
/* allocate memory for an HMAC context */
if (NULL == (ctx = (NTRU_CRYPTO_HMAC_CTX *) MALLOC(sizeof(NTRU_CRYPTO_HMAC_CTX)))) {
HMAC_RET(NTRU_CRYPTO_HMAC_OUT_OF_MEMORY);
}
/* set the algorithm */
if ((result = ntru_crypto_hash_set_alg(algid, &ctx->hash_ctx))) {
FREE(ctx);
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_ALG);
}
/* set block length and digest length */
if ((result = ntru_crypto_hash_block_length(&ctx->hash_ctx,
&ctx->blk_len)) ||
(result = ntru_crypto_hash_digest_length(&ctx->hash_ctx,
&ctx->md_len))) {
FREE(ctx);
return result;
}
/* allocate memory for K0 */
if ((ctx->k0 = (uint8_t *) MALLOC(ctx->blk_len)) == NULL) {
FREE(ctx);
HMAC_RET(NTRU_CRYPTO_HMAC_OUT_OF_MEMORY);
}
/* calculate K0 and store in HMAC context */
memset(ctx->k0, 0, ctx->blk_len);
/* check if key is too large */
if (key_len > ctx->blk_len) {
if ((result = ntru_crypto_hash_digest(algid, key, key_len, ctx->k0))) {
memset(ctx->k0, 0, ctx->blk_len);
FREE(ctx->k0);
FREE(ctx);
return result;
}
} else {
memcpy(ctx->k0, key, key_len);
}
/* return pointer to HMAC context */
*c = ctx;
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_destroy_ctx
*
* Destroys an HMAC context.
*
* Returns NTRU_CRYPTO_HMAC_OK if successful.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
uint32_t
ntru_crypto_hmac_destroy_ctx(
NTRU_CRYPTO_HMAC_CTX *c) /* in/out - pointer to HMAC context */
{
if (!c || !c->k0) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
/* clear key and release memory */
memset(c->k0, 0, c->blk_len);
FREE(c->k0);
FREE(c);
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_get_md_len
*
* This routine gets the digest length of the HMAC.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
uint32_t
ntru_crypto_hmac_get_md_len(
NTRU_CRYPTO_HMAC_CTX const *c, /* in - pointer to HMAC context */
uint16_t *md_len) /* out - address for digest length */
{
/* check parameters */
if (!c || !md_len) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
/* get digest length */
*md_len = c->md_len;
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_set_key
*
* This routine sets a digest-length key into the HMAC context.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
uint32_t
ntru_crypto_hmac_set_key(
NTRU_CRYPTO_HMAC_CTX *c, /* in - pointer to HMAC context */
uint8_t const *key) /* in - pointer to new HMAC key */
{
/* check parameters */
if (!c || !key) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
/* copy key */
memcpy(c->k0, key, c->md_len);
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_init
*
* This routine performs standard initialization of the HMAC state.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
uint32_t
ntru_crypto_hmac_init(
NTRU_CRYPTO_HMAC_CTX *c) /* in/out - pointer to HMAC context */
{
uint32_t result;
int i;
/* check parameters */
if (!c) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
/* init hash context and compute H(K0 ^ ipad) */
for (i = 0; i < c->blk_len; i++) {
c->k0[i] ^= 0x36; /* K0 ^ ipad */
}
if ((result = ntru_crypto_hash_init(&c->hash_ctx)) ||
(result = ntru_crypto_hash_update(&c->hash_ctx, c->k0, c->blk_len))) {
return result;
}
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_update
*
* This routine processes input data and updates the HMAC hash calculation.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OVERFLOW if more than bytes are hashed than the
* underlying hash algorithm can handle.
*/
uint32_t
ntru_crypto_hmac_update(
NTRU_CRYPTO_HMAC_CTX *c, /* in/out - pointer to HMAC context */
const uint8_t *data, /* in - pointer to input data */
uint32_t data_len) /* in - no. of bytes of input data */
{
uint32_t result;
/* check parameters */
if (!c || (data_len && !data)) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
if ((result = ntru_crypto_hash_update(&c->hash_ctx, data, data_len))) {
return result;
}
HMAC_RET(NTRU_CRYPTO_HMAC_OK);
}
/* ntru_crypto_hmac_final
*
* This routine completes the HMAC hash calculation and returns the
* message digest.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HASH_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
uint32_t
ntru_crypto_hmac_final(
NTRU_CRYPTO_HMAC_CTX *c, /* in/out - pointer to HMAC context */
uint8_t *md) /* out - address for message digest */
{
uint32_t result = NTRU_CRYPTO_HMAC_OK;
int i;
/* check parameters */
if (!c || !md) {
HMAC_RET(NTRU_CRYPTO_HMAC_BAD_PARAMETER);
}
/* form K0 ^ opad
* complete md = H((K0 ^ ipad) || data)
* compute md = H((K0 ^ opad) || md)
* re-form K0
*/
for (i = 0; i < c->blk_len; i++) {
c->k0[i] ^= (0x36 ^ 0x5c);
}
if ((result = ntru_crypto_hash_final(&c->hash_ctx, md)) ||
(result = ntru_crypto_hash_init(&c->hash_ctx)) ||
(result = ntru_crypto_hash_update(&c->hash_ctx, c->k0, c->blk_len)) ||
(result = ntru_crypto_hash_update(&c->hash_ctx, md, c->md_len)) ||
(result = ntru_crypto_hash_final(&c->hash_ctx, md))) {
}
for (i = 0; i < c->blk_len; i++) {
c->k0[i] ^= 0x5c;
}
return result;
}

View File

@@ -0,0 +1,169 @@
/******************************************************************************
* NTRU Cryptography Reference Source Code
*
* Copyright (C) 2009-2016 Security Innovation (SI)
*
* SI has dedicated the work to the public domain by waiving all of its rights
* to the work worldwide under copyright law, including all related and
* neighboring rights, to the extent allowed by law.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* You can copy, modify, distribute and perform the work, even for commercial
* purposes, all without asking permission. You should have received a copy of
* the creative commons license (CC0 1.0 universal) along with this program.
* See the license file for more information.
*
*
*********************************************************************************/
/******************************************************************************
*
* File: ntru_crypto_hmac.h
*
* Contents: Definitions and declarations for the HMAC implementation.
*
*****************************************************************************/
#ifndef NTRU_CRYPTO_HMAC_H
#define NTRU_CRYPTO_HMAC_H
#include "ntru_crypto_platform.h"
#include "ntru_crypto_hash.h"
/***************
* error codes *
***************/
#define NTRU_CRYPTO_HMAC_OK ((uint32_t) NTRU_CRYPTO_HASH_OK)
#define NTRU_CRYPTO_HMAC_BAD_PARAMETER ((uint32_t) NTRU_CRYPTO_HASH_BAD_PARAMETER)
#define NTRU_CRYPTO_HMAC_BAD_ALG ((uint32_t) NTRU_CRYPTO_HASH_BAD_ALG)
#define NTRU_CRYPTO_HMAC_OUT_OF_MEMORY ((uint32_t) NTRU_CRYPTO_HASH_OUT_OF_MEMORY)
#define HMAC_RESULT(e) ((uint32_t)((e) ? HMAC_ERROR_BASE + (e) : (e)))
#define HMAC_RET(e) return HMAC_RESULT(e)
/*************************
* structure definitions *
*************************/
/* HMAC context structure */
struct _NTRU_CRYPTO_HMAC_CTX; /* opaque forward reference */
typedef struct _NTRU_CRYPTO_HMAC_CTX NTRU_CRYPTO_HMAC_CTX;
/*************************
* function declarations *
*************************/
/* ntru_crypto_hmac_create_ctx
*
* This routine creates an HMAC context, setting the hash algorithm and
* the key to be used.
*
* Returns NTRU_CRYPTO_HASH_OK if successful.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HASH_OUT_OF_MEMORY if memory cannot be allocated.
*/
extern uint32_t
ntru_crypto_hmac_create_ctx(
NTRU_CRYPTO_HASH_ALGID algid, /* in - the hash algorithm to be used */
uint8_t const *key, /* in - pointer to the HMAC key */
uint32_t key_len, /* in - number of bytes in HMAC key */
NTRU_CRYPTO_HMAC_CTX **c); /* out - address for pointer to HMAC
context */
/* ntru_crypto_hmac_destroy_ctx
*
* Destroys an HMAC context.
*
* Returns NTRU_CRYPTO_HASH_OK if successful.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
extern uint32_t
ntru_crypto_hmac_destroy_ctx(
NTRU_CRYPTO_HMAC_CTX *c); /* in/out - pointer to HMAC context */
/* ntru_crypto_hmac_get_md_len
*
* This routine gets the digest length of the HMAC.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
extern uint32_t
ntru_crypto_hmac_get_md_len(
NTRU_CRYPTO_HMAC_CTX const *c, /* in - pointer to HMAC context */
uint16_t *md_len); /* out - address for digest length */
/* ntru_crypto_hmac_set_key
*
* This routine sets a digest-length key into the HMAC context.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
extern uint32_t
ntru_crypto_hmac_set_key(
NTRU_CRYPTO_HMAC_CTX *c, /* in - pointer to HMAC context */
uint8_t const *key); /* in - pointer to new HMAC key */
/* ntru_crypto_hmac_init
*
* This routine performs standard initialization of the HMAC state.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
extern uint32_t
ntru_crypto_hmac_init(
NTRU_CRYPTO_HMAC_CTX *c); /* in/out - pointer to HMAC context */
/* ntru_crypto_hmac_update
*
* This routine processes input data and updates the HMAC hash calculation.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
* Returns NTRU_CRYPTO_HMAC_OVERFLOW if more than bytes are hashed than the underlying
* hash algorithm can handle.
*/
extern uint32_t
ntru_crypto_hmac_update(
NTRU_CRYPTO_HMAC_CTX *c, /* in/out - pointer to HMAC context */
uint8_t const *data, /* in - pointer to input data */
uint32_t data_len); /* in - no. of bytes of input data */
/* ntru_crypto_hmac_final
*
* This routine completes the HMAC hash calculation and returns the
* message digest.
*
* Returns NTRU_CRYPTO_HMAC_OK on success.
* Returns NTRU_CRYPTO_HMAC_FAIL with corrupted context.
* Returns NTRU_CRYPTO_HMAC_BAD_PARAMETER if inappropriate NULL pointers are
* passed.
*/
extern uint32_t
ntru_crypto_hmac_final(
NTRU_CRYPTO_HMAC_CTX *c, /* in/out - pointer to HMAC context */
uint8_t *md); /* out - address for message digest */
#endif /* NTRU_CRYPTO_HMAC_H */

Some files were not shown because too many files have changed in this diff Show More