mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-12-06 00:01:28 -05:00
Master rm kex (#402)
* Remove kex_ntru from master (issue #370). * Remove KEX components (issue #372). * Remove anything kex * Tweaks to READMEs re: removal of KEX.
This commit is contained in:
parent
d6bfc7384c
commit
3dbd609e92
2
.gitignore
vendored
2
.gitignore
vendored
@ -37,12 +37,10 @@ tests/example_sig
|
||||
tests/speed_kem
|
||||
tests/speed_sig
|
||||
tests/test_kem
|
||||
tests/test_kex
|
||||
tests/test_sig
|
||||
tests/test_rand
|
||||
tests/test_aes
|
||||
tests/test_sha3
|
||||
tests/minimal_kex_oqs
|
||||
|
||||
#kat
|
||||
tests/kat_kem
|
||||
|
||||
@ -44,10 +44,6 @@ source $(dirname $0)/defs.sh
|
||||
enable_disable_str+=" --disable-aes-ni"
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_KEX_NTRU} == 0 ]];then
|
||||
enable_disable_str+=" --disable-kex-ntru"
|
||||
fi
|
||||
|
||||
if [[ ${ENABLE_SIG_PICNIC} == 0 ]];then
|
||||
enable_disable_str+=" --disable-sig-picnic"
|
||||
fi
|
||||
|
||||
@ -4,7 +4,7 @@ set -e
|
||||
|
||||
source $(dirname $0)/defs.sh
|
||||
|
||||
REGEX=' T [_]?(OQS|ntru|picnic|Keccak|.*SIKEp503|.*SIDHp503|.*SIKEp751|.*SIDHp751|.*shake128|.*shake256|rand_bytes|cpu_supports|uint64_from_char_array|uint64_to_char_array|print_hex|ntt_double|rec|aligned_alloc|aligned_free)'
|
||||
REGEX=' T [_]?(OQS|picnic|Keccak|.*SIKEp503|.*SIDHp503|.*SIKEp751|.*SIDHp751|.*shake128|.*shake256|rand_bytes|cpu_supports|uint64_from_char_array|uint64_to_char_array|print_hex|ntt_double|rec|aligned_alloc|aligned_free)'
|
||||
|
||||
# For catching errors, we have the first (otherwise superfluous) two lines below two make sure that the commands are being executed correctly
|
||||
NON_NAMESPACED=`nm -g .libs/liboqs.a`
|
||||
|
||||
12
Makefile.am
12
Makefile.am
@ -20,11 +20,6 @@ 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/kem/libkem.la
|
||||
liboqs_la_LIBADD += src/kex/libkex.la
|
||||
if ENABLE_KEX_NTRU
|
||||
liboqs_la_LIBADD += src/kex_ntru/libntru.la
|
||||
endif
|
||||
|
||||
liboqs_la_LIBADD += src/sig/libsig.la
|
||||
|
||||
if ENABLE_SIG_PICNIC
|
||||
@ -54,8 +49,6 @@ installheader_HEADERS=config.h \
|
||||
src/crypto/rand_urandom_chacha20/rand_urandom_chacha20.h \
|
||||
src/crypto/sha3/sha3.h \
|
||||
src/kem/kem.h \
|
||||
src/kex/kex.h \
|
||||
src/kex_ntru/kex_ntru.h \
|
||||
src/kem/bike/kem_bike.h \
|
||||
src/kem/frodokem/kem_frodokem.h \
|
||||
src/kem/sike/kem_sike.h \
|
||||
@ -71,7 +64,6 @@ else
|
||||
tests/example_kem
|
||||
tests/example_sig
|
||||
tests/test_kem
|
||||
tests/test_kex --quiet
|
||||
tests/test_rand --quiet
|
||||
tests/test_aes
|
||||
tests/test_sha3
|
||||
@ -98,8 +90,6 @@ links:
|
||||
cp -f src/kem/bike/kem_bike.h include/oqs
|
||||
cp -f src/kem/frodokem/kem_frodokem.h include/oqs
|
||||
cp -f src/kem/sike/kem_sike.h include/oqs
|
||||
cp -f src/kex/kex.h include/oqs
|
||||
cp -f src/kex_ntru/kex_ntru.h include/oqs
|
||||
cp -f src/sig/sig.h include/oqs
|
||||
cp -f src/sig/picnic/sig_picnic.h include/oqs
|
||||
cp -f src/sig/qtesla/sig_qtesla.h include/oqs
|
||||
@ -108,7 +98,7 @@ clean-local:
|
||||
rm -rf include
|
||||
|
||||
clean-tests:
|
||||
rm -f tests/example_kem tests/example_sig tests/speed_kem tests/speed_sig tests/test_kem tests/minimal_kex_oqs tests/test_kex tests/test_sig tests/test_rand tests/test_aes tests/test_sha3
|
||||
rm -f tests/example_kem tests/example_sig tests/speed_kem tests/speed_sig tests/test_kem tests/test_sig tests/test_rand tests/test_aes tests/test_sha3
|
||||
|
||||
clean-kats:
|
||||
rm -rf tests/kat_kem kat_kem_rsp/
|
||||
|
||||
17
README.md
17
README.md
@ -80,11 +80,6 @@ Lifecycle for master branch
|
||||
|
||||
**API stability:** The public API of liboqs master branch is currently considered to be the functions in `oqs/common.h`, `oqs/config.h`, `oqs/kem.h`, and `oqs/rand.h`. Incompatible changes to the public API will lead to incrementing $X$ in version $X.Y.Z$. (`oqs/sig.h` will eventually be part of the public API, but is currently under development, and no promises are made about its API stability at present.)
|
||||
|
||||
Some aspects of liboqs master branch are currently in transition:
|
||||
|
||||
- All key exchange (KEX) algorithms will be removed; some will be replaced with key encapsulation mechanisms (KEMs), others will not be replaced.
|
||||
- The signature API will be modified to be closer to the API used on liboqs nist-branch
|
||||
|
||||
Building and running liboqs master branch
|
||||
-----------------------------------------
|
||||
|
||||
@ -130,26 +125,14 @@ The main build result is `liboqs.a`, a static library. (This may be placed in t
|
||||
There are also a variety of test programs built under the `tests` directory:
|
||||
|
||||
- `test_kem`: Simple test harness for all enabled key encapsulation mechanisms
|
||||
- `test_kem`: Simple test harness for all enabled key exchange algorithms
|
||||
- `test_sig`: Simple test harness for all enabled key signature schemes
|
||||
- `kat_kem`: Program that generates known answer test (KAT) values for all enabled key encapsulation mechanisms using the same mechanism as the NIST submission requirements, for checking against submitted KAT values
|
||||
- `speed_kem`: Benchmarking program for key encapsulation mechanisms; see `./speed_kem --help` for usage instructions
|
||||
- `speed_sig`: Benchmarking program for signature mechanisms; see `./speed_sig --help` for usage instructions
|
||||
- `example_kem`: Minimal runnable example showing the usage of the KEM API
|
||||
- `example_sig`: Minimal runnable example showing the usage of the signature API
|
||||
- `minimal_kex_oqs`: Minimal runnable example showing the usage of the kex exchange API (to be removed)
|
||||
- `test_aes`, `test_rand`, `test_sha3`: Simple test harnesses for crypto sub-components
|
||||
|
||||
#### Memory benchmarks
|
||||
|
||||
To run one or more ciphers only once use `--mem-bench`, which is suitable for memory usage profiling:
|
||||
|
||||
tests/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
|
||||
|
||||
Building and running on Windows
|
||||
-------------------------------
|
||||
|
||||
|
||||
@ -12,12 +12,6 @@ EXPORTS
|
||||
OQS_RAND_n
|
||||
OQS_RAND_test_record_occurrence
|
||||
OQS_RAND_report_statistics
|
||||
OQS_KEX_new
|
||||
OQS_KEX_alice_0
|
||||
OQS_KEX_bob
|
||||
OQS_KEX_alice_1
|
||||
OQS_KEX_alice_priv_free
|
||||
OQS_KEX_free
|
||||
OQS_SIG_new
|
||||
OQS_SIG_keygen
|
||||
OQS_SIG_sign
|
||||
|
||||
@ -264,8 +264,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -301,8 +299,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -338,8 +334,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -382,8 +376,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -425,8 +417,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -466,8 +456,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -507,8 +495,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
@ -555,8 +541,6 @@ copy "$(SolutionDir)..\src\kem\kem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\bike\kem_bike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\frodokem\kem_frodokem.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kem\sike\kem_sike.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex\kex.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\kex_ntru\kex_ntru.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\sig.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\picnic\sig_picnic.h" "$(SolutionDir)include\oqs\"
|
||||
copy "$(SolutionDir)..\src\sig\qtesla\sig_qtesla.h" "$(SolutionDir)include\oqs\"</Command>
|
||||
|
||||
@ -46,9 +46,6 @@ AC_DEFUN([CONFIG_FEATURE_FLAGS],
|
||||
ARG_DISBL_SET_WRAP([kem-frodokem], [kem_frodokem], [ENABLE_KEM_FRODOKEM], [src/kem/frodokem])
|
||||
ARG_DISBL_SET_WRAP([kem-sike], [kem_sike], [ENABLE_KEM_SIKE], [src/kem/sike])
|
||||
|
||||
ARG_DISBL_SET_WRAP([kex-ntru], [kex_ntru],
|
||||
[ENABLE_KEX_NTRU], [src/kex_ntru])
|
||||
|
||||
ARG_DISBL_SET_WRAP([sig-picnic], [sig_picnic],
|
||||
[ENABLE_SIG_PICNIC], [src/sig/picnic])
|
||||
ARG_DISBL_SET_WRAP([sig-qtesla], [sig_qtesla],
|
||||
|
||||
@ -45,7 +45,6 @@ SRCDIR=${SRCDIR}" src/crypto/aes \
|
||||
|
||||
# Protocols
|
||||
SRCDIR=${SRCDIR}" src/kem \
|
||||
src/kex \
|
||||
src/sig"
|
||||
|
||||
#Set the default compilation flags
|
||||
@ -55,12 +54,10 @@ AC_SUBST(SRCDIR)
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/common/Makefile
|
||||
src/kem/Makefile
|
||||
src/kex/Makefile
|
||||
src/crypto/sha3/Makefile
|
||||
src/crypto/rand_urandom_chacha20/Makefile
|
||||
src/crypto/rand_urandom_aesctr/Makefile
|
||||
src/crypto/aes/Makefile
|
||||
src/kex_ntru/Makefile
|
||||
src/sig/Makefile
|
||||
src/sig/picnic/Makefile
|
||||
src/sig/qtesla/Makefile
|
||||
|
||||
@ -874,9 +874,7 @@ RECURSIVE = NO
|
||||
# Note that relative paths are relative to the directory from which doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE = include/oqs/kex.h \
|
||||
include/oqs/kex_ntru.h \
|
||||
include/oqs/rand_urandom_aesctr.h \
|
||||
EXCLUDE = include/oqs/rand_urandom_aesctr.h \
|
||||
include/oqs/rand_urandom_chacha20.h
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
|
||||
@ -6,7 +6,7 @@ Summary
|
||||
|
||||
- **Name**: SIDH
|
||||
- **Algorithm type**: key exchange
|
||||
- **Note**: SIDH is as ephemeral KEX related to the SIKE KEM (sike.org) submitted to NIST
|
||||
- **Note**: SIDH is as ephemeral key exchange algorithm related to the SIKE KEM (sike.org) submitted to NIST. It is NOT secure to use it with static keys.
|
||||
- **Main cryptographic assumption**: (supersingular) isogeny walk problem
|
||||
- **Submitters' website**: https://github.com/Microsoft/PQCrypto-SIDH
|
||||
- **Added to liboqs by**: Christian Paquin
|
||||
@ -31,4 +31,4 @@ Implementation
|
||||
Additional comments
|
||||
-------------------
|
||||
|
||||
No KAT are available for SIDH.
|
||||
No KAT are available for SIDH.
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
#!/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
|
||||
|
||||
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
noinst_LTLIBRARIES = libkex.la
|
||||
libkex_la_SOURCES = kex.c
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include <oqs/kex.h>
|
||||
|
||||
#include <oqs/kex_ntru.h>
|
||||
|
||||
#define UNUSED_KEX(expr) \
|
||||
do { \
|
||||
(void) (expr); \
|
||||
} while (0)
|
||||
|
||||
OQS_API 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_KEX(seed);
|
||||
UNUSED_KEX(seed_len);
|
||||
UNUSED_KEX(named_parameters);
|
||||
|
||||
switch (alg_name) {
|
||||
case OQS_KEX_alg_default:
|
||||
return NULL;
|
||||
|
||||
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
|
||||
case OQS_KEX_alg_ntru:
|
||||
#ifdef ENABLE_KEX_NTRU
|
||||
return OQS_KEX_ntru_new(rand);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OQS_API OQS_STATUS OQS_KEX_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
|
||||
if (k == NULL) {
|
||||
return OQS_ERROR;
|
||||
} else {
|
||||
return k->alice_0(k, alice_priv, alice_msg, alice_msg_len);
|
||||
}
|
||||
}
|
||||
|
||||
OQS_API OQS_STATUS 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 OQS_ERROR;
|
||||
} else {
|
||||
return k->bob(k, alice_msg, alice_msg_len, bob_msg, bob_msg_len, key, key_len);
|
||||
}
|
||||
}
|
||||
|
||||
OQS_API OQS_STATUS 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 OQS_ERROR;
|
||||
} else {
|
||||
return k->alice_1(k, alice_priv, bob_msg, bob_msg_len, key, key_len);
|
||||
}
|
||||
}
|
||||
|
||||
OQS_API void OQS_KEX_alice_priv_free(OQS_KEX *k, void *alice_priv) {
|
||||
if (k) {
|
||||
k->alice_priv_free(k, alice_priv);
|
||||
}
|
||||
}
|
||||
|
||||
OQS_API void OQS_KEX_free(OQS_KEX *k) {
|
||||
if (k) {
|
||||
k->free(k); // IGNORE free-check
|
||||
}
|
||||
}
|
||||
160
src/kex/kex.h
160
src/kex/kex.h
@ -1,160 +0,0 @@
|
||||
/**
|
||||
* \file kex.h
|
||||
* \brief Header defining the API for generic OQS Key exchange
|
||||
* \deprecated Expected removal Sep. 2018
|
||||
*/
|
||||
|
||||
#ifndef __OQS_KEX_H
|
||||
#define __OQS_KEX_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <oqs/common.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <oqs/winconfig.h>
|
||||
#else
|
||||
#include <oqs/config.h>
|
||||
#endif
|
||||
|
||||
enum OQS_KEX_alg_name {
|
||||
OQS_KEX_alg_default,
|
||||
OQS_KEX_alg_ntru,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
const 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 OQS_SUCCESS on success, or OQS_ERROR on failure
|
||||
*/
|
||||
OQS_STATUS(*alice_0)
|
||||
(struct 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 OQS_SUCCESS on success, or OQS_ERROR on failure
|
||||
*/
|
||||
OQS_STATUS(*bob)
|
||||
(struct 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 OQS_SUCCESS on success, or OQS_ERROR on failure
|
||||
*/
|
||||
OQS_STATUS(*alice_1)
|
||||
(struct 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)(struct OQS_KEX *k, void *alice_priv);
|
||||
|
||||
/**
|
||||
* Pointer to a function for freeing the allocated key exchange structure
|
||||
*
|
||||
* @param k Key exchange structure
|
||||
*/
|
||||
void (*free)(struct 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_API 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);
|
||||
|
||||
OQS_API OQS_STATUS OQS_KEX_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
|
||||
|
||||
OQS_API OQS_STATUS 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);
|
||||
|
||||
OQS_API OQS_STATUS 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);
|
||||
|
||||
OQS_API void OQS_KEX_alice_priv_free(OQS_KEX *k, void *alice_priv);
|
||||
OQS_API void OQS_KEX_free(OQS_KEX *k);
|
||||
|
||||
#endif
|
||||
@ -1,19 +0,0 @@
|
||||
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
|
||||
@ -1,236 +0,0 @@
|
||||
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
|
||||
|
||||
#include <fcntl.h>
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <Wincrypt.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <oqs/common.h>
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/kex_ntru.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
#define HAVE_BOOL
|
||||
#include <ntru_crypto.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define strdup _strdup // for strdup deprecation warning
|
||||
#endif
|
||||
|
||||
#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; // IGNORE free-check
|
||||
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) != OQS_SUCCESS) {
|
||||
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;
|
||||
|
||||
OQS_STATUS OQS_KEX_ntru_alice_0(UNUSED OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len) {
|
||||
|
||||
OQS_STATUS ret = OQS_ERROR;
|
||||
uint32_t rc;
|
||||
DRBG_HANDLE drbg;
|
||||
OQS_KEX_ntru_alice_priv *ntru_alice_priv = NULL;
|
||||
|
||||
*alice_priv = NULL;
|
||||
*alice_msg = 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)
|
||||
return OQS_ERROR;
|
||||
|
||||
/* allocate private key */
|
||||
ntru_alice_priv = malloc(sizeof(OQS_KEX_ntru_alice_priv));
|
||||
if (ntru_alice_priv == NULL)
|
||||
goto err;
|
||||
ntru_alice_priv->priv_key = NULL;
|
||||
*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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
ret = OQS_ERROR;
|
||||
if (ntru_alice_priv != NULL)
|
||||
OQS_MEM_secure_free(ntru_alice_priv->priv_key, ntru_alice_priv->priv_key_len);
|
||||
OQS_MEM_insecure_free(ntru_alice_priv);
|
||||
*alice_priv = NULL;
|
||||
OQS_MEM_insecure_free(*alice_msg);
|
||||
*alice_msg = NULL;
|
||||
cleanup:
|
||||
ntru_crypto_drbg_uninstantiate(drbg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OQS_STATUS 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) {
|
||||
|
||||
OQS_STATUS 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)
|
||||
return OQS_ERROR;
|
||||
|
||||
/* 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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
ret = OQS_ERROR;
|
||||
OQS_MEM_insecure_free(*bob_msg);
|
||||
*bob_msg = NULL;
|
||||
OQS_MEM_secure_free(*key, *key_len);
|
||||
*key = NULL;
|
||||
cleanup:
|
||||
ntru_crypto_drbg_uninstantiate(drbg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
OQS_STATUS 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) {
|
||||
|
||||
OQS_STATUS 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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
ret = OQS_ERROR;
|
||||
OQS_MEM_secure_free(*key, *key_len);
|
||||
*key = NULL;
|
||||
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;
|
||||
OQS_MEM_secure_free(ntru_alice_priv->priv_key, ntru_alice_priv->priv_key_len);
|
||||
}
|
||||
}
|
||||
|
||||
void OQS_KEX_ntru_free(OQS_KEX *k) {
|
||||
if (k)
|
||||
OQS_MEM_insecure_free(k->method_name);
|
||||
OQS_MEM_insecure_free(k);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,30 +0,0 @@
|
||||
/**
|
||||
* \file kex_ntru.h
|
||||
* \brief Header for the NTRU implementation of OQS_KEX
|
||||
* \deprecated Expected removal Sep. 2018
|
||||
*/
|
||||
|
||||
#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/common.h>
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
OQS_KEX *OQS_KEX_ntru_new(OQS_RAND *rand);
|
||||
|
||||
OQS_STATUS OQS_KEX_ntru_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
|
||||
OQS_STATUS 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);
|
||||
OQS_STATUS 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
|
||||
@ -1,340 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,850 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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"
|
||||
#include <oqs/common.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) {
|
||||
OQS_MEM_secure_free(s, sizeof(SHA256_HMAC_DRBG_STATE));
|
||||
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));
|
||||
OQS_MEM_secure_free(s, sizeof(SHA256_HMAC_DRBG_STATE));
|
||||
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;
|
||||
OQS_MEM_secure_free(s, sizeof(SHA256_HMAC_DRBG_STATE));
|
||||
}
|
||||
|
||||
/* 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:
|
||||
OQS_MEM_secure_free(drbg->state, sizeof(EXTERNAL_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);
|
||||
}
|
||||
}
|
||||
@ -1,208 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,42 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,307 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
@ -1,201 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,67 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,319 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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;
|
||||
}
|
||||
@ -1,169 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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 */
|
||||
@ -1,86 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_msbyte_uint32.c
|
||||
*
|
||||
* Contents: Routines to convert between an array of bytes in network byte
|
||||
* order (most-significant byte first) and an array of uint32 words.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_msbyte_uint32.h"
|
||||
|
||||
/* ntru_crypto_msbyte_2_uint32()
|
||||
*
|
||||
* This routine converts an array of bytes in network byte order to an array
|
||||
* of uint32_t, placing the first byte in the most significant byte of the
|
||||
* first uint32_t word.
|
||||
*
|
||||
* The number of bytes in the input stream MUST be at least 4 times the
|
||||
* number of words expected in the output array.
|
||||
*/
|
||||
|
||||
void ntru_crypto_msbyte_2_uint32(
|
||||
uint32_t *words, /* out - pointer to the output uint32_t array */
|
||||
uint8_t const *bytes, /* in - pointer to the input byte array */
|
||||
uint32_t n) /* in - number of words in the output array */
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
words[i] = ((uint32_t)(*bytes++)) << 24;
|
||||
words[i] |= ((uint32_t)(*bytes++)) << 16;
|
||||
words[i] |= ((uint32_t)(*bytes++)) << 8;
|
||||
words[i] |= (uint32_t)(*bytes++);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_crypto_uint32_2_msbyte()
|
||||
*
|
||||
* This routine converts an array of uint32_t to an array of bytes in
|
||||
* network byte order, placing the most significant byte of the first uint32_t
|
||||
* word as the first byte of the output array.
|
||||
*
|
||||
* The number of bytes in the output stream will be 4 times the number of words
|
||||
* specified in the input array.
|
||||
*/
|
||||
|
||||
void ntru_crypto_uint32_2_msbyte(
|
||||
uint8_t *bytes, /* out - pointer to the output byte array */
|
||||
uint32_t const *words, /* in - pointer to the input uint32_t array */
|
||||
uint32_t n) /* in - number of words in the input array */
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
*bytes++ = (uint8_t)(words[i] >> 24);
|
||||
*bytes++ = (uint8_t)(words[i] >> 16);
|
||||
*bytes++ = (uint8_t)(words[i] >> 8);
|
||||
*bytes++ = (uint8_t)(words[i]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_msbyte_uint32.h
|
||||
*
|
||||
* Contents: Definitions and declarations for converting between a most-
|
||||
* significant-first byte stream and a uint32_t array.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_MSBYTE_UINT32_H
|
||||
#define NTRU_CRYPTO_MSBYTE_UINT32_H
|
||||
|
||||
#include "ntru_crypto_platform.h"
|
||||
|
||||
/* ntru_crypto_msbyte_2_uint32()
|
||||
*
|
||||
* This routine converts an array of bytes in network byte order to an array
|
||||
* of uint32_t, placing the first byte in the most significant byte of the
|
||||
* first uint32_t word.
|
||||
*
|
||||
* The number of bytes in the input stream MUST be at least 4 times the
|
||||
* number of words expected in the output array.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_crypto_msbyte_2_uint32(
|
||||
uint32_t *words, /* out - pointer to the output uint32_t array */
|
||||
uint8_t const *bytes, /* in - pointer to the input byte array */
|
||||
uint32_t n); /* in - number of words in the output array */
|
||||
|
||||
/* ntru_crypto_uint32_2_msbyte()
|
||||
*
|
||||
* This routine converts an array of uint32_t to an array of bytes in
|
||||
* network byte order, placing the most significant byte of the first uint32_t
|
||||
* word as the first byte of the output array.
|
||||
*
|
||||
* The number of bytes in the output stream will be 4 times the number of words
|
||||
* specified in the input array.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_crypto_uint32_2_msbyte(
|
||||
uint8_t *bytes, /* out - pointer to the output byte array */
|
||||
uint32_t const *words, /* in - pointer to the input uint32_t array */
|
||||
uint32_t n); /* in - number of words in the input array */
|
||||
|
||||
#endif /* NTRU_CRYPTO_MSBYTE_UINT32_H */
|
||||
@ -1,556 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_convert.c
|
||||
*
|
||||
* Contents: Conversion routines for NTRUEncrypt, including packing, unpacking,
|
||||
* and others.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_convert.h"
|
||||
|
||||
/* 3-bit to 2-trit conversion tables: 2 represents -1 */
|
||||
|
||||
static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2};
|
||||
static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1};
|
||||
|
||||
/* ntru_bits_2_trits
|
||||
*
|
||||
* Each 3 bits in an array of octets is converted to 2 trits in an array
|
||||
* of trits.
|
||||
*
|
||||
* The octet array may overlap the end of the trit array.
|
||||
*/
|
||||
|
||||
void ntru_bits_2_trits(
|
||||
uint8_t const *octets, /* in - pointer to array of octets */
|
||||
uint16_t num_trits, /* in - number of trits to produce */
|
||||
uint8_t *trits) /* out - address for array of trits */
|
||||
{
|
||||
uint32_t bits24;
|
||||
uint32_t bits3;
|
||||
uint32_t shift;
|
||||
|
||||
while (num_trits >= 16) {
|
||||
/* get next three octets */
|
||||
|
||||
bits24 = ((uint32_t)(*octets++)) << 16;
|
||||
bits24 |= ((uint32_t)(*octets++)) << 8;
|
||||
bits24 |= (uint32_t)(*octets++);
|
||||
|
||||
/* for each 3 bits in the three octets, output 2 trits */
|
||||
|
||||
bits3 = (bits24 >> 21) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 18) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 15) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 12) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 9) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 6) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = (bits24 >> 3) & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
bits3 = bits24 & 0x7;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
|
||||
num_trits -= 16;
|
||||
}
|
||||
|
||||
if (num_trits == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get three octets */
|
||||
|
||||
bits24 = ((uint32_t)(*octets++)) << 16;
|
||||
bits24 |= ((uint32_t)(*octets++)) << 8;
|
||||
bits24 |= (uint32_t)(*octets++);
|
||||
|
||||
shift = 21;
|
||||
while (num_trits) {
|
||||
/* for each 3 bits in the three octets, output up to 2 trits
|
||||
* until all trits needed are produced
|
||||
*/
|
||||
|
||||
bits3 = (bits24 >> shift) & 0x7;
|
||||
shift -= 3;
|
||||
*trits++ = bits_2_trit1[bits3];
|
||||
|
||||
if (--num_trits) {
|
||||
*trits++ = bits_2_trit2[bits3];
|
||||
--num_trits;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_trits_2_bits
|
||||
*
|
||||
* Each 2 trits in an array of trits is converted to 3 bits, and the bits
|
||||
* are packed in an array of octets. A multiple of 3 octets is output.
|
||||
* Any bits in the final octets not derived from trits are zero.
|
||||
*
|
||||
* Returns TRUE if all trits were valid.
|
||||
* Returns FALSE if invalid trits were found.
|
||||
*/
|
||||
|
||||
bool ntru_trits_2_bits(
|
||||
uint8_t const *trits, /* in - pointer to array of trits */
|
||||
uint32_t num_trits, /* in - number of trits to convert */
|
||||
uint8_t *octets) /* out - address for array of octets */
|
||||
{
|
||||
bool all_trits_valid = TRUE;
|
||||
uint32_t bits24;
|
||||
uint32_t bits3;
|
||||
uint32_t shift;
|
||||
|
||||
while (num_trits >= 16) {
|
||||
|
||||
/* convert each 2 trits to 3 bits and pack */
|
||||
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 = (bits3 << 21);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 18);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 15);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 12);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 9);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 6);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << 3);
|
||||
bits3 = *trits++ * 3;
|
||||
bits3 += *trits++;
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= bits3;
|
||||
num_trits -= 16;
|
||||
|
||||
/* output three octets */
|
||||
|
||||
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
||||
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
||||
*octets++ = (uint8_t)(bits24 & 0xff);
|
||||
}
|
||||
|
||||
bits24 = 0;
|
||||
shift = 21;
|
||||
|
||||
while (num_trits) {
|
||||
|
||||
/* convert each 2 trits to 3 bits and pack */
|
||||
|
||||
bits3 = *trits++ * 3;
|
||||
|
||||
if (--num_trits) {
|
||||
bits3 += *trits++;
|
||||
--num_trits;
|
||||
}
|
||||
|
||||
if (bits3 > 7) {
|
||||
bits3 = 7;
|
||||
all_trits_valid = FALSE;
|
||||
}
|
||||
|
||||
bits24 |= (bits3 << shift);
|
||||
shift -= 3;
|
||||
}
|
||||
|
||||
/* output three octets */
|
||||
|
||||
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
||||
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
||||
*octets++ = (uint8_t)(bits24 & 0xff);
|
||||
|
||||
return all_trits_valid;
|
||||
}
|
||||
|
||||
/* ntru_coeffs_mod4_2_octets
|
||||
*
|
||||
* Takes an array of ring element coefficients mod 4 and packs the
|
||||
* results into an octet string.
|
||||
*/
|
||||
|
||||
void ntru_coeffs_mod4_2_octets(
|
||||
uint16_t num_coeffs, /* in - number of coefficients */
|
||||
uint16_t const *coeffs, /* in - pointer to coefficients */
|
||||
uint8_t *octets) /* out - address for octets */
|
||||
{
|
||||
uint8_t bits2;
|
||||
int shift;
|
||||
uint16_t i;
|
||||
|
||||
*octets = 0;
|
||||
shift = 6;
|
||||
for (i = 0; i < num_coeffs; i++) {
|
||||
bits2 = (uint8_t)(coeffs[i] & 0x3);
|
||||
*octets |= bits2 << shift;
|
||||
shift -= 2;
|
||||
|
||||
if (shift < 0) {
|
||||
++octets;
|
||||
*octets = 0;
|
||||
shift = 6;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_trits_2_octet
|
||||
*
|
||||
* Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
|
||||
*/
|
||||
|
||||
void ntru_trits_2_octet(
|
||||
uint8_t const *trits, /* in - pointer to trits */
|
||||
uint8_t *octet) /* out - address for octet */
|
||||
{
|
||||
int i;
|
||||
|
||||
*octet = 0;
|
||||
for (i = 4; i >= 0; i--) {
|
||||
*octet = (*octet * 3) + trits[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_octet_2_trits
|
||||
*
|
||||
* Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
|
||||
*/
|
||||
|
||||
void ntru_octet_2_trits(
|
||||
uint8_t octet, /* in - octet to be unpacked */
|
||||
uint8_t *trits) /* out - address for trits */
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
trits[i] = octet % 3;
|
||||
octet = (octet - trits[i]) / 3;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_indices_2_trits
|
||||
*
|
||||
* Converts a list of the nonzero indices of a polynomial into an array of
|
||||
* trits.
|
||||
*/
|
||||
|
||||
void ntru_indices_2_trits(
|
||||
uint16_t in_len, /* in - no. of indices */
|
||||
uint16_t const *in, /* in - pointer to list of indices */
|
||||
bool plus1, /* in - if list is +1 cofficients */
|
||||
uint8_t *out) /* out - address of output polynomial */
|
||||
{
|
||||
uint8_t trit = plus1 ? 1 : 2;
|
||||
uint16_t i;
|
||||
|
||||
for (i = 0; i < in_len; i++) {
|
||||
out[in[i]] = trit;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_packed_trits_2_indices
|
||||
*
|
||||
* Unpacks an array of N trits and creates a list of array indices
|
||||
* corresponding to trits = +1, and list of array indices corresponding to
|
||||
* trits = -1.
|
||||
*/
|
||||
|
||||
void ntru_packed_trits_2_indices(
|
||||
uint8_t const *in, /* in - pointer to packed-trit octets */
|
||||
uint16_t num_trits, /* in - no. of packed trits */
|
||||
uint16_t *indices_plus1, /* out - address for indices of +1 trits */
|
||||
uint16_t *indices_minus1) /* out - address for indices of -1 trits */
|
||||
{
|
||||
uint8_t trits[5];
|
||||
uint16_t i = 0;
|
||||
int j;
|
||||
|
||||
while (num_trits >= 5) {
|
||||
ntru_octet_2_trits(*in++, trits);
|
||||
num_trits -= 5;
|
||||
|
||||
for (j = 0; j < 5; j++, i++) {
|
||||
if (trits[j] == 1) {
|
||||
*indices_plus1 = i;
|
||||
++indices_plus1;
|
||||
} else if (trits[j] == 2) {
|
||||
*indices_minus1 = i;
|
||||
++indices_minus1;
|
||||
} else {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_trits) {
|
||||
ntru_octet_2_trits(*in, trits);
|
||||
|
||||
for (j = 0; num_trits && (j < 5); j++, i++) {
|
||||
if (trits[j] == 1) {
|
||||
*indices_plus1 = i;
|
||||
++indices_plus1;
|
||||
} else if (trits[j] == 2) {
|
||||
*indices_minus1 = i;
|
||||
++indices_minus1;
|
||||
} else {
|
||||
;
|
||||
}
|
||||
|
||||
--num_trits;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_indices_2_packed_trits
|
||||
*
|
||||
* Takes a list of array indices corresponding to elements whose values
|
||||
* are +1 or -1, and packs the N-element array of trits described by these
|
||||
* lists into octets, 5 trits per octet.
|
||||
*/
|
||||
|
||||
void ntru_indices_2_packed_trits(
|
||||
uint16_t const *indices, /* in - pointer to indices */
|
||||
uint16_t num_plus1, /* in - no. of indices for +1 trits */
|
||||
uint16_t num_minus1, /* in - no. of indices for -1 trits */
|
||||
uint16_t num_trits, /* in - N, no. of trits in array */
|
||||
uint8_t *buf, /* in - temp buf, N octets */
|
||||
uint8_t *out) /* out - address for packed octets */
|
||||
{
|
||||
|
||||
/* convert indices to an array of trits */
|
||||
|
||||
memset(buf, 0, num_trits);
|
||||
ntru_indices_2_trits(num_plus1, indices, TRUE, buf);
|
||||
ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf);
|
||||
|
||||
/* pack the array of trits */
|
||||
|
||||
while (num_trits >= 5) {
|
||||
ntru_trits_2_octet(buf, out);
|
||||
num_trits -= 5;
|
||||
buf += 5;
|
||||
++out;
|
||||
}
|
||||
|
||||
if (num_trits) {
|
||||
uint8_t trits[5];
|
||||
|
||||
memcpy(trits, buf, num_trits);
|
||||
memset(trits + num_trits, 0, sizeof(trits) - num_trits);
|
||||
ntru_trits_2_octet(trits, out);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_elements_2_octets
|
||||
*
|
||||
* Packs an array of n-bit elements into an array of
|
||||
* ((in_len * n_bits) + 7) / 8 octets.
|
||||
* NOTE: Assumes 8 < n_bits < 16.
|
||||
*/
|
||||
|
||||
void ntru_elements_2_octets(
|
||||
uint16_t in_len, /* in - no. of elements to be packed */
|
||||
uint16_t const *in, /* in - ptr to elements to be packed */
|
||||
uint8_t n_bits, /* in - no. of bits in input element */
|
||||
uint8_t *out) /* out - addr for output octets */
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t shift;
|
||||
uint16_t i;
|
||||
|
||||
/* pack */
|
||||
|
||||
temp = 0;
|
||||
shift = n_bits - 8;
|
||||
i = 0;
|
||||
while (i < in_len) {
|
||||
/* add bits to temp to fill an octet and output the octet */
|
||||
temp |= in[i] >> shift;
|
||||
*out++ = (uint8_t)(temp & 0xff);
|
||||
if (shift > 8) {
|
||||
/* next full octet is in current input word */
|
||||
|
||||
shift = shift - 8;
|
||||
temp = 0;
|
||||
} else {
|
||||
shift = 8 - shift;
|
||||
/* put remaining bits of input word in temp as partial octet,
|
||||
* and increment index to next input word
|
||||
*/
|
||||
temp = in[i] << shift;
|
||||
shift = n_bits - shift;
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/* output any bits remaining in last input word */
|
||||
|
||||
if (shift != n_bits - 8) {
|
||||
*out++ = (uint8_t)(temp & 0xff);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_octets_2_elements
|
||||
*
|
||||
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
||||
* n-bit elements. Any extra bits are discarded.
|
||||
* NOTE: Assumes 8 < n_bits < 16.
|
||||
*/
|
||||
|
||||
void ntru_octets_2_elements(
|
||||
uint16_t in_len, /* in - no. of octets to be unpacked */
|
||||
uint8_t const *in, /* in - ptr to octets to be unpacked */
|
||||
uint8_t n_bits, /* in - no. of bits in output element */
|
||||
uint16_t *out) /* out - addr for output elements */
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t mask;
|
||||
uint16_t shift;
|
||||
uint16_t i;
|
||||
|
||||
/* unpack */
|
||||
|
||||
temp = 0;
|
||||
mask = (1 << n_bits) - 1;
|
||||
shift = n_bits;
|
||||
i = 0;
|
||||
|
||||
while (i < in_len) {
|
||||
if (shift > 8) {
|
||||
/* the current octet will not fill the current element */
|
||||
|
||||
shift = shift - 8;
|
||||
temp |= ((uint16_t) in[i]) << shift;
|
||||
} else {
|
||||
/* add bits from the current octet to fill the current element and
|
||||
* output the element
|
||||
*/
|
||||
|
||||
shift = 8 - shift;
|
||||
|
||||
temp |= ((uint16_t) in[i]) >> shift;
|
||||
*out++ = temp & mask;
|
||||
|
||||
/* add the remaining bits of the current octet to start an element */
|
||||
shift = n_bits - shift;
|
||||
temp = ((uint16_t) in[i]) << shift;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,167 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_convert.h
|
||||
*
|
||||
* Contents: Definitions and declarations for conversion routines
|
||||
* for NTRUEncrypt, including packing, unpacking and others.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_NTRU_CONVERT_H
|
||||
#define NTRU_CRYPTO_NTRU_CONVERT_H
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
|
||||
/* function declarations */
|
||||
|
||||
/* ntru_bits_2_trits
|
||||
*
|
||||
* Each 3 bits in an array of octets is converted to 2 trits in an array
|
||||
* of trits.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_bits_2_trits(
|
||||
uint8_t const *octets, /* in - pointer to array of octets */
|
||||
uint16_t num_trits, /* in - number of trits to produce */
|
||||
uint8_t *trits); /* out - address for array of trits */
|
||||
|
||||
/* ntru_trits_2_bits
|
||||
*
|
||||
* Each 2 trits in an array of trits is converted to 3 bits, and the bits
|
||||
* are packed in an array of octets. A multiple of 3 octets is output.
|
||||
* Any bits in the final octets not derived from trits are zero.
|
||||
*
|
||||
* Returns TRUE if all trits were valid.
|
||||
* Returns FALSE if invalid trits were found.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
ntru_trits_2_bits(
|
||||
uint8_t const *trits, /* in - pointer to array of trits */
|
||||
uint32_t num_trits, /* in - number of trits to convert */
|
||||
uint8_t *octets); /* out - address for array of octets */
|
||||
|
||||
/* ntru_coeffs_mod4_2_octets
|
||||
*
|
||||
* Takes an array of coefficients mod 4 and packs the results into an
|
||||
* octet string.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_coeffs_mod4_2_octets(
|
||||
uint16_t num_coeffs, /* in - number of coefficients */
|
||||
uint16_t const *coeffs, /* in - pointer to coefficients */
|
||||
uint8_t *octets); /* out - address for octets */
|
||||
|
||||
/* ntru_trits_2_octet
|
||||
*
|
||||
* Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_trits_2_octet(
|
||||
uint8_t const *trits, /* in - pointer to trits */
|
||||
uint8_t *octet); /* out - address for octet */
|
||||
|
||||
/* ntru_octet_2_trits
|
||||
*
|
||||
* Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_octet_2_trits(
|
||||
uint8_t octet, /* in - octet to be unpacked */
|
||||
uint8_t *trits); /* out - address for trits */
|
||||
|
||||
/* ntru_indices_2_trits
|
||||
*
|
||||
* Converts a list of the nonzero indices of a polynomial into an array of
|
||||
* trits.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_indices_2_trits(
|
||||
uint16_t in_len, /* in - no. of indices */
|
||||
uint16_t const *in, /* in - pointer to list of indices */
|
||||
bool plus1, /* in - if list is +1 coefficients */
|
||||
uint8_t *out); /* out - address of output polynomial */
|
||||
|
||||
/* ntru_packed_trits_2_indices
|
||||
*
|
||||
* Unpacks an array of N trits and creates a list of array indices
|
||||
* corresponding to trits = +1, and list of array indices corresponding to
|
||||
* trits = -1.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_packed_trits_2_indices(
|
||||
uint8_t const *in, /* in - pointer to packed-trit octets */
|
||||
uint16_t num_trits, /* in - no. of packed trits */
|
||||
uint16_t *indices_plus1, /* out - address for indices of +1 trits */
|
||||
uint16_t *indices_minus1); /* out - address for indices of -1 trits */
|
||||
|
||||
/* ntru_indices_2_packed_trits
|
||||
*
|
||||
* Takes a list of array indices corresponding to elements whose values
|
||||
* are +1 or -1, and packs the N-element array of trits described by these
|
||||
* lists into octets, 5 trits per octet.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_indices_2_packed_trits(
|
||||
uint16_t const *indices, /* in - pointer to indices */
|
||||
uint16_t num_plus1, /* in - no. of indices for +1 trits */
|
||||
uint16_t num_minus1, /* in - no. of indices for -1 trits */
|
||||
uint16_t num_trits, /* in - N, no. of trits in array */
|
||||
uint8_t *buf, /* in - temp buf, N octets */
|
||||
uint8_t *out); /* out - address for packed octets */
|
||||
|
||||
/* ntru_elements_2_octets
|
||||
*
|
||||
* Packs an array of n-bit elements into an array of
|
||||
* ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_elements_2_octets(
|
||||
uint16_t in_len, /* in - no. of elements to be packed */
|
||||
uint16_t const *in, /* in - ptr to elements to be packed */
|
||||
uint8_t n_bits, /* in - no. of bits in input element */
|
||||
uint8_t *out); /* out - addr for output octets */
|
||||
|
||||
/* ntru_octets_2_elements
|
||||
*
|
||||
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
||||
* n-bit elements, 8 < n < 16. Any extra bits are discarded.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_octets_2_elements(
|
||||
uint16_t in_len, /* in - no. of octets to be unpacked */
|
||||
uint8_t const *in, /* in - ptr to octets to be unpacked */
|
||||
uint8_t n_bits, /* in - no. of bits in output element */
|
||||
uint16_t *out); /* out - addr for output elements */
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_CONVERT_H */
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,392 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_encrypt_key.c
|
||||
*
|
||||
* Contents: Routines for exporting and importing public and private keys
|
||||
* for NTRUEncrypt.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_encrypt_key.h"
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_parse
|
||||
*
|
||||
* Parses an NTRUEncrypt key blob.
|
||||
* If the blob is not corrupt, returns packing types for public and private
|
||||
* keys, a pointer to the parameter set, a pointer to the public key, and
|
||||
* a pointer to the private key if it exists.
|
||||
*
|
||||
* Returns TRUE if successful.
|
||||
* Returns FALSE if the blob is invalid.
|
||||
*/
|
||||
|
||||
bool ntru_crypto_ntru_encrypt_key_parse(
|
||||
bool pubkey_parse, /* in - if parsing pubkey
|
||||
blob */
|
||||
uint16_t key_blob_len, /* in - no. octets in key
|
||||
blob */
|
||||
uint8_t const *key_blob, /* in - pointer to key blob */
|
||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
||||
packing type */
|
||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
||||
packing type */
|
||||
NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to
|
||||
parameter set */
|
||||
uint8_t const **pubkey, /* out - addr for ptr to
|
||||
packed pubkey */
|
||||
uint8_t const **privkey) /* out - addr for ptr to
|
||||
packed privkey */
|
||||
{
|
||||
uint8_t tag;
|
||||
|
||||
/* parse key blob based on tag */
|
||||
|
||||
tag = key_blob[0];
|
||||
switch (tag) {
|
||||
case NTRU_ENCRYPT_PUBKEY_TAG:
|
||||
|
||||
if (!pubkey_parse) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG:
|
||||
case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG:
|
||||
case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG:
|
||||
|
||||
if (pubkey_parse) {
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tag) {
|
||||
case NTRU_ENCRYPT_PUBKEY_TAG:
|
||||
case NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG:
|
||||
case NTRU_ENCRYPT_PRIVKEY_TRITS_TAG:
|
||||
case NTRU_ENCRYPT_PRIVKEY_INDICES_TAG:
|
||||
|
||||
/* Version 0:
|
||||
* byte 0: tag
|
||||
* byte 1: no. of octets in OID
|
||||
* bytes 2-4: OID
|
||||
* bytes 5- : packed pubkey
|
||||
* [packed privkey]
|
||||
*/
|
||||
|
||||
{
|
||||
NTRU_ENCRYPT_PARAM_SET *p = NULL;
|
||||
uint16_t pubkey_packed_len;
|
||||
|
||||
/* check OID length and minimum blob length for tag and OID */
|
||||
|
||||
if ((key_blob_len < 5) || (key_blob[1] != 3)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get a pointer to the parameter set corresponding to the OID */
|
||||
|
||||
if ((p = ntru_encrypt_get_params_with_OID(key_blob + 2)) == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check blob length and assign pointers to blob fields */
|
||||
|
||||
pubkey_packed_len = (p->N * p->q_bits + 7) / 8;
|
||||
|
||||
if (pubkey_parse) /* public-key parsing */
|
||||
{
|
||||
if (key_blob_len != 5 + pubkey_packed_len) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pubkey = key_blob + 5;
|
||||
|
||||
} else /* private-key parsing */
|
||||
{
|
||||
uint16_t privkey_packed_len;
|
||||
uint16_t privkey_packed_trits_len = (p->N + 4) / 5;
|
||||
uint16_t privkey_packed_indices_len;
|
||||
uint16_t dF;
|
||||
|
||||
/* check packing type for product-form private keys */
|
||||
|
||||
if (p->is_product_form &&
|
||||
(tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* set packed-key length for packed indices */
|
||||
|
||||
if (p->is_product_form) {
|
||||
dF = (uint16_t)((p->dF_r & 0xff) + /* df1 */
|
||||
((p->dF_r >> 8) & 0xff) + /* df2 */
|
||||
((p->dF_r >> 16) & 0xff)); /* df3 */
|
||||
} else {
|
||||
dF = (uint16_t) p->dF_r;
|
||||
}
|
||||
|
||||
privkey_packed_indices_len = ((dF << 1) * p->N_bits + 7) >> 3;
|
||||
|
||||
/* set private-key packing type if defaulted */
|
||||
|
||||
if (tag == NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG) {
|
||||
if (p->is_product_form ||
|
||||
(privkey_packed_indices_len <=
|
||||
privkey_packed_trits_len)) {
|
||||
tag = NTRU_ENCRYPT_PRIVKEY_INDICES_TAG;
|
||||
} else {
|
||||
tag = NTRU_ENCRYPT_PRIVKEY_TRITS_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
if (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG) {
|
||||
privkey_packed_len = privkey_packed_trits_len;
|
||||
} else {
|
||||
privkey_packed_len = privkey_packed_indices_len;
|
||||
}
|
||||
|
||||
if (key_blob_len != 5 + pubkey_packed_len + privkey_packed_len) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*pubkey = key_blob + 5;
|
||||
*privkey = *pubkey + pubkey_packed_len;
|
||||
*privkey_pack_type = (tag == NTRU_ENCRYPT_PRIVKEY_TRITS_TAG) ? NTRU_ENCRYPT_KEY_PACKED_TRITS : NTRU_ENCRYPT_KEY_PACKED_INDICES;
|
||||
}
|
||||
|
||||
/* return parameter set pointer */
|
||||
|
||||
*pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS;
|
||||
*params = p;
|
||||
}
|
||||
|
||||
default:
|
||||
break; /* can't get here */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_get_blob_params
|
||||
*
|
||||
* Returns public and private key packing types and blob lengths given
|
||||
* a packing format. For now, only a default packing format exists.
|
||||
*
|
||||
* Only public-key params may be returned by setting privkey_pack_type
|
||||
* and privkey_blob_len to NULL.
|
||||
*/
|
||||
|
||||
void ntru_crypto_ntru_encrypt_key_get_blob_params(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
||||
packing type */
|
||||
uint16_t *pubkey_blob_len, /* out - addr for no. of
|
||||
bytes in
|
||||
pubkey blob */
|
||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
||||
packing type */
|
||||
uint16_t *privkey_blob_len) /* out - addr for no. of
|
||||
bytes in
|
||||
privkey blob */
|
||||
{
|
||||
uint16_t pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
|
||||
|
||||
*pubkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS;
|
||||
*pubkey_blob_len = 5 + pubkey_packed_len;
|
||||
|
||||
if (privkey_pack_type && privkey_blob_len) {
|
||||
uint16_t privkey_packed_trits_len = (params->N + 4) / 5;
|
||||
uint16_t privkey_packed_indices_len;
|
||||
uint16_t dF;
|
||||
|
||||
if (params->is_product_form) {
|
||||
dF = (uint16_t)((params->dF_r & 0xff) + /* df1 */
|
||||
((params->dF_r >> 8) & 0xff) + /* df2 */
|
||||
((params->dF_r >> 16) & 0xff)); /* df3 */
|
||||
} else {
|
||||
dF = (uint16_t) params->dF_r;
|
||||
}
|
||||
|
||||
privkey_packed_indices_len = ((dF << 1) * params->N_bits + 7) >> 3;
|
||||
|
||||
if (params->is_product_form ||
|
||||
(privkey_packed_indices_len <= privkey_packed_trits_len)) {
|
||||
*privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_INDICES;
|
||||
*privkey_blob_len =
|
||||
5 + pubkey_packed_len + privkey_packed_indices_len;
|
||||
} else {
|
||||
*privkey_pack_type = NTRU_ENCRYPT_KEY_PACKED_TRITS;
|
||||
*privkey_blob_len =
|
||||
5 + pubkey_packed_len + privkey_packed_trits_len;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_create_pubkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t const *pubkey, /* in - pointer to the
|
||||
coefficients
|
||||
of the pubkey */
|
||||
uint8_t pubkey_pack_type, /* out - pubkey packing
|
||||
type */
|
||||
uint8_t *pubkey_blob) /* out - addr for the
|
||||
pubkey blob */
|
||||
{
|
||||
|
||||
switch (pubkey_pack_type) {
|
||||
case NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS:
|
||||
*pubkey_blob++ = NTRU_ENCRYPT_PUBKEY_TAG;
|
||||
*pubkey_blob++ = (uint8_t) sizeof(params->OID);
|
||||
memcpy(pubkey_blob, params->OID, sizeof(params->OID));
|
||||
pubkey_blob += sizeof(params->OID);
|
||||
ntru_elements_2_octets(params->N, pubkey, params->q_bits,
|
||||
pubkey_blob);
|
||||
break;
|
||||
|
||||
default:
|
||||
NTRU_RET(NTRU_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, recreated from an already-packed public key.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t packed_pubkey_len, /* in - no. octets in
|
||||
packed pubkey */
|
||||
uint8_t const *packed_pubkey, /* in - pointer to the
|
||||
packed pubkey */
|
||||
uint8_t pubkey_pack_type, /* out - pubkey packing
|
||||
type */
|
||||
uint8_t *pubkey_blob) /* out - addr for the
|
||||
pubkey blob */
|
||||
{
|
||||
|
||||
switch (pubkey_pack_type) {
|
||||
case NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS:
|
||||
*pubkey_blob++ = NTRU_ENCRYPT_PUBKEY_TAG;
|
||||
*pubkey_blob++ = (uint8_t) sizeof(params->OID);
|
||||
memcpy(pubkey_blob, params->OID, sizeof(params->OID));
|
||||
pubkey_blob += sizeof(params->OID);
|
||||
memcpy(pubkey_blob, packed_pubkey, packed_pubkey_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
NTRU_RET(NTRU_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_privkey_blob
|
||||
*
|
||||
* Returns a private key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_create_privkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t const *pubkey, /* in - pointer to the
|
||||
coefficients
|
||||
of the pubkey */
|
||||
uint16_t const *privkey, /* in - pointer to the
|
||||
indices of the
|
||||
privkey */
|
||||
uint8_t privkey_pack_type, /* in - privkey packing
|
||||
type */
|
||||
uint8_t *buf, /* in - temp, N bytes */
|
||||
uint8_t *privkey_blob) /* out - addr for the
|
||||
privkey blob */
|
||||
{
|
||||
switch (privkey_pack_type) {
|
||||
case NTRU_ENCRYPT_KEY_PACKED_TRITS:
|
||||
case NTRU_ENCRYPT_KEY_PACKED_INDICES:
|
||||
|
||||
/* format header and packed public key */
|
||||
|
||||
*privkey_blob++ = NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG;
|
||||
*privkey_blob++ = (uint8_t) sizeof(params->OID);
|
||||
memcpy(privkey_blob, params->OID, sizeof(params->OID));
|
||||
privkey_blob += sizeof(params->OID);
|
||||
ntru_elements_2_octets(params->N, pubkey, params->q_bits,
|
||||
privkey_blob);
|
||||
privkey_blob += (params->N * params->q_bits + 7) >> 3;
|
||||
|
||||
/* add packed private key */
|
||||
|
||||
if (privkey_pack_type == NTRU_ENCRYPT_KEY_PACKED_TRITS) {
|
||||
ntru_indices_2_packed_trits(privkey, (uint16_t) params->dF_r,
|
||||
(uint16_t) params->dF_r,
|
||||
params->N, buf, privkey_blob);
|
||||
} else {
|
||||
uint32_t dF;
|
||||
|
||||
if (params->is_product_form) {
|
||||
dF = (params->dF_r & 0xff) +
|
||||
((params->dF_r >> 8) & 0xff) +
|
||||
((params->dF_r >> 16) & 0xff);
|
||||
} else {
|
||||
dF = params->dF_r;
|
||||
}
|
||||
|
||||
ntru_elements_2_octets((uint16_t) dF << 1, privkey,
|
||||
params->N_bits, privkey_blob);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NTRU_RET(NTRU_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
@ -1,156 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
*********************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
|
||||
#define NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
|
||||
|
||||
#include "ntru_crypto_ntru_convert.h"
|
||||
#include "ntru_crypto_ntru_encrypt_param_sets.h"
|
||||
|
||||
/* key-blob definitions */
|
||||
|
||||
#define NTRU_ENCRYPT_PUBKEY_TAG 0x01
|
||||
#define NTRU_ENCRYPT_PRIVKEY_DEFAULT_TAG 0x02
|
||||
#define NTRU_ENCRYPT_PRIVKEY_TRITS_TAG 0xfe
|
||||
#define NTRU_ENCRYPT_PRIVKEY_INDICES_TAG 0xff
|
||||
|
||||
/* packing types */
|
||||
|
||||
#define NTRU_ENCRYPT_KEY_PACKED_COEFFICIENTS 0x01
|
||||
#define NTRU_ENCRYPT_KEY_PACKED_INDICES 0x02
|
||||
#define NTRU_ENCRYPT_KEY_PACKED_TRITS 0x03
|
||||
|
||||
/* function declarations */
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_parse
|
||||
*
|
||||
* Parses an NTRUEncrypt key blob.
|
||||
* If the blob is not corrupt, returns packing types for public and private
|
||||
* keys, a pointer to the parameter set, a pointer to the public key, and
|
||||
* a pointer to the private key if it exists.
|
||||
*
|
||||
* Returns TRUE if successful.
|
||||
* Returns FALSE if the blob is invalid.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
ntru_crypto_ntru_encrypt_key_parse(
|
||||
bool pubkey_parse, /* in - if parsing pubkey
|
||||
blob */
|
||||
uint16_t key_blob_len, /* in - no. octets in key
|
||||
blob */
|
||||
uint8_t const *key_blob, /* in - pointer to key blob */
|
||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
||||
packing type */
|
||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
||||
packing type */
|
||||
NTRU_ENCRYPT_PARAM_SET **params, /* out - addr for ptr to
|
||||
parameter set */
|
||||
uint8_t const **pubkey, /* out - addr for ptr to
|
||||
packed pubkey */
|
||||
uint8_t const **privkey); /* out - addr for ptr to
|
||||
packed privkey */
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_get_blob_params
|
||||
*
|
||||
* Returns public and private key packing types and blob lengths given
|
||||
* a packing format. For now, only a default packing format exists.
|
||||
*
|
||||
* Only public-key params may be returned by setting privkey_pack_type
|
||||
* and privkey_blob_len to NULL.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_crypto_ntru_encrypt_key_get_blob_params(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
||||
packing type */
|
||||
uint16_t *pubkey_blob_len, /* out - addr for no. of
|
||||
bytes in
|
||||
pubkey blob */
|
||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
||||
packing type */
|
||||
uint16_t *privkey_blob_len); /* out - addr for no. of
|
||||
bytes in
|
||||
privkey blob */
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_create_pubkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t const *pubkey, /* in - pointer to the
|
||||
coefficients
|
||||
of the pubkey */
|
||||
uint8_t pubkey_pack_type, /* out - addr for pubkey
|
||||
packing type */
|
||||
uint8_t *pubkey_blob); /* out - addr for the
|
||||
pubkey blob */
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, recreated from an already-packed public key.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t packed_pubkey_len, /* in - no. octets in
|
||||
packed pubkey */
|
||||
uint8_t const *packed_pubkey, /* in - pointer to the
|
||||
packed pubkey */
|
||||
uint8_t pubkey_pack_type, /* out - pubkey packing
|
||||
type */
|
||||
uint8_t *pubkey_blob); /* out - addr for the
|
||||
pubkey blob */
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_privkey_blob
|
||||
*
|
||||
* Returns a privlic key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_ntru_encrypt_key_create_privkey_blob(
|
||||
NTRU_ENCRYPT_PARAM_SET const *params, /* in - pointer to
|
||||
param set
|
||||
parameters */
|
||||
uint16_t const *pubkey, /* in - pointer to the
|
||||
coefficients
|
||||
of the pubkey */
|
||||
uint16_t const *privkey, /* in - pointer to the
|
||||
indices of the
|
||||
privkey */
|
||||
uint8_t privkey_pack_type, /* in - privkey packing
|
||||
type */
|
||||
uint8_t *buf, /* in - temp, N bytes */
|
||||
uint8_t *privkey_blob); /* out - addr for the
|
||||
privkey blob */
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H */
|
||||
@ -1,577 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_encrypt_param_sets.c
|
||||
*
|
||||
* Contents: Defines the NTRUEncrypt parameter sets.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_encrypt_param_sets.h"
|
||||
|
||||
/* parameter sets */
|
||||
|
||||
static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = {
|
||||
|
||||
{
|
||||
NTRU_EES401EP1, /* parameter-set id */
|
||||
"ees401ep1", /* human readable param set name */
|
||||
{0x00, 0x02, 0x04}, /* OID */
|
||||
0x22, /* DER id */
|
||||
9, /* no. of bits in N (i.e., in an index) */
|
||||
401, /* N */
|
||||
14, /* security strength in octets */
|
||||
14, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
113, /* df, dr */
|
||||
133, /* dg */
|
||||
60, /* maxMsgLenBytes */
|
||||
113, /* dm0 */
|
||||
2005, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
41, /* min. no. of hash calls for IGF-2 */
|
||||
7, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES449EP1, /* parameter-set id */
|
||||
"ees449ep1", /* human readable param set name */
|
||||
{0x00, 0x03, 0x03}, /* OID */
|
||||
0x23, /* DER id */
|
||||
9, /* no. of bits in N (i.e., in an index) */
|
||||
449, /* N */
|
||||
16, /* security strength in octets */
|
||||
16, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
134, /* df, dr */
|
||||
149, /* dg */
|
||||
67, /* maxMsgLenBytes */
|
||||
134, /* dm0 */
|
||||
449, /* 2^c - (2^c mod N) */
|
||||
9, /* c */
|
||||
1, /* lLen */
|
||||
47, /* min. no. of hash calls for IGF-2 */
|
||||
8, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES677EP1, /* parameter-set id */
|
||||
"ees677ep1", /* human readable param set name */
|
||||
{0x00, 0x05, 0x03}, /* OID */
|
||||
0x24, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
677, /* N */
|
||||
24, /* security strength in octets */
|
||||
24, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
157, /* df, dr */
|
||||
225, /* dg */
|
||||
101, /* maxMsgLenBytes */
|
||||
157, /* dm0 */
|
||||
2031, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
32, /* min. no. of hash calls for IGF-2 */
|
||||
8, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1087EP2, /* parameter-set id */
|
||||
"ees1087ep2", /* human readable param set name */
|
||||
{0x00, 0x06, 0x03}, /* OID */
|
||||
0x25, /* DER id */
|
||||
11, /* no. of bits in N (i.e., in an index) */
|
||||
1087, /* N */
|
||||
32, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
120, /* df, dr */
|
||||
362, /* dg */
|
||||
170, /* maxMsgLenBytes */
|
||||
120, /* dm0 */
|
||||
7609, /* 2^c - (2^c mod N) */
|
||||
13, /* c */
|
||||
1, /* lLen */
|
||||
27, /* min. no. of hash calls for IGF-2 */
|
||||
11, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES541EP1, /* parameter-set id */
|
||||
"ees541ep1", /* human readable param set name */
|
||||
{0x00, 0x02, 0x05}, /* OID */
|
||||
0x26, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
541, /* N */
|
||||
14, /* security strength in octets */
|
||||
14, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
49, /* df, dr */
|
||||
180, /* dg */
|
||||
86, /* maxMsgLenBytes */
|
||||
49, /* dm0 */
|
||||
3787, /* 2^c - (2^c mod N) */
|
||||
12, /* c */
|
||||
1, /* lLen */
|
||||
16, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES613EP1, /* parameter-set id */
|
||||
"ees613ep1", /* human readable param set name */
|
||||
{0x00, 0x03, 0x04}, /* OID */
|
||||
0x27, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
613, /* N */
|
||||
16, /* securuity strength in octets */
|
||||
16, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
55, /* df, dr */
|
||||
204, /* dg */
|
||||
97, /* maxMsgLenBytes */
|
||||
55, /* dm0 */
|
||||
1839, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
18, /* min. no. of hash calls for IGF-2 */
|
||||
10, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES887EP1, /* parameter-set id */
|
||||
"ees887ep1", /* human readable param set name */
|
||||
{0x00, 0x05, 0x04}, /* OID */
|
||||
0x28, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
887, /* N */
|
||||
24, /* security strength in octets */
|
||||
24, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
81, /* df, dr */
|
||||
295, /* dg */
|
||||
141, /* maxMsgLenBytes */
|
||||
81, /* dm0 */
|
||||
887, /* 2^c - (2^c mod N) */
|
||||
10, /* c */
|
||||
1, /* lLen */
|
||||
16, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1171EP1, /* parameter-set id */
|
||||
"ees1171ep1", /* human readable param set name */
|
||||
{0x00, 0x06, 0x04}, /* OID */
|
||||
0x29, /* DER id */
|
||||
11, /* no. of bits in N (i.e., in an index) */
|
||||
1171, /* N */
|
||||
32, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
106, /* df, dr */
|
||||
390, /* dg */
|
||||
186, /* maxMsgLenBytes */
|
||||
106, /* dm0 */
|
||||
3513, /* 2^c - (2^c mod N) */
|
||||
12, /* c */
|
||||
1, /* lLen */
|
||||
25, /* min. no. of hash calls for IGF-2 */
|
||||
12, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES659EP1, /* parameter-set id */
|
||||
"ees659ep1", /* human readable param set name */
|
||||
{0x00, 0x02, 0x06}, /* OID */
|
||||
0x2a, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
659, /* N */
|
||||
14, /* security strength in octets */
|
||||
14, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
38, /* df, dr */
|
||||
219, /* dg */
|
||||
108, /* maxMsgLenBytes */
|
||||
38, /* dm0 */
|
||||
1977, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
11, /* min. no. of hash calls for IGF-2 */
|
||||
10, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES761EP1, /* parameter-set id */
|
||||
"ees761ep1", /* human readable param set name */
|
||||
{0x00, 0x03, 0x05}, /* OID */
|
||||
0x2b, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
761, /* N */
|
||||
16, /* security strength in octets */
|
||||
16, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
42, /* df, dr */
|
||||
253, /* dg */
|
||||
125, /* maxMsgLenBytes */
|
||||
42, /* dm0 */
|
||||
3805, /* 2^c - (2^c mod N) */
|
||||
12, /* c */
|
||||
1, /* lLen */
|
||||
14, /* min. no. of hash calls for IGF-2 */
|
||||
12, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1087EP1, /* parameter-set id */
|
||||
"ees1087ep1", /* human readable param set name */
|
||||
{0x00, 0x05, 0x05}, /* OID */
|
||||
0x2c, /* DER id */
|
||||
11, /* no. of bits in N (i.e., in an index) */
|
||||
1087, /* N */
|
||||
24, /* security strength in octets */
|
||||
24, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
63, /* df, dr */
|
||||
362, /* dg */
|
||||
178, /* maxMsgLenBytes */
|
||||
63, /* dm0 */
|
||||
7609, /* 2^c - (2^c mod N) */
|
||||
13, /* c */
|
||||
1, /* lLen */
|
||||
14, /* min. no. of hash calls for IGF-2 */
|
||||
11, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1499EP1, /* parameter-set id */
|
||||
"ees1499ep1", /* human readable param set name */
|
||||
{0x00, 0x06, 0x05}, /* OID */
|
||||
0x2d, /* DER id */
|
||||
11, /* no. of bits in N (i.e., in an index) */
|
||||
1499, /* N */
|
||||
32, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
FALSE, /* product form */
|
||||
79, /* df, dr */
|
||||
499, /* dg */
|
||||
247, /* maxMsgLenBytes */
|
||||
79, /* dm0 */
|
||||
7495, /* 2^c - (2^c mod N) */
|
||||
13, /* c */
|
||||
1, /* lLen */
|
||||
18, /* min. no. of hash calls for IGF-2 */
|
||||
14, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES401EP2, /* parameter-set id */
|
||||
"ees401ep2", /* human readable param set name */
|
||||
{0x00, 0x02, 0x10}, /* OID */
|
||||
0x2e, /* DER id */
|
||||
9, /* no. of bits in N (i.e., in an index) */
|
||||
401, /* N */
|
||||
14, /* security strength in octets */
|
||||
14, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
8 + (8 << 8) + (6 << 16), /* df, dr */
|
||||
133, /* dg */
|
||||
60, /* maxMsgLenBytes */
|
||||
101, /* dm0 */
|
||||
2005, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
7, /* min. no. of hash calls for IGF-2 */
|
||||
7, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES439EP1, /* parameter-set id */
|
||||
"ees439ep1", /* human readable param set name */
|
||||
{0x00, 0x03, 0x10}, /* OID */
|
||||
0x2f, /* DER id */
|
||||
9, /* no. of bits in N (i.e., in an index) */
|
||||
439, /* N */
|
||||
16, /* security strength in octets */
|
||||
16, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
9 + (8 << 8) + (5 << 16), /* df, dr */
|
||||
146, /* dg */
|
||||
65, /* maxMsgLenBytes */
|
||||
112, /* dm0 */
|
||||
439, /* 2^c - (2^c mod N) */
|
||||
9, /* c */
|
||||
1, /* lLen */
|
||||
8, /* min. no. of hash calls for IGF-2 */
|
||||
8, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA1, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES593EP1, /* parameter-set id */
|
||||
"ees593ep1", /* human readable param set name */
|
||||
{0x00, 0x05, 0x10}, /* OID */
|
||||
0x30, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
593, /* N */
|
||||
24, /* security strength in octets */
|
||||
24, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
10 + (10 << 8) + (8 << 16), /* df, dr */
|
||||
197, /* dg */
|
||||
86, /* maxMsgLenBytes */
|
||||
158, /* dm0 */
|
||||
1779, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
9, /* min. no. of hash calls for IGF-2 */
|
||||
7, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES743EP1, /* parameter-set id */
|
||||
"ees743ep1", /* human readable param set name */
|
||||
{0x00, 0x06, 0x10}, /* OID */
|
||||
0x31, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
743, /* N */
|
||||
32, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
11 + (11 << 8) + (15 << 16), /* df, dr */
|
||||
247, /* dg */
|
||||
106, /* maxMsgLenBytes */
|
||||
204, /* dm0 */
|
||||
8173, /* 2^c - (2^c mod N) */
|
||||
13, /* c */
|
||||
1, /* lLen */
|
||||
9, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES443EP1, /* parameter-set id */
|
||||
"ees443ep1", /* human readable param set name */
|
||||
{0x00, 0x03, 0x11}, /* OID */
|
||||
0x32, /* DER id */
|
||||
9, /* no. of bits in N (i.e., in an index) */
|
||||
443, /* N */
|
||||
16, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
9 + (8 << 8) + (5 << 16), /* df, dr */
|
||||
148, /* dg */
|
||||
49, /* maxMsgLenBytes */
|
||||
115, /* dm0 */
|
||||
443, /* 2^c - (2^c mod N) */
|
||||
9, /* c */
|
||||
1, /* lLen */
|
||||
5, /* min. no. of hash calls for IGF-2 */
|
||||
5, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES587EP1, /* parameter-set id */
|
||||
"ees587ep1", /* human readable param set name */
|
||||
{0x00, 0x05, 0x11}, /* OID */
|
||||
0x33, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
587, /* N */
|
||||
24, /* security strength in octets */
|
||||
32, /* no. of octets for random string b */
|
||||
2048, /* q */
|
||||
11, /* no. of bits in q (i.e., in a coeff) */
|
||||
TRUE, /* product form */
|
||||
10 + (10 << 8) + (8 << 16), /* df, dr */
|
||||
196, /* dg */
|
||||
76, /* maxMsgLenBytes */
|
||||
157, /* dm0 */
|
||||
1761, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
7, /* min. no. of hash calls for IGF-2 */
|
||||
7, /* min. no. of hash calls for MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID_SHA256, /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
},
|
||||
};
|
||||
|
||||
static size_t numParamSets =
|
||||
sizeof(ntruParamSets) / sizeof(NTRU_ENCRYPT_PARAM_SET);
|
||||
|
||||
/* functions */
|
||||
|
||||
/* ntru_encrypt_get_params_with_id
|
||||
*
|
||||
* Looks up a set of NTRUEncrypt parameters based on the id of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_id(
|
||||
NTRU_ENCRYPT_PARAM_SET_ID id) /* in - parameter-set id */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numParamSets; i++) {
|
||||
if (ntruParamSets[i].id == id) {
|
||||
return &(ntruParamSets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ntru_encrypt_get_params_with_OID
|
||||
*
|
||||
* Looks up a set of NTRUEncrypt parameters based on the OID of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_OID(
|
||||
uint8_t const *oid) /* in - pointer to parameter-set OID */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numParamSets; i++) {
|
||||
if (!memcmp(ntruParamSets[i].OID, oid, 3)) {
|
||||
return &(ntruParamSets[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ntru_encrypt_get_params_with_DER_id
|
||||
*
|
||||
* Looks up a set of NTRUEncrypt parameters based on the DER id of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_DER_id(
|
||||
uint8_t der_id) /* in - parameter-set DER id */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numParamSets; i++) {
|
||||
if (ntruParamSets[i].der_id == der_id) {
|
||||
return &(ntruParamSets[i]);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
ntru_encrypt_get_param_set_name(
|
||||
NTRU_ENCRYPT_PARAM_SET_ID id) /* in - parameter-set id */
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < numParamSets; i++) {
|
||||
if (ntruParamSets[i].id == id) {
|
||||
return ntruParamSets[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -1,119 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_encrypt_param_sets.h
|
||||
*
|
||||
* Contents: Definitions and declarations for the NTRUEncrypt parameter sets.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H
|
||||
#define NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_hash_basics.h"
|
||||
|
||||
/* structures */
|
||||
|
||||
typedef struct _NTRU_ENCRYPT_PARAM_SET {
|
||||
NTRU_ENCRYPT_PARAM_SET_ID id; /* parameter-set ID */
|
||||
const char *name; /* human readable param set name */
|
||||
uint8_t const OID[3]; /* pointer to OID */
|
||||
uint8_t der_id; /* parameter-set DER id */
|
||||
uint8_t N_bits; /* no. of bits in N (i.e. in
|
||||
an index */
|
||||
uint16_t N; /* ring dimension */
|
||||
uint16_t sec_strength_len; /* no. of octets of
|
||||
security strength */
|
||||
uint16_t b_len; /* no. of octets for random
|
||||
string b */
|
||||
uint16_t q; /* big modulus */
|
||||
uint8_t q_bits; /* no. of bits in q (i.e. in
|
||||
a coefficient */
|
||||
bool is_product_form; /* if product form used */
|
||||
uint32_t dF_r; /* no. of 1 or -1 coefficients
|
||||
in ring elements F, r */
|
||||
uint16_t dg; /* no. - 1 of 1 coefficients
|
||||
or no. of -1 coefficients
|
||||
in ring element g */
|
||||
uint16_t m_len_max; /* max no. of plaintext
|
||||
octets */
|
||||
uint16_t min_msg_rep_wt; /* min. message
|
||||
representative weight */
|
||||
uint16_t no_bias_limit; /* limit for no bias in
|
||||
IGF-2 */
|
||||
uint8_t c_bits; /* no. bits in candidate for
|
||||
deriving an index in
|
||||
IGF-2 */
|
||||
uint8_t m_len_len; /* no. of octets to hold
|
||||
mLenOctets */
|
||||
uint8_t min_IGF_hash_calls; /* min. no. of hash calls for
|
||||
IGF-2 */
|
||||
uint8_t min_MGF_hash_calls; /* min. no. of hash calls for
|
||||
MGF-TP-1 */
|
||||
NTRU_CRYPTO_HASH_ALGID hash_algid; /* hash function for MGF-TP-1,
|
||||
HMAC-DRBG, etc. */
|
||||
} NTRU_ENCRYPT_PARAM_SET;
|
||||
|
||||
/* function declarations */
|
||||
|
||||
/* ntru_encrypt_get_params_with_id
|
||||
*
|
||||
* Looks up a set of NTRU Encrypt parameters based on the id of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
extern NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_id(
|
||||
NTRU_ENCRYPT_PARAM_SET_ID id); /* in - parameter-set id */
|
||||
|
||||
/* ntru_encrypt_get_params_with_OID
|
||||
*
|
||||
* Looks up a set of NTRU Encrypt parameters based on the OID of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
extern NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_OID(
|
||||
uint8_t const *oid); /* in - pointer to parameter-set OID */
|
||||
|
||||
/* ntru_encrypt_get_params_with_DER_id
|
||||
*
|
||||
* Looks up a set of NTRUEncrypt parameters based on the DER id of the
|
||||
* parameter set.
|
||||
*
|
||||
* Returns a pointer to the parameter set parameters if successful.
|
||||
* Returns NULL if the parameter set cannot be found.
|
||||
*/
|
||||
|
||||
extern NTRU_ENCRYPT_PARAM_SET *
|
||||
ntru_encrypt_get_params_with_DER_id(
|
||||
uint8_t der_id); /* in - parameter-set DER id */
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_PARAM_SETS_H */
|
||||
@ -1,193 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_mgf1.c
|
||||
*
|
||||
* Contents: Routines implementing MGF-TP-1 and MGF-1.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_mgf1.h"
|
||||
#include "ntru_crypto_ntru_convert.h"
|
||||
|
||||
/* ntru_mgf1
|
||||
*
|
||||
* Implements a basic mask-generation function, generating an arbitrary
|
||||
* number of octets based on hashing a digest-length string concatenated
|
||||
* with a 4-octet counter.
|
||||
*
|
||||
* The state (string and counter) is initialized when a seed is present.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns NTRU_CRYPTO_HASH_ errors if they occur.
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_mgf1(
|
||||
uint8_t *state, /* in/out - pointer to the state */
|
||||
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm ID */
|
||||
uint8_t md_len, /* in - no. of octets in digest */
|
||||
uint8_t num_calls, /* in - no. of hash calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t const *seed, /* in - pointer to seed */
|
||||
uint8_t *out) /* out - address for output */
|
||||
{
|
||||
uint8_t *ctr = state + md_len;
|
||||
uint32_t retcode;
|
||||
|
||||
/* if seed present, init state */
|
||||
|
||||
if (seed) {
|
||||
if ((retcode = ntru_crypto_hash_digest(algid, seed, seed_len, state)) !=
|
||||
NTRU_CRYPTO_HASH_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
memset(ctr, 0, 4);
|
||||
}
|
||||
|
||||
/* generate output */
|
||||
|
||||
while (num_calls-- > 0) {
|
||||
if ((retcode = ntru_crypto_hash_digest(algid, state, md_len + 4,
|
||||
out)) != NTRU_CRYPTO_HASH_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
out += md_len;
|
||||
|
||||
/* increment counter */
|
||||
|
||||
if (++ctr[3] == 0) {
|
||||
if (++ctr[2] == 0) {
|
||||
if (++ctr[1] == 0) {
|
||||
++ctr[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
|
||||
/* ntru_mgftp1
|
||||
*
|
||||
* Implements a mask-generation function for trinary polynomials,
|
||||
* MGF-TP-1, generating an arbitrary number of octets based on hashing
|
||||
* a digest-length string concatenated with a 4-octet counter. From
|
||||
* these octets, N trits are derived.
|
||||
*
|
||||
* The state (string and counter) is initialized when a seed is present.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns NTRU_CRYPTO_HASH_ errors if they occur.
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_mgftp1(
|
||||
NTRU_CRYPTO_HASH_ALGID hash_algid, /* in - hash alg ID for
|
||||
MGF-TP-1 */
|
||||
uint8_t md_len, /* in - no. of octets in
|
||||
digest */
|
||||
uint8_t min_calls, /* in - minimum no. of hash
|
||||
calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t *seed, /* in - pointer to seed */
|
||||
uint8_t *buf, /* in - pointer to working
|
||||
buffer */
|
||||
uint16_t num_trits_needed, /* in - no. of trits in mask */
|
||||
uint8_t *mask) /* out - address for mask trits */
|
||||
{
|
||||
uint8_t *mgf_out;
|
||||
uint8_t *octets;
|
||||
uint16_t octets_available;
|
||||
uint32_t retcode;
|
||||
|
||||
/* generate minimum MGF1 output */
|
||||
|
||||
mgf_out = buf + md_len + 4;
|
||||
if ((retcode = ntru_mgf1(buf, hash_algid, md_len, min_calls,
|
||||
seed_len, seed, mgf_out)) != NTRU_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
octets = mgf_out;
|
||||
octets_available = min_calls * md_len;
|
||||
|
||||
/* get trits for mask */
|
||||
|
||||
while (num_trits_needed >= 5) {
|
||||
/* get another octet and convert it to 5 trits */
|
||||
|
||||
if (octets_available == 0) {
|
||||
if ((retcode = ntru_mgf1(buf, hash_algid, md_len, 1,
|
||||
0, NULL, mgf_out)) != NTRU_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
octets = mgf_out;
|
||||
octets_available = md_len;
|
||||
}
|
||||
|
||||
if (*octets < 243) {
|
||||
ntru_octet_2_trits(*octets, mask);
|
||||
mask += 5;
|
||||
num_trits_needed -= 5;
|
||||
}
|
||||
|
||||
octets++;
|
||||
--octets_available;
|
||||
}
|
||||
|
||||
/* get any remaining trits */
|
||||
|
||||
while (num_trits_needed) {
|
||||
uint8_t trits[5];
|
||||
|
||||
/* get another octet and convert it to remaining trits */
|
||||
|
||||
if (octets_available == 0) {
|
||||
if ((retcode = ntru_mgf1(buf, hash_algid, md_len, 1,
|
||||
0, NULL, mgf_out)) != NTRU_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
octets = mgf_out;
|
||||
octets_available = md_len;
|
||||
}
|
||||
|
||||
if (*octets < 243) {
|
||||
ntru_octet_2_trits(*octets, trits);
|
||||
memcpy(mask, trits, num_trits_needed);
|
||||
num_trits_needed = 0;
|
||||
} else {
|
||||
octets++;
|
||||
--octets_available;
|
||||
}
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_mgf1.h
|
||||
*
|
||||
* Contents: Public header file for MGF-1 in the NTRU algorithm.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_NTRU_MGF1_H
|
||||
#define NTRU_CRYPTO_NTRU_MGF1_H
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_hash.h"
|
||||
|
||||
/* function declarations */
|
||||
|
||||
/* ntru_mgf1
|
||||
*
|
||||
* Implements a basic mask-generation function, generating an arbitrary
|
||||
* number of octets based on hashing a digest-length string concatenated
|
||||
* with a 4-octet counter.
|
||||
*
|
||||
* The state (string and counter) is initialized when a seed is present.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns NTRU_CRYPTO_HASH_ errors if they occur.
|
||||
*
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_mgf1(
|
||||
uint8_t *state, /* in/out - pointer to the state */
|
||||
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm ID */
|
||||
uint8_t md_len, /* in - no. of octets in digest */
|
||||
uint8_t num_calls, /* in - no. of hash calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t const *seed, /* in - pointer to seed */
|
||||
uint8_t *out); /* out - address for output */
|
||||
|
||||
/* ntru_mgftp1
|
||||
*
|
||||
* Implements a mask-generation function for trinary polynomials,
|
||||
* MGF-TP-1, generating an arbitrary number of octets based on hashing
|
||||
* a digest-length string concatenated with a 4-octet counter. From
|
||||
* these octets, N trits are derived.
|
||||
*
|
||||
* The state (string and counter) is initialized when a seed is present.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns NTRU_CRYPTO_HASH_ errors if they occur.
|
||||
*
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_mgftp1(
|
||||
NTRU_CRYPTO_HASH_ALGID hash_algid, /* in - hash alg ID for
|
||||
MGF-TP-1 */
|
||||
uint8_t md_len, /* in - no. of octets in
|
||||
digest */
|
||||
uint8_t min_calls, /* in - minimum no. of hash
|
||||
calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t *seed, /* in - pointer to seed */
|
||||
uint8_t *buf, /* in - pointer to working
|
||||
buffer */
|
||||
uint16_t num_trits_needed, /* in - no. of trits in mask */
|
||||
uint8_t *mask); /* out - address for mask trits */
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_MGF1_H */
|
||||
@ -1,137 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
|
||||
#define PAD(N) ((N + 0x000f) & 0xfff0)
|
||||
|
||||
static void
|
||||
grade_school_mul(
|
||||
uint16_t *res1, /* out - a * b in Z[x], must be length 2N */
|
||||
uint16_t const *a, /* in - polynomial */
|
||||
uint16_t const *b, /* in - polynomial */
|
||||
uint16_t const N) /* in - number of coefficients in a and b */
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
|
||||
for (j = 0; j < N; j++) {
|
||||
res1[j] = a[0] * b[j];
|
||||
}
|
||||
for (i = 1; i < N; i++) {
|
||||
res1[i + N - 1] = 0;
|
||||
for (j = 0; j < N; j++) {
|
||||
res1[i + j] += a[i] * b[j];
|
||||
}
|
||||
}
|
||||
res1[2 * N - 1] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
karatsuba(
|
||||
uint16_t *res1, /* out - a * b in Z[x], must be length 2k */
|
||||
uint16_t *tmp1, /* in - k coefficients of scratch space */
|
||||
uint16_t const *a, /* in - polynomial */
|
||||
uint16_t const *b, /* in - polynomial */
|
||||
uint16_t const k) /* in - number of coefficients in a and b */
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
uint16_t const p = k >> 1;
|
||||
|
||||
uint16_t *res2;
|
||||
uint16_t *res3;
|
||||
uint16_t *res4;
|
||||
uint16_t *tmp2;
|
||||
uint16_t const *a2;
|
||||
uint16_t const *b2;
|
||||
|
||||
/* Grade school multiplication for small / odd inputs */
|
||||
if (k <= 38 || (k & 1) != 0) {
|
||||
grade_school_mul(res1, a, b, k);
|
||||
return;
|
||||
}
|
||||
|
||||
res2 = res1 + p;
|
||||
res3 = res1 + k;
|
||||
res4 = res1 + k + p;
|
||||
tmp2 = tmp1 + p;
|
||||
a2 = a + p;
|
||||
b2 = b + p;
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
res1[i] = a[i] - a2[i];
|
||||
res2[i] = b2[i] - b[i];
|
||||
}
|
||||
|
||||
karatsuba(tmp1, res3, res1, res2, p);
|
||||
|
||||
karatsuba(res3, res1, a2, b2, p);
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
tmp1[i] += res3[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
res2[i] = tmp1[i];
|
||||
tmp2[i] += res4[i];
|
||||
res3[i] += tmp2[i];
|
||||
}
|
||||
|
||||
karatsuba(tmp1, res1, a, b, p);
|
||||
|
||||
for (i = 0; i < p; i++) {
|
||||
res1[i] = tmp1[i];
|
||||
res2[i] += tmp1[i] + tmp2[i];
|
||||
res3[i] += tmp2[i];
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ntru_ring_mult_coefficients_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *tmp_polys,
|
||||
uint16_t *poly_coeffs) {
|
||||
if (tmp_polys) {
|
||||
*tmp_polys = 3;
|
||||
}
|
||||
|
||||
if (poly_coeffs) {
|
||||
*poly_coeffs = PAD(N);
|
||||
}
|
||||
}
|
||||
|
||||
/* ntru_ring_mult_coefficients
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
void ntru_ring_mult_coefficients(
|
||||
uint16_t const *a, /* in - pointer to polynomial a */
|
||||
uint16_t const *b, /* in - pointer to polynomial b */
|
||||
uint16_t N, /* in - degree of (x^N - 1) */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *tmp, /* in - temp buffer of 3*padN elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t q_mask = q - 1;
|
||||
|
||||
memset(tmp, 0, 3 * PAD(N) * sizeof(uint16_t));
|
||||
karatsuba(tmp, tmp + 2 * PAD(N), a, b, PAD(N));
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
c[i] = (tmp[i] + tmp[i + N]) & q_mask;
|
||||
}
|
||||
for (; i < PAD(N); i++) {
|
||||
c[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,131 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
#include <immintrin.h>
|
||||
|
||||
#define PAD(N) ((N + 0x0007) & 0xfff8)
|
||||
|
||||
static void
|
||||
grade_school_mul(
|
||||
uint16_t *res1, /* out - a * b in Z[x], must be length 2N */
|
||||
uint16_t const *a, /* in - polynomial */
|
||||
uint16_t const *b, /* in - polynomial */
|
||||
uint16_t const N) /* in - number of coefficients in a and b */
|
||||
{
|
||||
__m128i *T;
|
||||
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t m;
|
||||
|
||||
__m128i ai8;
|
||||
__m128i ai8h;
|
||||
__m128i ai8l;
|
||||
__m128i abroad[8];
|
||||
|
||||
__m128i cur;
|
||||
__m128i next;
|
||||
|
||||
__m128i x1;
|
||||
__m128i x2;
|
||||
|
||||
T = (__m128i *) res1;
|
||||
memset(T, 0, 2 * PAD(N) * sizeof(uint16_t));
|
||||
for (i = 0; i < PAD(N) / 8; i++) {
|
||||
/* Broadcast each of the uint16's at a[8*i] into 8
|
||||
copies of that value in a separate __m128i. */
|
||||
ai8 = _mm_load_si128((__m128i *) a + i);
|
||||
ai8h = _mm_unpackhi_epi16(ai8, ai8);
|
||||
ai8l = _mm_unpacklo_epi16(ai8, ai8);
|
||||
abroad[0] = _mm_shuffle_epi32(ai8h, 0xFFFF);
|
||||
abroad[1] = _mm_shuffle_epi32(ai8h, 0xAAAA);
|
||||
abroad[2] = _mm_shuffle_epi32(ai8h, 0x5555);
|
||||
abroad[3] = _mm_shuffle_epi32(ai8h, 0x0000);
|
||||
|
||||
abroad[4] = _mm_shuffle_epi32(ai8l, 0xFFFF);
|
||||
abroad[5] = _mm_shuffle_epi32(ai8l, 0xAAAA);
|
||||
abroad[6] = _mm_shuffle_epi32(ai8l, 0x5555);
|
||||
abroad[7] = _mm_shuffle_epi32(ai8l, 0x0000);
|
||||
|
||||
/* Load a 256 bit section of b.
|
||||
Shift it down by 2*(m+1) bytes and multiply the
|
||||
low 128 bits by abroad[m]. Add all 8 of these
|
||||
values to T[i+j]. */
|
||||
cur = _mm_setzero_si128();
|
||||
for (j = 0; j < PAD(N) / 8; j++) {
|
||||
next = _mm_load_si128((__m128i *) b + j);
|
||||
|
||||
x2 = _mm_xor_si128(x2, x2);
|
||||
for (m = 0; m < 8; m++) {
|
||||
cur = _mm_alignr_epi8(next, cur, 2);
|
||||
next = _mm_srli_si128(next, 2);
|
||||
|
||||
x1 = _mm_mullo_epi16(cur, abroad[m]);
|
||||
x2 = _mm_add_epi16(x2, x1);
|
||||
}
|
||||
x2 = _mm_add_epi16(x2, _mm_load_si128(T + i + j));
|
||||
_mm_store_si128(T + i + j, x2);
|
||||
}
|
||||
|
||||
/* Handle the last N&7 coefficients from a */
|
||||
x2 = _mm_xor_si128(x2, x2);
|
||||
for (m = 0; m < (N & 7); m++) {
|
||||
cur = _mm_srli_si128(cur, 2);
|
||||
|
||||
x1 = _mm_mullo_epi16(cur, abroad[m]);
|
||||
x2 = _mm_add_epi16(x2, x1);
|
||||
}
|
||||
_mm_store_si128(T + i + j, x2);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* To multiply polynomials mod x^N - 1 this mult_coefficients implementation
|
||||
* needs scratch space of size num_polys * num_coeffs * sizeof(uint16_t) */
|
||||
void ntru_ring_mult_coefficients_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *num_polys,
|
||||
uint16_t *num_coeffs) {
|
||||
if (num_polys) {
|
||||
*num_polys = 2;
|
||||
}
|
||||
|
||||
if (num_coeffs) {
|
||||
*num_coeffs = PAD(N);
|
||||
}
|
||||
}
|
||||
|
||||
/* ntru_ring_mult_coefficients
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" has coefficients in the range [0,N).
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
void ntru_ring_mult_coefficients(
|
||||
uint16_t const *a, /* in - pointer to polynomial a */
|
||||
uint16_t const *b, /* in - pointer to polynomial b */
|
||||
uint16_t N, /* in - degree of (x^N - 1) */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *tmp, /* in - temp buffer of 3*PAD(N) elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t q_mask = q - 1;
|
||||
|
||||
grade_school_mul(tmp, a, b, N);
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
c[i] = (tmp[i] + tmp[i + N]) & q_mask;
|
||||
}
|
||||
for (; i < PAD(N); i++) {
|
||||
c[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,98 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
|
||||
void ntru_ring_mult_indices_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *tmp_polys,
|
||||
uint16_t *poly_coeffs) {
|
||||
if (tmp_polys) {
|
||||
*tmp_polys = 1;
|
||||
}
|
||||
|
||||
if (poly_coeffs) {
|
||||
*poly_coeffs = N;
|
||||
}
|
||||
}
|
||||
|
||||
/* ntru_ring_mult_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is a sparse trinary polynomial with coefficients -1, 0,
|
||||
* and 1. It is specified by a list, bi, of its nonzero indices containing
|
||||
* indices for the bi_P1_len +1 coefficients followed by the indices for the
|
||||
* bi_M1_len -1 coefficients.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* input array "b", or temp array "t".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
void ntru_ring_mult_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const bi_P1_len, /* in - no. of +1 coefficients in b */
|
||||
uint16_t const bi_M1_len, /* in - no. of -1 coefficients in b */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of ring element b,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t mod_q_mask = q - 1;
|
||||
uint16_t i, j, k;
|
||||
|
||||
/* t[(i+k)%N] = sum i=0 through N-1 of a[i], for b[k] = -1 */
|
||||
|
||||
for (k = 0; k < N; k++) {
|
||||
t[k] = 0;
|
||||
}
|
||||
|
||||
for (j = bi_P1_len; j < bi_P1_len + bi_M1_len; j++) {
|
||||
k = bi[j];
|
||||
|
||||
for (i = 0; k < N; ++i, ++k) {
|
||||
t[k] = t[k] + a[i];
|
||||
}
|
||||
|
||||
for (k = 0; i < N; ++i, ++k) {
|
||||
t[k] = t[k] + a[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* t[(i+k)%N] = -(sum i=0 through N-1 of a[i] for b[k] = -1) */
|
||||
|
||||
for (k = 0; k < N; k++) {
|
||||
t[k] = -t[k];
|
||||
}
|
||||
|
||||
/* t[(i+k)%N] += sum i=0 through N-1 of a[i] for b[k] = +1 */
|
||||
|
||||
for (j = 0; j < bi_P1_len; j++) {
|
||||
k = bi[j];
|
||||
|
||||
for (i = 0; k < N; ++i, ++k) {
|
||||
t[k] = t[k] + a[i];
|
||||
}
|
||||
|
||||
for (k = 0; i < N; ++i, ++k) {
|
||||
t[k] = t[k] + a[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* c = (a * b) mod q */
|
||||
|
||||
for (k = 0; k < N; k++) {
|
||||
c[k] = t[k] & mod_q_mask;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,152 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
|
||||
/* ntru_ring_mult_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is a sparse trinary polynomial with coefficients -1, 0,
|
||||
* and 1. It is specified by a list, bi, of its nonzero indices containing
|
||||
* indices for the bi_P1_len +1 coefficients followed by the indices for the
|
||||
* bi_M1_len -1 coefficients.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* input array "b", or temp array "t".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
void ntru_ring_mult_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const bi_P1_len, /* in - no. of +1 coefficients in b */
|
||||
uint16_t const bi_M1_len, /* in - no. of -1 coefficients in b */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of ring element b,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t mod_q_mask;
|
||||
uint32_t mask_interval;
|
||||
uint16_t iA, iT, iB; /* Loop variables for the relevant arrays */
|
||||
uint16_t mask_time;
|
||||
uint16_t end;
|
||||
|
||||
uint32_t tmp1;
|
||||
uint32_t tmp2;
|
||||
|
||||
end = N & 0xfffe; /* 4 * floor((N-i)/4) */
|
||||
|
||||
mod_q_mask = q - 1;
|
||||
mask_interval = ((1 << 16) / q);
|
||||
mask_time = 0;
|
||||
|
||||
/* t[(i+k)%N] = sum i=0 through N-1 of a[i], for b[k] = -1 */
|
||||
memset(t, 0, N * sizeof(uint16_t));
|
||||
for (iB = bi_P1_len; iB < bi_P1_len + bi_M1_len; iB++) {
|
||||
/* first half -- iT from bi[iB] to N
|
||||
iA from 0 to N - bi[iB] */
|
||||
iT = bi[iB];
|
||||
|
||||
for (iA = 0; iT < end; iA += 2, iT += 2) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
if (iT < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
/* second half -- iT from 0 to bi[iB]
|
||||
iA from bi[iB] to N */
|
||||
|
||||
for (iT = 0; iA < end; iA += 2, iT += 2) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
if (iA < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
mask_time++;
|
||||
if (mask_time == mask_interval) {
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
t[iT] &= mod_q_mask;
|
||||
}
|
||||
mask_time = 0;
|
||||
}
|
||||
} /* for (iB = 0; iB < bi_M1_len; iB++) -- minus-index loop */
|
||||
|
||||
/* Minus everything */
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
t[iT] = -t[iT];
|
||||
t[iT] &= mod_q_mask;
|
||||
}
|
||||
mask_time = 0;
|
||||
|
||||
for (iB = 0; iB < bi_P1_len; iB++) {
|
||||
/* first half -- iT from bi[iB] to N
|
||||
iA from 0 to N - bi[iB] */
|
||||
iT = bi[iB];
|
||||
|
||||
for (iA = 0; iT < end; iA += 2, iT += 2) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
if (iT < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
/* second half -- iT from 0 to bi[iB]
|
||||
iA from bi[iB] to N */
|
||||
for (iT = 0; iA < end; iA += 2, iT += 2) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
if (iA < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
mask_time++;
|
||||
if (mask_time == mask_interval) {
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
t[iT] &= mod_q_mask;
|
||||
}
|
||||
mask_time = 0;
|
||||
}
|
||||
|
||||
} /* for (iB = 0; iB < bi_P1_len; iB++) -- plus-index loop */
|
||||
|
||||
/* c = (a * b) mod q */
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
c[iT] = t[iT] & mod_q_mask;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,186 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
|
||||
/* ntru_ring_mult_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is a sparse trinary polynomial with coefficients -1, 0,
|
||||
* and 1. It is specified by a list, bi, of its nonzero indices containing
|
||||
* indices for the bi_P1_len +1 coefficients followed by the indices for the
|
||||
* bi_M1_len -1 coefficients.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* input array "b", or temp array "t".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
void ntru_ring_mult_indices_64(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t bi_P1_len, /* in - no. of +1 coefficients in b */
|
||||
uint16_t bi_M1_len, /* in - no. of -1 coefficients in b */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of ring element b,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients */
|
||||
uint16_t N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t mod_q_mask;
|
||||
uint64_t full_mod_q_mask;
|
||||
uint32_t mask_interval;
|
||||
uint16_t iA, iT, iB; /* Loop variables for the relevant arrays */
|
||||
uint16_t mask_time;
|
||||
uint16_t oend[4];
|
||||
uint16_t end;
|
||||
uint16_t const Nmod4 = N & 3;
|
||||
|
||||
uint64_t tmp1;
|
||||
uint64_t tmp2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
oend[i] = (N - i) & 0xfffc; /* 4 * floor((N-i)/4) */
|
||||
}
|
||||
|
||||
mod_q_mask = q - 1;
|
||||
full_mod_q_mask = (mod_q_mask << 16) | mod_q_mask;
|
||||
full_mod_q_mask |= (full_mod_q_mask << 32);
|
||||
mask_interval = ((1 << 16) / q);
|
||||
|
||||
/* t[(i+k)%N] = sum i=0 through N-1 of a[i], for b[k] = -1 */
|
||||
|
||||
mask_time = 0;
|
||||
|
||||
memset(t, 0, N * sizeof(uint16_t));
|
||||
for (iB = bi_P1_len; iB < bi_P1_len + bi_M1_len; iB++) {
|
||||
/* first half -- from iT to N */
|
||||
iT = bi[iB];
|
||||
end = oend[iT & 3];
|
||||
|
||||
for (iA = 0; iT < end; iA += 4, iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
while (iT < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
/* second half -- from 0 to start -1 */
|
||||
|
||||
/* at this point we have used (N-bi[iB + bi_P1_len]) and iA should be
|
||||
* equal to bi[iB+bi_P1_len]+1.
|
||||
*/
|
||||
end = oend[iA & 3];
|
||||
|
||||
for (iT = 0; iA < end; iA += 4, iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp2);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
while (iA < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
mask_time++;
|
||||
if (mask_time == mask_interval) {
|
||||
memcpy(&tmp1, t, sizeof tmp1);
|
||||
tmp1 &= full_mod_q_mask;
|
||||
memcpy(t, &tmp1, sizeof tmp1);
|
||||
|
||||
end = oend[Nmod4];
|
||||
for (iT = Nmod4; iT < end; iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
tmp1 &= full_mod_q_mask;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
mask_time = 0;
|
||||
}
|
||||
} /* for (iB = 0; iB < bi_M1_len; iB++) -- minus-index loop */
|
||||
|
||||
/* Minus everything */
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
t[iT] = -t[iT];
|
||||
t[iT] &= mod_q_mask;
|
||||
}
|
||||
mask_time = 0;
|
||||
|
||||
for (iB = 0; iB < bi_P1_len; iB++) {
|
||||
/* first half -- from iT to N */
|
||||
iT = bi[iB];
|
||||
end = oend[iT & 3];
|
||||
|
||||
for (iA = 0; iT < end; iA += 4, iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp1);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
while (iT < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
/* second half -- from 0 to start -1 */
|
||||
|
||||
/* at this point we have used (N-bi[iB + bi_P1_len]) and iA should be
|
||||
* equal to bi[iB+bi_P1_len]+1.
|
||||
*/
|
||||
end = oend[iA & 3];
|
||||
|
||||
for (iT = 0; iA < end; iA += 4, iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
memcpy(&tmp2, a + iA, sizeof tmp1);
|
||||
tmp1 += tmp2;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
|
||||
while (iA < N) {
|
||||
t[iT] += a[iA];
|
||||
iT++;
|
||||
iA++;
|
||||
}
|
||||
|
||||
mask_time++;
|
||||
if (mask_time == mask_interval) {
|
||||
memcpy(&tmp1, t, sizeof tmp1);
|
||||
tmp1 &= full_mod_q_mask;
|
||||
memcpy(t, &tmp1, sizeof tmp1);
|
||||
|
||||
end = oend[Nmod4];
|
||||
for (iT = Nmod4; iT < end; iT += 4) {
|
||||
memcpy(&tmp1, t + iT, sizeof tmp1);
|
||||
tmp1 &= full_mod_q_mask;
|
||||
memcpy(t + iT, &tmp1, sizeof tmp1);
|
||||
}
|
||||
mask_time = 0;
|
||||
}
|
||||
|
||||
} /* for (iB = 0; iB < bi_P1_len; iB++) -- plus-index loop */
|
||||
|
||||
/* c = (a * b) mod q */
|
||||
for (iT = 0; iT < N; iT++) {
|
||||
c[iT] = t[iT] & mod_q_mask;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,149 +0,0 @@
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
#include <immintrin.h>
|
||||
|
||||
#define PAD(N) ((N + 0x0007) & 0xfff8)
|
||||
|
||||
void ntru_ring_mult_indices_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *tmp_polys,
|
||||
uint16_t *poly_coeffs) {
|
||||
if (tmp_polys) {
|
||||
*tmp_polys = 2;
|
||||
}
|
||||
|
||||
if (poly_coeffs) {
|
||||
*poly_coeffs = PAD(N);
|
||||
}
|
||||
}
|
||||
|
||||
/* ntru_ring_mult_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is a sparse trinary polynomial with coefficients -1, 0,
|
||||
* and 1. It is specified by a list, bi, of its nonzero indices containing
|
||||
* indices for the bi_P1_len +1 coefficients followed by the indices for the
|
||||
* bi_M1_len -1 coefficients.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* input array "b", or temp array "t".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
void ntru_ring_mult_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const bi_P1_len, /* in - no. of +1 coefficients in b */
|
||||
uint16_t const bi_M1_len, /* in - no. of -1 coefficients in b */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of ring element b,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
__m128i *T;
|
||||
__m128i *Tp;
|
||||
__m128i *Ti;
|
||||
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t k;
|
||||
uint16_t m;
|
||||
uint16_t const mod_q_mask = q - 1;
|
||||
|
||||
__m128i a0s[8];
|
||||
__m128i aNs[8];
|
||||
|
||||
__m128i neg;
|
||||
__m128i x0;
|
||||
__m128i x1;
|
||||
__m128i x2;
|
||||
__m128i x3;
|
||||
__m128i x4;
|
||||
|
||||
T = (__m128i *) t;
|
||||
memset(T, 0, 2 * PAD(N) * sizeof(uint16_t));
|
||||
|
||||
a0s[0] = _mm_lddqu_si128((__m128i *) a);
|
||||
aNs[0] = _mm_lddqu_si128((__m128i *) (a + N - 8));
|
||||
for (i = 1; i < 8; i++) {
|
||||
a0s[i] = _mm_slli_si128(a0s[i - 1], 2);
|
||||
aNs[i] = _mm_srli_si128(aNs[i - 1], 2);
|
||||
}
|
||||
|
||||
for (i = bi_P1_len; i < bi_P1_len + bi_M1_len; i++) {
|
||||
k = bi[i];
|
||||
m = k & 7;
|
||||
k /= 8;
|
||||
Tp = T + k;
|
||||
x2 = _mm_add_epi16(*Tp, a0s[m]);
|
||||
_mm_store_si128(Tp, x2);
|
||||
Tp++;
|
||||
for (j = 8 - m; j <= (N - 8); j += 8) {
|
||||
x3 = _mm_lddqu_si128((__m128i *) &a[j]);
|
||||
x2 = _mm_add_epi16(*Tp, x3);
|
||||
_mm_store_si128(Tp, x2);
|
||||
Tp++;
|
||||
}
|
||||
if (j == N)
|
||||
continue;
|
||||
x2 = _mm_add_epi16(*Tp, aNs[j - (N - 8)]);
|
||||
_mm_store_si128(Tp, x2);
|
||||
}
|
||||
|
||||
neg = _mm_setzero_si128();
|
||||
neg = _mm_cmpeq_epi8(neg, neg);
|
||||
Tp = T;
|
||||
for (i = 0; i < (2 * PAD(N)) / 8; i++) {
|
||||
x1 = _mm_sign_epi16(*Tp, neg);
|
||||
_mm_store_si128(Tp, x1);
|
||||
Tp++;
|
||||
}
|
||||
|
||||
for (i = 0; i < bi_P1_len; i++) {
|
||||
k = bi[i];
|
||||
m = k & 7;
|
||||
k /= 8;
|
||||
Tp = T + k;
|
||||
x2 = _mm_add_epi16(*Tp, a0s[m]);
|
||||
_mm_store_si128(Tp, x2);
|
||||
Tp++;
|
||||
for (j = 8 - m; j <= (N - 8); j += 8) {
|
||||
x3 = _mm_lddqu_si128((__m128i *) &a[j]);
|
||||
x2 = _mm_add_epi16(*Tp, x3);
|
||||
_mm_store_si128(Tp, x2);
|
||||
Tp++;
|
||||
}
|
||||
if (j == N)
|
||||
continue;
|
||||
x2 = _mm_add_epi16(*Tp, aNs[j - (N - 8)]);
|
||||
_mm_store_si128(Tp, x2);
|
||||
}
|
||||
|
||||
Ti = T;
|
||||
Tp = (__m128i *) (((uint16_t *) T) + N);
|
||||
x0 = _mm_set1_epi16(mod_q_mask);
|
||||
for (j = 0; j < N; j += 8) {
|
||||
x1 = _mm_load_si128(Ti);
|
||||
x2 = _mm_lddqu_si128(Tp);
|
||||
x3 = _mm_add_epi16(x1, x2);
|
||||
x4 = _mm_and_si128(x3, x0);
|
||||
_mm_store_si128(Ti, x4);
|
||||
Ti++;
|
||||
Tp++;
|
||||
}
|
||||
memmove(c, T, N * sizeof(uint16_t));
|
||||
for (j = N; j < PAD(N); j++) {
|
||||
c[j] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1,547 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_poly.c
|
||||
*
|
||||
* Contents: Routines for generating and operating on polynomials in the
|
||||
* NTRU algorithm.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_ntru_poly.h"
|
||||
#include "ntru_crypto_ntru_mgf1.h"
|
||||
|
||||
/* ntru_gen_poly
|
||||
*
|
||||
* Generates polynomials by creating for each polynomial, a list of the
|
||||
* indices of the +1 coefficients followed by a list of the indices of
|
||||
* the -1 coefficients.
|
||||
*
|
||||
* If a single polynomial is generated (non-product form), indices_counts
|
||||
* contains a single value of the total number of indices (for +1 and -1
|
||||
* comefficients combined).
|
||||
*
|
||||
* If multiple polynomials are generated (for product form), their lists of
|
||||
* indices are sequentially stored in the indices buffer. Each byte of
|
||||
* indices_counts contains the total number of indices (for +1 and -1
|
||||
* coefficients combined) for a single polynomial, beginning with the
|
||||
* low-order byte for the first polynomial. The high-order byte is unused.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns HASH_BAD_ALG if the algorithm is not supported.
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_gen_poly(
|
||||
NTRU_CRYPTO_HASH_ALGID hash_algid, /* in - hash algorithm ID for
|
||||
IGF-2 */
|
||||
uint8_t md_len, /* in - no. of octets in digest */
|
||||
uint8_t min_calls, /* in - minimum no. of hash
|
||||
calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t *seed, /* in - pointer to seed */
|
||||
uint8_t *buf, /* in - pointer to working
|
||||
buffer */
|
||||
uint16_t N, /* in - max index + 1 */
|
||||
uint8_t c_bits, /* in - no. bits for candidate */
|
||||
uint16_t limit, /* in - conversion to index
|
||||
limit */
|
||||
bool is_product_form, /* in - if generating multiple
|
||||
polys */
|
||||
uint32_t indices_counts, /* in - nos. of indices needed */
|
||||
uint16_t *indices) /* out - address for indices */
|
||||
{
|
||||
uint8_t *mgf_out;
|
||||
uint8_t *octets;
|
||||
uint8_t *used;
|
||||
uint8_t num_polys;
|
||||
uint16_t num_indices;
|
||||
uint16_t octets_available;
|
||||
uint16_t index_cnt = 0;
|
||||
uint8_t left = 0;
|
||||
uint8_t num_left = 0;
|
||||
uint32_t retcode;
|
||||
|
||||
/* generate minimum MGF1 output */
|
||||
|
||||
mgf_out = buf + md_len + 4;
|
||||
if ((retcode = ntru_mgf1(buf, hash_algid, md_len, min_calls,
|
||||
seed_len, seed, mgf_out)) != NTRU_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
octets = mgf_out;
|
||||
octets_available = min_calls * md_len;
|
||||
|
||||
/* init indices counts for number of polynomials being generated */
|
||||
|
||||
if (is_product_form) {
|
||||
/* number of indices for poly1 is in low byte of indices_counts,
|
||||
* number of indices for poly2 and poly3 are in next higher bytes
|
||||
*/
|
||||
|
||||
num_polys = 3;
|
||||
num_indices = (uint16_t)(indices_counts & 0xff);
|
||||
indices_counts >>= 8;
|
||||
|
||||
} else {
|
||||
/* number of bytes for poly is in low 16 bits of indices_counts */
|
||||
|
||||
num_polys = 1;
|
||||
num_indices = (uint16_t) indices_counts;
|
||||
}
|
||||
|
||||
/* init used-index array */
|
||||
|
||||
used = mgf_out + octets_available;
|
||||
memset(used, 0, N);
|
||||
|
||||
/* generate indices (IGF-2) for all polynomials */
|
||||
|
||||
while (num_polys > 0) {
|
||||
|
||||
/* generate indices for a single polynomial */
|
||||
|
||||
while (index_cnt < num_indices) {
|
||||
uint16_t index;
|
||||
uint8_t num_needed;
|
||||
|
||||
/* form next index to convert to an index */
|
||||
|
||||
do {
|
||||
/* use any leftover bits first */
|
||||
|
||||
if (num_left != 0) {
|
||||
index = left << (c_bits - num_left);
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
/* get the rest of the bits needed from new octets */
|
||||
|
||||
num_needed = c_bits - num_left;
|
||||
while (num_needed != 0) {
|
||||
/* get another octet */
|
||||
|
||||
if (octets_available == 0) {
|
||||
if ((retcode = ntru_mgf1(buf, hash_algid, md_len, 1,
|
||||
0, NULL, mgf_out)) != NTRU_OK) {
|
||||
return retcode;
|
||||
}
|
||||
|
||||
octets = mgf_out;
|
||||
octets_available = md_len;
|
||||
}
|
||||
left = *octets++;
|
||||
--octets_available;
|
||||
|
||||
if (num_needed <= 8) {
|
||||
/* all bits needed to fill the index are in this octet */
|
||||
|
||||
index |= ((uint16_t)(left)) >> (8 - num_needed);
|
||||
num_left = 8 - num_needed;
|
||||
num_needed = 0;
|
||||
left &= 0xff >> (8 - num_left);
|
||||
|
||||
} else {
|
||||
/* another octet will be needed after using this
|
||||
* whole octet
|
||||
*/
|
||||
|
||||
index |= ((uint16_t) left) << (num_needed - 8);
|
||||
num_needed -= 8;
|
||||
}
|
||||
}
|
||||
} while (index >= limit);
|
||||
|
||||
/* form index and check if unique */
|
||||
|
||||
index %= N;
|
||||
|
||||
if (!used[index]) {
|
||||
used[index] = 1;
|
||||
indices[index_cnt] = index;
|
||||
++index_cnt;
|
||||
}
|
||||
}
|
||||
--num_polys;
|
||||
|
||||
/* init for next polynomial if another polynomial to be generated */
|
||||
|
||||
if (num_polys > 0) {
|
||||
memset(used, 0, N);
|
||||
num_indices = num_indices +
|
||||
(uint16_t)(indices_counts & 0xff);
|
||||
indices_counts >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
|
||||
/* ntru_poly_check_min_weight
|
||||
*
|
||||
* Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
|
||||
* a minimum weight.
|
||||
*/
|
||||
|
||||
bool ntru_poly_check_min_weight(
|
||||
uint16_t num_els, /* in - degree of polynomial */
|
||||
uint8_t *ringels, /* in - pointer to trinary ring elements */
|
||||
uint16_t min_wt) /* in - minimum weight */
|
||||
{
|
||||
uint16_t wt[3];
|
||||
uint16_t i;
|
||||
|
||||
wt[0] = wt[1] = wt[2] = 0;
|
||||
|
||||
for (i = 0; i < num_els; i++) {
|
||||
++wt[ringels[i]];
|
||||
}
|
||||
|
||||
if ((wt[0] < min_wt) || (wt[1] < min_wt) || (wt[2] < min_wt)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ntru_ring_mult_product_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is represented by the product form b1 * b2 + b3, where
|
||||
* b1, b2, and b3 are each a sparse trinary polynomial with coefficients -1,
|
||||
* 0, and 1. It is specified by a list, bi, of the nonzero indices of b1, b2,
|
||||
* and b3, containing the indices for the +1 coefficients followed by the
|
||||
* indices for the -1 coefficients for each polynomial in that order.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* or input array "b".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
void ntru_ring_mult_product_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const b1i_len, /* in - no. of +1 or -1 coefficients in b1 */
|
||||
uint16_t const b2i_len, /* in - no. of +1 or -1 coefficients in b2 */
|
||||
uint16_t const b3i_len, /* in - no. of +1 or -1 coefficients in b3 */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of polynomials b1, b2, b3,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients for
|
||||
each polynomial */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t scratch_polys;
|
||||
uint16_t poly_coeffs;
|
||||
uint16_t *t2;
|
||||
uint16_t mod_q_mask;
|
||||
uint16_t i;
|
||||
|
||||
ntru_ring_mult_indices_memreq(N, &scratch_polys, &poly_coeffs);
|
||||
t2 = t + scratch_polys * poly_coeffs;
|
||||
mod_q_mask = q - 1;
|
||||
|
||||
/* t2 = a * b1 */
|
||||
|
||||
ntru_ring_mult_indices(a, b1i_len, b1i_len, bi, N, q, t, t2);
|
||||
|
||||
/* t2 = (a * b1) * b2 */
|
||||
|
||||
ntru_ring_mult_indices(t2, b2i_len, b2i_len, bi + (b1i_len << 1), N, q,
|
||||
t, t2);
|
||||
|
||||
/* t = a * b3 */
|
||||
|
||||
ntru_ring_mult_indices(a, b3i_len, b3i_len,
|
||||
bi + ((b1i_len + b2i_len) << 1), N, q, t, t);
|
||||
|
||||
/* c = (a * b1 * b2) + (a * b3) */
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
c[i] = (t2[i] + t[i]) & mod_q_mask;
|
||||
}
|
||||
for (; i < poly_coeffs; i++) {
|
||||
c[i] = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* ntru_ring_inv
|
||||
*
|
||||
* Finds the inverse of a polynomial, a, in (Z/2Z)[X]/(X^N - 1).
|
||||
*/
|
||||
|
||||
bool ntru_ring_inv(
|
||||
uint16_t *a, /* in - pointer to polynomial a */
|
||||
uint16_t N, /* in - no. of coefficients in a */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
uint16_t *a_inv) /* out - address for polynomial a^-1 */
|
||||
{
|
||||
uint8_t *b = (uint8_t *) t; /* b cannot be in a_inv since it must be
|
||||
rotated and copied there as a^-1 mod 2 */
|
||||
uint8_t *c = b + N; /* c cannot be in a_inv since it exchanges
|
||||
with b, and b cannot be in a_inv */
|
||||
uint8_t *f = c + N;
|
||||
uint8_t *g = (uint8_t *) a_inv; /* g needs N + 1 bytes */
|
||||
uint16_t deg_b;
|
||||
uint16_t deg_c;
|
||||
uint16_t deg_f;
|
||||
uint16_t deg_g;
|
||||
uint16_t k = 0;
|
||||
uint16_t i, j;
|
||||
|
||||
if (a == NULL || t == NULL || a_inv == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* form a^-1 in (Z/2Z)[X]/(X^N - 1) */
|
||||
|
||||
memset(b, 0, (N << 1)); /* clear to init b, c */
|
||||
|
||||
/* b(X) = 1 */
|
||||
|
||||
b[0] = 1;
|
||||
deg_b = 0;
|
||||
|
||||
/* c(X) = 0 (cleared above) */
|
||||
|
||||
deg_c = 0;
|
||||
|
||||
/* f(X) = a(X) mod 2 */
|
||||
|
||||
deg_f = 0;
|
||||
j = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
f[i] = (uint8_t)(a[i] & 1);
|
||||
j ^= f[i];
|
||||
if (f[i])
|
||||
deg_f = i;
|
||||
}
|
||||
|
||||
/* Parity is zero, not invertible */
|
||||
if (j == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* g(X) = X^N - 1 */
|
||||
|
||||
g[0] = 1;
|
||||
memset(g + 1, 0, N - 1);
|
||||
g[N] = 1;
|
||||
deg_g = N;
|
||||
|
||||
/* until f(X) = 1 */
|
||||
|
||||
while (1) {
|
||||
/* while f[0] = 0, f(X) /= X, c(X) *= X, k++ */
|
||||
|
||||
for (i = 0; (i <= deg_f) && (f[i] == 0); ++i)
|
||||
;
|
||||
if (i > deg_f)
|
||||
return FALSE;
|
||||
if (i) {
|
||||
k = k + i;
|
||||
|
||||
f = f + i;
|
||||
deg_f = deg_f - i;
|
||||
|
||||
memmove(c + i, c, deg_c + 1);
|
||||
memset(c, 0, i);
|
||||
deg_c = deg_c + i;
|
||||
}
|
||||
|
||||
/* if f(X) = 1, done */
|
||||
|
||||
if (deg_f == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* if deg_f < deg_g, f <-> g, b <-> c */
|
||||
|
||||
if (deg_f < deg_g) {
|
||||
uint8_t *x;
|
||||
|
||||
x = f;
|
||||
f = g;
|
||||
g = x;
|
||||
deg_f ^= deg_g;
|
||||
deg_g ^= deg_f;
|
||||
deg_f ^= deg_g;
|
||||
x = b;
|
||||
b = c;
|
||||
c = x;
|
||||
deg_b ^= deg_c;
|
||||
deg_c ^= deg_b;
|
||||
deg_b ^= deg_c;
|
||||
}
|
||||
|
||||
/* f(X) += g(X)
|
||||
* might change degree of f if deg_g >= deg_f
|
||||
*/
|
||||
for (i = 0; i <= deg_g; i++) {
|
||||
f[i] ^= g[i];
|
||||
}
|
||||
|
||||
if (deg_g == deg_f) {
|
||||
while (deg_f > 0 && f[deg_f] == 0) {
|
||||
--deg_f;
|
||||
}
|
||||
}
|
||||
|
||||
/* b(X) += c(X) */
|
||||
for (i = 0; i <= deg_c; i++) {
|
||||
b[i] ^= c[i];
|
||||
}
|
||||
|
||||
if (deg_c >= deg_b) {
|
||||
deg_b = deg_c;
|
||||
while (deg_b > 0 && b[deg_b] == 0) {
|
||||
--deg_b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* a^-1 in (Z/2Z)[X]/(X^N - 1) = b(X) shifted left k coefficients */
|
||||
|
||||
j = 0;
|
||||
|
||||
if (k >= N) {
|
||||
k = k - N;
|
||||
}
|
||||
|
||||
for (i = k; i < N; i++) {
|
||||
a_inv[j++] = (uint16_t)(b[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < k; i++) {
|
||||
a_inv[j++] = (uint16_t)(b[i]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* ntru_ring_lift_inv_pow2_product
|
||||
*
|
||||
* Lifts an element of (Z/2)[x]/(x^N - 1) to (Z/q)[x]/(x^N - 1)
|
||||
* where q is a power of 2 such that 256 < q <= 65536.
|
||||
*
|
||||
* inv must be padded with zeros to the degree used by
|
||||
* ntru_ring_mult_coefficients.
|
||||
*
|
||||
* inv is assumed to be the inverse mod 2 of the product form element
|
||||
* given by (1 + 3*(F1*F2 + F3)). The lift is performed in place --
|
||||
* inv will be overwritten with the result.
|
||||
*
|
||||
* Requires scratch space for ntru_ring_mult_coefficients + one extra
|
||||
* polynomial with the same padding.
|
||||
*/
|
||||
uint32_t
|
||||
ntru_ring_lift_inv_pow2_product(
|
||||
uint16_t *inv,
|
||||
uint16_t const dF1,
|
||||
uint16_t const dF2,
|
||||
uint16_t const dF3,
|
||||
uint16_t const *F_buf,
|
||||
uint16_t const N,
|
||||
uint16_t const q,
|
||||
uint16_t *t) {
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t mod_q_mask = q - 1;
|
||||
uint16_t padN;
|
||||
ntru_ring_mult_coefficients_memreq(N, NULL, &padN);
|
||||
|
||||
for (j = 0; j < 4; ++j) /* assumes 256 < q <= 65536 */
|
||||
{
|
||||
/* f^-1 = f^-1 * (2 - f * f^-1) mod q */
|
||||
ntru_ring_mult_product_indices(inv, (uint16_t) dF1,
|
||||
(uint16_t) dF2, (uint16_t) dF3,
|
||||
F_buf, N, q,
|
||||
t, t);
|
||||
for (i = 0; i < N; ++i) {
|
||||
t[i] = -((inv[i] + 3 * t[i]) & mod_q_mask);
|
||||
}
|
||||
t[0] = t[0] + 2;
|
||||
/* mult_indices works with degree N, mult_coefficients with padN */
|
||||
memset(t + N, 0, (padN - N) * sizeof(uint16_t));
|
||||
|
||||
ntru_ring_mult_coefficients(inv, t, N, q, t + padN, inv);
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
|
||||
/* ntru_ring_lift_inv_pow2_standard
|
||||
*
|
||||
* Lifts an element of (Z/2)[x]/(x^N - 1) to (Z/q)[x]/(x^N - 1)
|
||||
* where q is a power of 2 such that 256 < q <= 65536.
|
||||
*
|
||||
* inv must be padded with zeros to the degree used by
|
||||
* ntru_ring_mult_coefficients.
|
||||
*
|
||||
* inv is assumed to be the inverse mod 2 of the trinary element f.
|
||||
* The lift is performed in place -- inv will be overwritten with the result.
|
||||
*
|
||||
* Requires scratch space for ntru_ring_mult_coefficients + one extra
|
||||
* polynomial with the same padding.
|
||||
*/
|
||||
uint32_t
|
||||
ntru_ring_lift_inv_pow2_standard(
|
||||
uint16_t *inv,
|
||||
uint16_t const *f,
|
||||
uint16_t const N,
|
||||
uint16_t const q,
|
||||
uint16_t *t) {
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t padN;
|
||||
ntru_ring_mult_coefficients_memreq(N, NULL, &padN);
|
||||
|
||||
for (j = 0; j < 4; ++j) /* assumes 256 < q <= 65536 */
|
||||
{
|
||||
/* f^-1 = f^-1 * (2 - f * f^-1) mod q */
|
||||
ntru_ring_mult_coefficients(f, inv, N, q, t, t);
|
||||
for (i = 0; i < N; ++i) {
|
||||
t[i] = -t[i];
|
||||
}
|
||||
t[0] = t[0] + 2;
|
||||
|
||||
ntru_ring_mult_coefficients(inv, t, N, q, t + padN, inv);
|
||||
}
|
||||
|
||||
NTRU_RET(NTRU_OK);
|
||||
}
|
||||
@ -1,280 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_ntru_poly.h
|
||||
*
|
||||
* Contents: Public header file for generating and operating on polynomials
|
||||
* in the NTRU algorithm.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_NTRU_POLY_H
|
||||
#define NTRU_CRYPTO_NTRU_POLY_H
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_hash_basics.h"
|
||||
|
||||
/* function declarations */
|
||||
|
||||
/* ntru_gen_poly
|
||||
*
|
||||
* Generates polynomials by creating for each polynomial, a list of the
|
||||
* indices of the +1 coefficients followed by a list of the indices of
|
||||
* the -1 coefficients.
|
||||
*
|
||||
* If a single polynomial is generated (non-product form), indices_counts
|
||||
* contains a single value of the total number of indices (for +1 and -1
|
||||
* comefficients combined).
|
||||
*
|
||||
* If multiple polynomials are generated (for product form), their lists of
|
||||
* indices are sequentially stored in the indices buffer. Each byte of
|
||||
* indices_counts contains the total number of indices (for +1 and -1
|
||||
* coefficients combined) for a single polynomial, beginning with the
|
||||
* low-order byte for the first polynomial. The high-order byte is unused.
|
||||
*
|
||||
* Returns NTRU_OK if successful.
|
||||
* Returns HASH_BAD_ALG if the algorithm is not supported.
|
||||
*
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_gen_poly(
|
||||
NTRU_CRYPTO_HASH_ALGID hash_algid, /* in - hash algorithm ID for
|
||||
IGF-2 */
|
||||
uint8_t md_len, /* in - no. of octets in digest */
|
||||
uint8_t min_calls, /* in - minimum no. of hash
|
||||
calls */
|
||||
uint16_t seed_len, /* in - no. of octets in seed */
|
||||
uint8_t *seed, /* in - pointer to seed */
|
||||
uint8_t *buf, /* in - pointer to working
|
||||
buffer */
|
||||
uint16_t N, /* in - max index + 1 */
|
||||
uint8_t c_bits, /* in - no. bits for candidate */
|
||||
uint16_t limit, /* in - conversion to index
|
||||
limit */
|
||||
bool is_product_form, /* in - if generating multiple
|
||||
polys */
|
||||
uint32_t indices_counts, /* in - nos. of indices needed */
|
||||
uint16_t *indices); /* out - address for indices */
|
||||
|
||||
/* ntru_poly_check_min_weight
|
||||
*
|
||||
* Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
|
||||
* a minimum weight.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
ntru_poly_check_min_weight(
|
||||
uint16_t num_els, /* in - degree of polynomial */
|
||||
uint8_t *ringels, /* in - pointer to trinary ring elements */
|
||||
uint16_t min_wt); /* in - minimum weight */
|
||||
|
||||
/* ntru_ring_mult_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is a sparse trinary polynomial with coefficients -1, 0,
|
||||
* and 1. It is specified by a list, bi, of its nonzero indices containing
|
||||
* indices for the bi_P1_len +1 coefficients followed by the indices for the
|
||||
* bi_M1_len -1 coefficients.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* or input array "b".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
/* wrapper */
|
||||
extern void
|
||||
ntru_ring_mult_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const bi_P1_len, /* in - no. of +1 coefficients in b */
|
||||
uint16_t const bi_M1_len, /* in - no. of -1 coefficients in b */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of ring element b,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer. Size is impl dependent.
|
||||
see ntru_ring_mult_indices_memreq */
|
||||
uint16_t *c); /* out - address for polynomial c */
|
||||
|
||||
/* ntru_ring_mult_product_indices
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* Ring element "b" is represented by the product form b1 * b2 + b3, where
|
||||
* b1, b2, and b3 are each a sparse trinary polynomial with coefficients -1,
|
||||
* 0, and 1. It is specified by a list, bi, of the nonzero indices of b1, b2,
|
||||
* and b3, containing the indices for the +1 coefficients followed by the
|
||||
* indices for the -1 coefficients for each polynomial in that order.
|
||||
* The indices are in the range [0,N).
|
||||
*
|
||||
* The result array "c" may share the same memory space as input array "a",
|
||||
* or input array "b".
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_ring_mult_product_indices(
|
||||
uint16_t const *a, /* in - pointer to ring element a */
|
||||
uint16_t const b1i_len, /* in - no. of +1 or -1 coefficients in b1 */
|
||||
uint16_t const b2i_len, /* in - no. of +1 or -1 coefficients in b2 */
|
||||
uint16_t const b3i_len, /* in - no. of +1 or -1 coefficients in b3 */
|
||||
uint16_t const *bi, /* in - pointer to the list of nonzero
|
||||
indices of polynomials b1, b2, b3,
|
||||
containing indices for the +1
|
||||
coefficients followed by the
|
||||
indices for -1 coefficients for
|
||||
each polynomial */
|
||||
uint16_t const N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t const q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer. Size is impl dependent.
|
||||
see ntru_ring_mult_indices_memreq */
|
||||
uint16_t *c); /* out - address for polynomial c */
|
||||
|
||||
/* ntru_ring_mult_coefficients
|
||||
*
|
||||
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
|
||||
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
|
||||
* This is a convolution operation.
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
|
||||
* beyond 16 bits does not matter.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_ring_mult_coefficients(
|
||||
uint16_t const *a, /* in - pointer to polynomial a */
|
||||
uint16_t const *b, /* in - pointer to polynomial b */
|
||||
uint16_t N, /* in - degree of (x^N - 1) */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *tmp, /* in - temp buffer. Size is impl dependent.
|
||||
see ntru_ring_mult_coefficients_memreq */
|
||||
uint16_t *c); /* out - address for polynomial c */
|
||||
|
||||
/* ntru_ring_inv
|
||||
*
|
||||
* Finds the inverse of a polynomial, a, in (Z/2^rZ)[X]/(X^N - 1).
|
||||
*
|
||||
* This assumes q is 2^r where 8 < r < 16, so that operations mod q can
|
||||
* wait until the end, and only 16-bit arrays need to be used.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
ntru_ring_inv(
|
||||
uint16_t *a, /* in - pointer to polynomial a */
|
||||
uint16_t N, /* in - no. of coefficients in a */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
uint16_t *a_inv); /* out - address for polynomial a^-1 */
|
||||
|
||||
/* ntru_ring_lift_inv_pow2_standard
|
||||
*
|
||||
* Lifts an element of (Z/2)[x]/(x^N - 1) to (Z/q)[x]/(x^N - 1)
|
||||
* where q is a power of 2 such that 256 < q <= 65536.
|
||||
*
|
||||
* inv must be padded with zeros to the degree used by
|
||||
* ntru_ring_mult_coefficients.
|
||||
*
|
||||
* inv is assumed to be the inverse mod 2 of the trinary element f.
|
||||
* The lift is performed in place -- inv will be overwritten with the result.
|
||||
*
|
||||
* Requires scratch space for ntru_ring_mult_coefficients + one extra
|
||||
* polynomial with the same padding.
|
||||
*/
|
||||
uint32_t
|
||||
ntru_ring_lift_inv_pow2_standard(
|
||||
uint16_t *inv,
|
||||
uint16_t const *f,
|
||||
uint16_t const N,
|
||||
uint16_t const q,
|
||||
uint16_t *t);
|
||||
|
||||
/* ntru_ring_lift_inv_pow2_product
|
||||
*
|
||||
* Lifts an element of (Z/2)[x]/(x^N - 1) to (Z/q)[x]/(x^N - 1)
|
||||
* where q is a power of 2 such that 256 < q <= 65536.
|
||||
*
|
||||
* inv must be padded with zeros to the degree used by
|
||||
* ntru_ring_mult_coefficients.
|
||||
*
|
||||
* inv is assumed to be the inverse mod 2 of the product form element
|
||||
* given by (1 + 3*(F1*F2 + F3)). The lift is performed in place --
|
||||
* inv will be overwritten with the result.
|
||||
*
|
||||
* Requires scratch space for ntru_ring_mult_coefficients + one extra
|
||||
* polynomial with the same padding.
|
||||
*/
|
||||
uint32_t
|
||||
ntru_ring_lift_inv_pow2_product(
|
||||
uint16_t *inv,
|
||||
uint16_t const dF1,
|
||||
uint16_t const dF2,
|
||||
uint16_t const dF3,
|
||||
uint16_t const *F_buf,
|
||||
uint16_t const N,
|
||||
uint16_t const q,
|
||||
uint16_t *t);
|
||||
|
||||
/* ntru_ring_mult_coefficients_memreq
|
||||
*
|
||||
* Different implementations of ntru_ring_mult_coefficients may
|
||||
* have different memory requirements.
|
||||
*
|
||||
* This gets the memory requirements of ntru_ring_mult_coefficients as
|
||||
* a number of scratch polynomials and the number of coefficients needed
|
||||
* per polynomial.
|
||||
*/
|
||||
void ntru_ring_mult_coefficients_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *num_scratch_polys,
|
||||
uint16_t *pad_deg);
|
||||
|
||||
/* ntru_ring_mult_indices_memreq
|
||||
*
|
||||
* Different implementations of ntru_ring_mult_indices may
|
||||
* have different memory requirements.
|
||||
*
|
||||
* This gets the memory requirements of ntru_ring_mult_indices as
|
||||
* a number of scratch polynomials (num_scratch_polys) and the number
|
||||
* of coefficients needed per polynomial (pad_deg).
|
||||
*
|
||||
* Note that ntru_ring_mult_prod_indices requires one additional polynomial
|
||||
* of degree pad_deg for holding a temporary result.
|
||||
*/
|
||||
void ntru_ring_mult_indices_memreq(
|
||||
uint16_t N,
|
||||
uint16_t *num_scratch_polys,
|
||||
uint16_t *pad_deg);
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_POLY_H */
|
||||
@ -1,92 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_platform.h
|
||||
*
|
||||
* Contents: Platform-specific basic definitions.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_PLATFORM_H
|
||||
#define NTRU_CRYPTO_PLATFORM_H
|
||||
|
||||
/* The default implementation is to use stdint.h, a part of the C99 standard.
|
||||
* Systems that don't support this are handled on a case-by-case basis.
|
||||
*/
|
||||
|
||||
#if defined(WIN32) && (_MSC_VER < 1600)
|
||||
|
||||
#include <basetsd.h>
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef short int int16_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
||||
|
||||
#elif defined(linux) && defined(__KERNEL__)
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#endif
|
||||
|
||||
/* For linux kernel drivers:
|
||||
* Use kmalloc and kfree in place of malloc / free
|
||||
* Use BUG_ON in place of assert */
|
||||
#if defined(linux) && defined(__KERNEL__)
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#define MALLOC(size) (kmalloc(size, GFP_KERNEL))
|
||||
#define FREE(x) (kfree(x))
|
||||
|
||||
#else
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#define MALLOC(size) (malloc(size))
|
||||
#define FREE(x) (free(x))
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_BOOL) && !defined(__cplusplus)
|
||||
#define HAVE_BOOL
|
||||
typedef uint8_t bool;
|
||||
#endif /* HAVE_BOOL */
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#endif /* NTRU_CRYPTO_PLATFORM_H */
|
||||
@ -1,56 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha.h
|
||||
*
|
||||
* Contents: Definitions and declarations common to all SHA hash algorithms.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_SHA_H
|
||||
#define NTRU_CRYPTO_SHA_H
|
||||
|
||||
#include "ntru_crypto_error.h"
|
||||
#include "ntru_crypto_hash_basics.h"
|
||||
|
||||
/***************
|
||||
* error codes *
|
||||
***************/
|
||||
|
||||
#define SHA_OK ((uint32_t) NTRU_CRYPTO_HASH_OK)
|
||||
#define SHA_FAIL ((uint32_t) NTRU_CRYPTO_HASH_FAIL)
|
||||
#define SHA_BAD_PARAMETER ((uint32_t) NTRU_CRYPTO_HASH_BAD_PARAMETER)
|
||||
#define SHA_OVERFLOW ((uint32_t) NTRU_CRYPTO_HASH_OVERFLOW)
|
||||
|
||||
#define SHA_RESULT(r) ((uint32_t)((r) ? SHA_ERROR_BASE + (r) : (r)))
|
||||
#define SHA_RET(r) return SHA_RESULT(r);
|
||||
|
||||
/*********
|
||||
* flags *
|
||||
*********/
|
||||
|
||||
#define SHA_DATA_ONLY HASH_DATA_ONLY
|
||||
#define SHA_INIT HASH_INIT
|
||||
#define SHA_FINISH HASH_FINISH
|
||||
|
||||
#endif /* NTRU_CRYPTO_SHA_H */
|
||||
@ -1,679 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha1.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-1 hash calculation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_sha1.h"
|
||||
#include "ntru_crypto_msbyte_uint32.h"
|
||||
|
||||
/* chaining state elements */
|
||||
|
||||
#define H0 state[0]
|
||||
#define H1 state[1]
|
||||
#define H2 state[2]
|
||||
#define H3 state[3]
|
||||
#define H4 state[4]
|
||||
|
||||
/* standard SHA-1 initialization values */
|
||||
|
||||
#define H0_INIT 0x67452301UL
|
||||
#define H1_INIT 0xefcdab89UL
|
||||
#define H2_INIT 0x98badcfeUL
|
||||
#define H3_INIT 0x10325476UL
|
||||
#define H4_INIT 0xc3d2e1f0UL
|
||||
|
||||
/* sha1_blk()
|
||||
*
|
||||
* This routine updates the current hash output (chaining state)
|
||||
* by performing SHA-1 on a 512-bit block of data represented as sixteen
|
||||
* 32-bit words.
|
||||
*/
|
||||
|
||||
#define K00_19 0x5a827999UL
|
||||
#define K20_39 0x6ed9eba1UL
|
||||
#define K40_59 0x8f1bbcdcUL
|
||||
#define K60_79 0xca62c1d6UL
|
||||
|
||||
#define RL(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
|
||||
|
||||
static void
|
||||
sha1_blk(
|
||||
uint32_t const *data, /* in - ptr to 16 32-bit word input block */
|
||||
uint32_t *state) /* in/out - ptr to 5 32-bit word chaining state */
|
||||
{
|
||||
uint32_t A, B, C, D, E;
|
||||
uint32_t w[16];
|
||||
|
||||
/* init A - E */
|
||||
|
||||
A = H0;
|
||||
B = H1;
|
||||
C = H2;
|
||||
D = H3;
|
||||
E = H4;
|
||||
|
||||
/* rounds 0 - 15 */
|
||||
|
||||
E += RL(A, 5) + K00_19 + ((B & (C ^ D)) ^ D) + data[0];
|
||||
B = RL(B, 30);
|
||||
D += RL(E, 5) + K00_19 + ((A & (B ^ C)) ^ C) + data[1];
|
||||
A = RL(A, 30);
|
||||
C += RL(D, 5) + K00_19 + ((E & (A ^ B)) ^ B) + data[2];
|
||||
E = RL(E, 30);
|
||||
B += RL(C, 5) + K00_19 + ((D & (E ^ A)) ^ A) + data[3];
|
||||
D = RL(D, 30);
|
||||
A += RL(B, 5) + K00_19 + ((C & (D ^ E)) ^ E) + data[4];
|
||||
C = RL(C, 30);
|
||||
E += RL(A, 5) + K00_19 + ((B & (C ^ D)) ^ D) + data[5];
|
||||
B = RL(B, 30);
|
||||
D += RL(E, 5) + K00_19 + ((A & (B ^ C)) ^ C) + data[6];
|
||||
A = RL(A, 30);
|
||||
C += RL(D, 5) + K00_19 + ((E & (A ^ B)) ^ B) + data[7];
|
||||
E = RL(E, 30);
|
||||
B += RL(C, 5) + K00_19 + ((D & (E ^ A)) ^ A) + data[8];
|
||||
D = RL(D, 30);
|
||||
A += RL(B, 5) + K00_19 + ((C & (D ^ E)) ^ E) + data[9];
|
||||
C = RL(C, 30);
|
||||
E += RL(A, 5) + K00_19 + ((B & (C ^ D)) ^ D) + data[10];
|
||||
B = RL(B, 30);
|
||||
D += RL(E, 5) + K00_19 + ((A & (B ^ C)) ^ C) + data[11];
|
||||
A = RL(A, 30);
|
||||
C += RL(D, 5) + K00_19 + ((E & (A ^ B)) ^ B) + data[12];
|
||||
E = RL(E, 30);
|
||||
B += RL(C, 5) + K00_19 + ((D & (E ^ A)) ^ A) + data[13];
|
||||
D = RL(D, 30);
|
||||
A += RL(B, 5) + K00_19 + ((C & (D ^ E)) ^ E) + data[14];
|
||||
C = RL(C, 30);
|
||||
E += RL(A, 5) + K00_19 + ((B & (C ^ D)) ^ D) + data[15];
|
||||
B = RL(B, 30);
|
||||
|
||||
/* rounds 16 - 19 */
|
||||
|
||||
w[0] = data[0] ^ data[2] ^ data[8] ^ data[13];
|
||||
w[0] = RL(w[0], 1);
|
||||
D += RL(E, 5) + K00_19 + ((A & (B ^ C)) ^ C) + w[0];
|
||||
A = RL(A, 30);
|
||||
w[1] = data[1] ^ data[3] ^ data[9] ^ data[14];
|
||||
w[1] = RL(w[1], 1);
|
||||
C += RL(D, 5) + K00_19 + ((E & (A ^ B)) ^ B) + w[1];
|
||||
E = RL(E, 30);
|
||||
w[2] = data[2] ^ data[4] ^ data[10] ^ data[15];
|
||||
w[2] = RL(w[2], 1);
|
||||
B += RL(C, 5) + K00_19 + ((D & (E ^ A)) ^ A) + w[2];
|
||||
D = RL(D, 30);
|
||||
w[3] = data[3] ^ data[5] ^ data[11] ^ w[0];
|
||||
w[3] = RL(w[3], 1);
|
||||
A += RL(B, 5) + K00_19 + ((C & (D ^ E)) ^ E) + w[3];
|
||||
C = RL(C, 30);
|
||||
|
||||
/* rounds 20 - 39 */
|
||||
|
||||
w[4] = data[4] ^ data[6] ^ data[12] ^ w[1];
|
||||
w[4] = RL(w[4], 1);
|
||||
E += RL(A, 5) + K20_39 + (B ^ C ^ D) + w[4];
|
||||
B = RL(B, 30);
|
||||
w[5] = data[5] ^ data[7] ^ data[13] ^ w[2];
|
||||
w[5] = RL(w[5], 1);
|
||||
D += RL(E, 5) + K20_39 + (A ^ B ^ C) + w[5];
|
||||
A = RL(A, 30);
|
||||
w[6] = data[6] ^ data[8] ^ data[14] ^ w[3];
|
||||
w[6] = RL(w[6], 1);
|
||||
C += RL(D, 5) + K20_39 + (E ^ A ^ B) + w[6];
|
||||
E = RL(E, 30);
|
||||
w[7] = data[7] ^ data[9] ^ data[15] ^ w[4];
|
||||
w[7] = RL(w[7], 1);
|
||||
B += RL(C, 5) + K20_39 + (D ^ E ^ A) + w[7];
|
||||
D = RL(D, 30);
|
||||
w[8] = data[8] ^ data[10] ^ w[0] ^ w[5];
|
||||
w[8] = RL(w[8], 1);
|
||||
A += RL(B, 5) + K20_39 + (C ^ D ^ E) + w[8];
|
||||
C = RL(C, 30);
|
||||
w[9] = data[9] ^ data[11] ^ w[1] ^ w[6];
|
||||
w[9] = RL(w[9], 1);
|
||||
E += RL(A, 5) + K20_39 + (B ^ C ^ D) + w[9];
|
||||
B = RL(B, 30);
|
||||
w[10] = data[10] ^ data[12] ^ w[2] ^ w[7];
|
||||
w[10] = RL(w[10], 1);
|
||||
D += RL(E, 5) + K20_39 + (A ^ B ^ C) + w[10];
|
||||
A = RL(A, 30);
|
||||
w[11] = data[11] ^ data[13] ^ w[3] ^ w[8];
|
||||
w[11] = RL(w[11], 1);
|
||||
C += RL(D, 5) + K20_39 + (E ^ A ^ B) + w[11];
|
||||
E = RL(E, 30);
|
||||
w[12] = data[12] ^ data[14] ^ w[4] ^ w[9];
|
||||
w[12] = RL(w[12], 1);
|
||||
B += RL(C, 5) + K20_39 + (D ^ E ^ A) + w[12];
|
||||
D = RL(D, 30);
|
||||
w[13] = data[13] ^ data[15] ^ w[5] ^ w[10];
|
||||
w[13] = RL(w[13], 1);
|
||||
A += RL(B, 5) + K20_39 + (C ^ D ^ E) + w[13];
|
||||
C = RL(C, 30);
|
||||
w[14] = data[14] ^ w[0] ^ w[6] ^ w[11];
|
||||
w[14] = RL(w[14], 1);
|
||||
E += RL(A, 5) + K20_39 + (B ^ C ^ D) + w[14];
|
||||
B = RL(B, 30);
|
||||
w[15] = data[15] ^ w[1] ^ w[7] ^ w[12];
|
||||
w[15] = RL(w[15], 1);
|
||||
D += RL(E, 5) + K20_39 + (A ^ B ^ C) + w[15];
|
||||
A = RL(A, 30);
|
||||
w[0] = w[0] ^ w[2] ^ w[8] ^ w[13];
|
||||
w[0] = RL(w[0], 1);
|
||||
C += RL(D, 5) + K20_39 + (E ^ A ^ B) + w[0];
|
||||
E = RL(E, 30);
|
||||
w[1] = w[1] ^ w[3] ^ w[9] ^ w[14];
|
||||
w[1] = RL(w[1], 1);
|
||||
B += RL(C, 5) + K20_39 + (D ^ E ^ A) + w[1];
|
||||
D = RL(D, 30);
|
||||
w[2] = w[2] ^ w[4] ^ w[10] ^ w[15];
|
||||
w[2] = RL(w[2], 1);
|
||||
A += RL(B, 5) + K20_39 + (C ^ D ^ E) + w[2];
|
||||
C = RL(C, 30);
|
||||
w[3] = w[3] ^ w[5] ^ w[11] ^ w[0];
|
||||
w[3] = RL(w[3], 1);
|
||||
E += RL(A, 5) + K20_39 + (B ^ C ^ D) + w[3];
|
||||
B = RL(B, 30);
|
||||
w[4] = w[4] ^ w[6] ^ w[12] ^ w[1];
|
||||
w[4] = RL(w[4], 1);
|
||||
D += RL(E, 5) + K20_39 + (A ^ B ^ C) + w[4];
|
||||
A = RL(A, 30);
|
||||
w[5] = w[5] ^ w[7] ^ w[13] ^ w[2];
|
||||
w[5] = RL(w[5], 1);
|
||||
C += RL(D, 5) + K20_39 + (E ^ A ^ B) + w[5];
|
||||
E = RL(E, 30);
|
||||
w[6] = w[6] ^ w[8] ^ w[14] ^ w[3];
|
||||
w[6] = RL(w[6], 1);
|
||||
B += RL(C, 5) + K20_39 + (D ^ E ^ A) + w[6];
|
||||
D = RL(D, 30);
|
||||
w[7] = w[7] ^ w[9] ^ w[15] ^ w[4];
|
||||
w[7] = RL(w[7], 1);
|
||||
A += RL(B, 5) + K20_39 + (C ^ D ^ E) + w[7];
|
||||
C = RL(C, 30);
|
||||
|
||||
/* rounds 40 - 59 */
|
||||
|
||||
w[8] = w[8] ^ w[10] ^ w[0] ^ w[5];
|
||||
w[8] = RL(w[8], 1);
|
||||
E += RL(A, 5) + K40_59 + ((B & C) | (D & (B | C))) + w[8];
|
||||
B = RL(B, 30);
|
||||
w[9] = w[9] ^ w[11] ^ w[1] ^ w[6];
|
||||
w[9] = RL(w[9], 1);
|
||||
D += RL(E, 5) + K40_59 + ((A & B) | (C & (A | B))) + w[9];
|
||||
A = RL(A, 30);
|
||||
w[10] = w[10] ^ w[12] ^ w[2] ^ w[7];
|
||||
w[10] = RL(w[10], 1);
|
||||
C += RL(D, 5) + K40_59 + ((E & A) | (B & (E | A))) + w[10];
|
||||
E = RL(E, 30);
|
||||
w[11] = w[11] ^ w[13] ^ w[3] ^ w[8];
|
||||
w[11] = RL(w[11], 1);
|
||||
B += RL(C, 5) + K40_59 + ((D & E) | (A & (D | E))) + w[11];
|
||||
D = RL(D, 30);
|
||||
w[12] = w[12] ^ w[14] ^ w[4] ^ w[9];
|
||||
w[12] = RL(w[12], 1);
|
||||
A += RL(B, 5) + K40_59 + ((C & D) | (E & (C | D))) + w[12];
|
||||
C = RL(C, 30);
|
||||
w[13] = w[13] ^ w[15] ^ w[5] ^ w[10];
|
||||
w[13] = RL(w[13], 1);
|
||||
E += RL(A, 5) + K40_59 + ((B & C) | (D & (B | C))) + w[13];
|
||||
B = RL(B, 30);
|
||||
w[14] = w[14] ^ w[0] ^ w[6] ^ w[11];
|
||||
w[14] = RL(w[14], 1);
|
||||
D += RL(E, 5) + K40_59 + ((A & B) | (C & (A | B))) + w[14];
|
||||
A = RL(A, 30);
|
||||
w[15] = w[15] ^ w[1] ^ w[7] ^ w[12];
|
||||
w[15] = RL(w[15], 1);
|
||||
C += RL(D, 5) + K40_59 + ((E & A) | (B & (E | A))) + w[15];
|
||||
E = RL(E, 30);
|
||||
w[0] = w[0] ^ w[2] ^ w[8] ^ w[13];
|
||||
w[0] = RL(w[0], 1);
|
||||
B += RL(C, 5) + K40_59 + ((D & E) | (A & (D | E))) + w[0];
|
||||
D = RL(D, 30);
|
||||
w[1] = w[1] ^ w[3] ^ w[9] ^ w[14];
|
||||
w[1] = RL(w[1], 1);
|
||||
A += RL(B, 5) + K40_59 + ((C & D) | (E & (C | D))) + w[1];
|
||||
C = RL(C, 30);
|
||||
w[2] = w[2] ^ w[4] ^ w[10] ^ w[15];
|
||||
w[2] = RL(w[2], 1);
|
||||
E += RL(A, 5) + K40_59 + ((B & C) | (D & (B | C))) + w[2];
|
||||
B = RL(B, 30);
|
||||
w[3] = w[3] ^ w[5] ^ w[11] ^ w[0];
|
||||
w[3] = RL(w[3], 1);
|
||||
D += RL(E, 5) + K40_59 + ((A & B) | (C & (A | B))) + w[3];
|
||||
A = RL(A, 30);
|
||||
w[4] = w[4] ^ w[6] ^ w[12] ^ w[1];
|
||||
w[4] = RL(w[4], 1);
|
||||
C += RL(D, 5) + K40_59 + ((E & A) | (B & (E | A))) + w[4];
|
||||
E = RL(E, 30);
|
||||
w[5] = w[5] ^ w[7] ^ w[13] ^ w[2];
|
||||
w[5] = RL(w[5], 1);
|
||||
B += RL(C, 5) + K40_59 + ((D & E) | (A & (D | E))) + w[5];
|
||||
D = RL(D, 30);
|
||||
w[6] = w[6] ^ w[8] ^ w[14] ^ w[3];
|
||||
w[6] = RL(w[6], 1);
|
||||
A += RL(B, 5) + K40_59 + ((C & D) | (E & (C | D))) + w[6];
|
||||
C = RL(C, 30);
|
||||
w[7] = w[7] ^ w[9] ^ w[15] ^ w[4];
|
||||
w[7] = RL(w[7], 1);
|
||||
E += RL(A, 5) + K40_59 + ((B & C) | (D & (B | C))) + w[7];
|
||||
B = RL(B, 30);
|
||||
w[8] = w[8] ^ w[10] ^ w[0] ^ w[5];
|
||||
w[8] = RL(w[8], 1);
|
||||
D += RL(E, 5) + K40_59 + ((A & B) | (C & (A | B))) + w[8];
|
||||
A = RL(A, 30);
|
||||
w[9] = w[9] ^ w[11] ^ w[1] ^ w[6];
|
||||
w[9] = RL(w[9], 1);
|
||||
C += RL(D, 5) + K40_59 + ((E & A) | (B & (E | A))) + w[9];
|
||||
E = RL(E, 30);
|
||||
w[10] = w[10] ^ w[12] ^ w[2] ^ w[7];
|
||||
w[10] = RL(w[10], 1);
|
||||
B += RL(C, 5) + K40_59 + ((D & E) | (A & (D | E))) + w[10];
|
||||
D = RL(D, 30);
|
||||
w[11] = w[11] ^ w[13] ^ w[3] ^ w[8];
|
||||
w[11] = RL(w[11], 1);
|
||||
A += RL(B, 5) + K40_59 + ((C & D) | (E & (C | D))) + w[11];
|
||||
C = RL(C, 30);
|
||||
|
||||
/* rounds 60 - 79 */
|
||||
|
||||
w[12] = w[12] ^ w[14] ^ w[4] ^ w[9];
|
||||
w[12] = RL(w[12], 1);
|
||||
E += RL(A, 5) + K60_79 + (B ^ C ^ D) + w[12];
|
||||
B = RL(B, 30);
|
||||
w[13] = w[13] ^ w[15] ^ w[5] ^ w[10];
|
||||
w[13] = RL(w[13], 1);
|
||||
D += RL(E, 5) + K60_79 + (A ^ B ^ C) + w[13];
|
||||
A = RL(A, 30);
|
||||
w[14] = w[14] ^ w[0] ^ w[6] ^ w[11];
|
||||
w[14] = RL(w[14], 1);
|
||||
C += RL(D, 5) + K60_79 + (E ^ A ^ B) + w[14];
|
||||
E = RL(E, 30);
|
||||
w[15] = w[15] ^ w[1] ^ w[7] ^ w[12];
|
||||
w[15] = RL(w[15], 1);
|
||||
B += RL(C, 5) + K60_79 + (D ^ E ^ A) + w[15];
|
||||
D = RL(D, 30);
|
||||
w[0] = w[0] ^ w[2] ^ w[8] ^ w[13];
|
||||
w[0] = RL(w[0], 1);
|
||||
A += RL(B, 5) + K60_79 + (C ^ D ^ E) + w[0];
|
||||
C = RL(C, 30);
|
||||
w[1] = w[1] ^ w[3] ^ w[9] ^ w[14];
|
||||
w[1] = RL(w[1], 1);
|
||||
E += RL(A, 5) + K60_79 + (B ^ C ^ D) + w[1];
|
||||
B = RL(B, 30);
|
||||
w[2] = w[2] ^ w[4] ^ w[10] ^ w[15];
|
||||
w[2] = RL(w[2], 1);
|
||||
D += RL(E, 5) + K60_79 + (A ^ B ^ C) + w[2];
|
||||
A = RL(A, 30);
|
||||
w[3] = w[3] ^ w[5] ^ w[11] ^ w[0];
|
||||
w[3] = RL(w[3], 1);
|
||||
C += RL(D, 5) + K60_79 + (E ^ A ^ B) + w[3];
|
||||
E = RL(E, 30);
|
||||
w[4] = w[4] ^ w[6] ^ w[12] ^ w[1];
|
||||
w[4] = RL(w[4], 1);
|
||||
B += RL(C, 5) + K60_79 + (D ^ E ^ A) + w[4];
|
||||
D = RL(D, 30);
|
||||
w[5] = w[5] ^ w[7] ^ w[13] ^ w[2];
|
||||
w[5] = RL(w[5], 1);
|
||||
A += RL(B, 5) + K60_79 + (C ^ D ^ E) + w[5];
|
||||
C = RL(C, 30);
|
||||
w[6] = w[6] ^ w[8] ^ w[14] ^ w[3];
|
||||
w[6] = RL(w[6], 1);
|
||||
E += RL(A, 5) + K60_79 + (B ^ C ^ D) + w[6];
|
||||
B = RL(B, 30);
|
||||
w[7] = w[7] ^ w[9] ^ w[15] ^ w[4];
|
||||
w[7] = RL(w[7], 1);
|
||||
D += RL(E, 5) + K60_79 + (A ^ B ^ C) + w[7];
|
||||
A = RL(A, 30);
|
||||
w[8] = w[8] ^ w[10] ^ w[0] ^ w[5];
|
||||
w[8] = RL(w[8], 1);
|
||||
C += RL(D, 5) + K60_79 + (E ^ A ^ B) + w[8];
|
||||
E = RL(E, 30);
|
||||
w[9] = w[9] ^ w[11] ^ w[1] ^ w[6];
|
||||
w[9] = RL(w[9], 1);
|
||||
B += RL(C, 5) + K60_79 + (D ^ E ^ A) + w[9];
|
||||
D = RL(D, 30);
|
||||
w[10] = w[10] ^ w[12] ^ w[2] ^ w[7];
|
||||
w[10] = RL(w[10], 1);
|
||||
A += RL(B, 5) + K60_79 + (C ^ D ^ E) + w[10];
|
||||
C = RL(C, 30);
|
||||
w[11] = w[11] ^ w[13] ^ w[3] ^ w[8];
|
||||
w[11] = RL(w[11], 1);
|
||||
E += RL(A, 5) + K60_79 + (B ^ C ^ D) + w[11];
|
||||
B = RL(B, 30);
|
||||
w[12] = w[12] ^ w[14] ^ w[4] ^ w[9];
|
||||
w[12] = RL(w[12], 1);
|
||||
D += RL(E, 5) + K60_79 + (A ^ B ^ C) + w[12];
|
||||
A = RL(A, 30);
|
||||
w[13] = w[13] ^ w[15] ^ w[5] ^ w[10];
|
||||
C += RL(D, 5) + K60_79 + (E ^ A ^ B) + RL(w[13], 1);
|
||||
E = RL(E, 30);
|
||||
w[14] = w[14] ^ w[0] ^ w[6] ^ w[11];
|
||||
B += RL(C, 5) + K60_79 + (D ^ E ^ A) + RL(w[14], 1);
|
||||
D = RL(D, 30);
|
||||
|
||||
/* update H0 - H4 */
|
||||
|
||||
w[15] = w[15] ^ w[1] ^ w[7] ^ w[12];
|
||||
H0 += A + RL(B, 5) + K60_79 + (C ^ D ^ E) + RL(w[15], 1);
|
||||
H1 += B;
|
||||
H2 += RL(C, 30);
|
||||
H3 += D;
|
||||
H4 += E;
|
||||
|
||||
/* clear temp variables */
|
||||
|
||||
A = B = C = D = E = 0;
|
||||
memset(w, 0, sizeof(w));
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha1()
|
||||
*
|
||||
* This routine provides all operations for a SHA-1 hash, and the use
|
||||
* of SHA-1 for DSA signing and key generation.
|
||||
* It may be used to initialize, update, or complete a message digest,
|
||||
* or any combination of those actions, as determined by the SHA_INIT flag,
|
||||
* the in_len parameter, and the SHA_FINISH flag, respectively.
|
||||
*
|
||||
* When in_len == 0 (no data to hash), the parameter, in, may be NULL.
|
||||
* When the SHA_FINISH flag is not set, the parameter, md, may be NULL.
|
||||
*
|
||||
* Initialization may be standard or use a specified initialization vector,
|
||||
* and is indicated by setting the SHA_INIT flag.
|
||||
* Setting init = NULL specifies standard initialization. Otherwise, init
|
||||
* points to the array of five alternate initialization 32-bit words.
|
||||
*
|
||||
* The hash operation can be updated with any number of input bytes, including
|
||||
* zero.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint32_t const *init, /* in - pointer to alternate */
|
||||
/* initialization - may be NULL */
|
||||
uint8_t const *in, /* in - pointer to input data -
|
||||
may be NULL if in_len == 0 */
|
||||
uint32_t in_len, /* in - number of input data bytes */
|
||||
uint32_t flags, /* in - INIT, FINISH flags */
|
||||
uint8_t *md) /* out - address for message digest -
|
||||
may be NULL if not FINISH */
|
||||
{
|
||||
uint32_t in_blk[16]; /* input block */
|
||||
uint32_t space;
|
||||
uint8_t *d = NULL;
|
||||
|
||||
/* check error conditions */
|
||||
|
||||
if (!c || (in_len && !in) || ((flags & SHA_FINISH) && !md)) {
|
||||
SHA_RET(SHA_BAD_PARAMETER)
|
||||
}
|
||||
|
||||
/* initialize context if requested */
|
||||
|
||||
if (flags & SHA_INIT) {
|
||||
|
||||
/* init chaining state */
|
||||
|
||||
if (!init) {
|
||||
c->state[0] = H0_INIT; /* standard initialization */
|
||||
c->state[1] = H1_INIT;
|
||||
c->state[2] = H2_INIT;
|
||||
c->state[3] = H3_INIT;
|
||||
c->state[4] = H4_INIT;
|
||||
} else {
|
||||
/* Non standard initialization values are not supported */
|
||||
SHA_RET(SHA_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
/* init bit count and number of unhashed data bytes */
|
||||
|
||||
c->num_bits_hashed[0] = 0;
|
||||
c->num_bits_hashed[1] = 0;
|
||||
c->unhashed_len = 0;
|
||||
}
|
||||
|
||||
/* determine space left in unhashed data buffer */
|
||||
|
||||
if (c->unhashed_len > 63) {
|
||||
SHA_RET(SHA_FAIL)
|
||||
}
|
||||
|
||||
space = 64 - c->unhashed_len;
|
||||
|
||||
/* process input if it exists */
|
||||
|
||||
if (in_len) {
|
||||
|
||||
/* update count of bits hashed */
|
||||
|
||||
{
|
||||
uint32_t bits0, bits1;
|
||||
|
||||
bits0 = in_len << 3;
|
||||
bits1 = in_len >> 29;
|
||||
|
||||
if ((c->num_bits_hashed[0] += bits0) < bits0) {
|
||||
bits1++;
|
||||
}
|
||||
|
||||
if ((c->num_bits_hashed[1] += bits1) < bits1) {
|
||||
memset((uint8_t *) c, 0, sizeof(NTRU_CRYPTO_SHA1_CTX));
|
||||
memset((char *) in_blk, 0, sizeof(in_blk));
|
||||
SHA_RET(SHA_OVERFLOW)
|
||||
}
|
||||
}
|
||||
|
||||
/* process input bytes */
|
||||
|
||||
if (in_len < space) {
|
||||
|
||||
/* input does not fill block buffer:
|
||||
* add input to buffer
|
||||
*/
|
||||
|
||||
memcpy(c->unhashed + c->unhashed_len, in, in_len);
|
||||
c->unhashed_len += in_len;
|
||||
|
||||
} else {
|
||||
uint32_t blks;
|
||||
|
||||
/* input will fill block buffer:
|
||||
* fill unhashed data buffer,
|
||||
* convert to block buffer,
|
||||
* and process block
|
||||
*/
|
||||
|
||||
in_len -= space;
|
||||
|
||||
for (d = c->unhashed + c->unhashed_len; space; space--) {
|
||||
*d++ = *in++;
|
||||
}
|
||||
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
16);
|
||||
sha1_blk((uint32_t const *) in_blk, c->state);
|
||||
|
||||
/* process any remaining full blocks */
|
||||
|
||||
for (blks = in_len >> 6; blks--; in += 64) {
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, in, 16);
|
||||
sha1_blk((uint32_t const *) in_blk, c->state);
|
||||
}
|
||||
|
||||
/* put any remaining input in the unhashed data buffer */
|
||||
|
||||
in_len &= 0x3f;
|
||||
memcpy(c->unhashed, in, in_len);
|
||||
c->unhashed_len = in_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* complete message digest if requested */
|
||||
|
||||
if (flags & SHA_FINISH) {
|
||||
space = 64 - c->unhashed_len;
|
||||
|
||||
/* add 0x80 padding byte to the unhashed data buffer
|
||||
* (there is always space since the buffer can't be full)
|
||||
*/
|
||||
|
||||
d = c->unhashed + c->unhashed_len;
|
||||
*d++ = 0x80;
|
||||
space--;
|
||||
|
||||
/* check for space for bit count */
|
||||
|
||||
if (space < 8) {
|
||||
|
||||
/* no space for count:
|
||||
* fill remainder of unhashed data buffer with zeros,
|
||||
* convert to input block,
|
||||
* process block,
|
||||
* fill all but 8 bytes of unhashed data buffer with zeros
|
||||
*/
|
||||
|
||||
memset(d, 0, space);
|
||||
ntru_crypto_msbyte_2_uint32(in_blk,
|
||||
(uint8_t const *) c->unhashed, 16);
|
||||
sha1_blk((uint32_t const *) in_blk, c->state);
|
||||
memset(c->unhashed, 0, 56);
|
||||
|
||||
} else {
|
||||
|
||||
/* fill unhashed data buffer with zeros,
|
||||
* leaving space for bit count
|
||||
*/
|
||||
|
||||
for (space -= 8; space; space--) {
|
||||
*d++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert partially filled unhashed data buffer to input block and
|
||||
* add bit count to input block
|
||||
*/
|
||||
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
14);
|
||||
in_blk[14] = c->num_bits_hashed[1];
|
||||
in_blk[15] = c->num_bits_hashed[0];
|
||||
|
||||
/* process last block */
|
||||
|
||||
sha1_blk((uint32_t const *) in_blk, c->state);
|
||||
|
||||
/* copy result to message digest buffer */
|
||||
|
||||
ntru_crypto_uint32_2_msbyte(md, c->state, 5);
|
||||
|
||||
/* clear context and stack variables */
|
||||
|
||||
memset((uint8_t *) c, 0, sizeof(NTRU_CRYPTO_SHA1_CTX));
|
||||
memset((char *) in_blk, 0, sizeof(in_blk));
|
||||
}
|
||||
|
||||
SHA_RET(SHA_OK)
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha1_init
|
||||
*
|
||||
* This routine performs standard initialization of the SHA-1 state.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1_init(
|
||||
NTRU_CRYPTO_SHA1_CTX *c) /* in/out - pointer to SHA-1 context */
|
||||
{
|
||||
return ntru_crypto_sha1(c, NULL, NULL, 0, SHA_INIT, NULL);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha1_update
|
||||
*
|
||||
* This routine processes input data and updates the SHA-1 hash calculation.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1_update(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint8_t const *data, /* in - pointer to input data */
|
||||
uint32_t data_len) /* in - number of bytes of input data */
|
||||
{
|
||||
return ntru_crypto_sha1(c, NULL, data, data_len, SHA_DATA_ONLY, NULL);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha1_final
|
||||
*
|
||||
* This routine completes the SHA-1 hash calculation and returns the
|
||||
* message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1_final(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint8_t *md) /* out - address for message digest */
|
||||
{
|
||||
return ntru_crypto_sha1(c, NULL, NULL, 0, SHA_FINISH, md);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha1_digest
|
||||
*
|
||||
* This routine computes a SHA-1 message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1_digest(
|
||||
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_SHA1_CTX c;
|
||||
|
||||
return ntru_crypto_sha1(&c, NULL, data, data_len, SHA_INIT | SHA_FINISH, md);
|
||||
}
|
||||
@ -1,163 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha1.h
|
||||
*
|
||||
* Contents: Definitions and declarations for the SHA-1 implementation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_SHA1_H
|
||||
#define NTRU_CRYPTO_SHA1_H
|
||||
|
||||
#include "ntru_crypto_platform.h"
|
||||
#include "ntru_crypto_sha.h"
|
||||
|
||||
/******************************************
|
||||
* macros needed for generic hash objects *
|
||||
******************************************/
|
||||
|
||||
#define SHA_1_CTX_LEN sizeof(SHA1_CTX) /* no. bytes in SHA-1 ctx */
|
||||
#define SHA_1_BLK_LEN 64 /* 64 bytes in input block */
|
||||
#define SHA_1_MD_LEN 20 /* 20 bytes in msg digest */
|
||||
#define SHA_1_INIT_FN &ntru_crypto_sha1_init /* init function */
|
||||
#define SHA_1_UPDATE_FN &ntru_crypto_sha1_update /* update function */
|
||||
#define SHA_1_FINAL_FN &ntru_crypto_sha1_final /* final function */
|
||||
#define SHA_1_DIGEST_FN &ntru_crypto_sha1_digest /* digest function */
|
||||
|
||||
/*************************
|
||||
* structure definitions *
|
||||
*************************/
|
||||
|
||||
/* SHA-1 context structure */
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[5]; /* chaining state */
|
||||
uint32_t num_bits_hashed[2]; /* number of bits hashed */
|
||||
uint8_t unhashed[64]; /* input data not yet hashed */
|
||||
uint32_t unhashed_len; /* number of bytes of unhashed input data */
|
||||
} NTRU_CRYPTO_SHA1_CTX;
|
||||
|
||||
/*************************
|
||||
* function declarations *
|
||||
*************************/
|
||||
|
||||
/* ntru_crypto_sha1()
|
||||
*
|
||||
* This routine provides all operations for a SHA-1 hash, and the use
|
||||
* of SHA-1 for DSA signing and key generation.
|
||||
* It may be used to initialize, update, or complete a message digest,
|
||||
* or any combination of those actions, as determined by the SHA_INIT flag,
|
||||
* the in_len parameter, and the SHA_FINISH flag, respectively.
|
||||
*
|
||||
* When in_len == 0 (no data to hash), the parameter, in, may be NULL.
|
||||
* When the SHA_FINISH flag is not set, the parameter, md, may be NULL.
|
||||
*
|
||||
* Initialization may be standard or use a specified initialization vector,
|
||||
* and is indicated by setting the SHA_INIT flag.
|
||||
* Setting init = NULL specifies standard initialization. Otherwise, init
|
||||
* points to the array of five alternate initialization 32-bit words.
|
||||
*
|
||||
* The hash operation can be updated with any number of input bytes, including
|
||||
* zero.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha1(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint32_t const *init, /* in - pointer to alternate */
|
||||
/* initialization - may be NULL */
|
||||
uint8_t const *in, /* in - pointer to input data -
|
||||
may be NULL if in_len == 0 */
|
||||
uint32_t in_len, /* in - number of input data bytes */
|
||||
uint32_t flags, /* in - INIT, FINISH */
|
||||
uint8_t *md); /* out - address for message digest -
|
||||
may be NULL if not FINISH */
|
||||
|
||||
/* ntru_crypto_sha1_init
|
||||
*
|
||||
* This routine performs standard initialization of the SHA-1 state.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha1_init(
|
||||
NTRU_CRYPTO_SHA1_CTX *c); /* in/out - pointer to SHA-1 context */
|
||||
|
||||
/* ntru_crypto_sha1_update
|
||||
*
|
||||
* This routine processes input data and updates the SHA-1 hash calculation.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha1_update(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint8_t const *data, /* in - pointer to input data */
|
||||
uint32_t data_len); /* in - number of bytes of input data */
|
||||
|
||||
/* ntru_crypto_sha1_final
|
||||
*
|
||||
* This routine completes the SHA-1 hash calculation and returns the
|
||||
* message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha1_final(
|
||||
NTRU_CRYPTO_SHA1_CTX *c, /* in/out - pointer to SHA-1 context */
|
||||
uint8_t *md); /* out - address for message digest */
|
||||
|
||||
/* ntru_crypto_sha1_digest
|
||||
*
|
||||
* This routine computes a SHA-1 message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha1_digest(
|
||||
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_SHA1_H */
|
||||
@ -1,570 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha2.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-256 hash calculation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto.h"
|
||||
#include "ntru_crypto_sha2.h"
|
||||
#include "ntru_crypto_msbyte_uint32.h"
|
||||
|
||||
/* chaining state elements */
|
||||
|
||||
#define H0 state[0]
|
||||
#define H1 state[1]
|
||||
#define H2 state[2]
|
||||
#define H3 state[3]
|
||||
#define H4 state[4]
|
||||
#define H5 state[5]
|
||||
#define H6 state[6]
|
||||
#define H7 state[7]
|
||||
|
||||
/* standard SHA-256 initialization values */
|
||||
|
||||
#define H0_SHA256_INIT 0x6a09e667UL
|
||||
#define H1_SHA256_INIT 0xbb67ae85UL
|
||||
#define H2_SHA256_INIT 0x3c6ef372UL
|
||||
#define H3_SHA256_INIT 0xa54ff53aUL
|
||||
#define H4_SHA256_INIT 0x510e527fUL
|
||||
#define H5_SHA256_INIT 0x9b05688cUL
|
||||
#define H6_SHA256_INIT 0x1f83d9abUL
|
||||
#define H7_SHA256_INIT 0x5be0cd19UL
|
||||
|
||||
/* sha2_blk()
|
||||
*
|
||||
* This routine updates the current hash output (chaining state)
|
||||
* by performing SHA-256 on a 512-bit block of data represented
|
||||
* as sixteen 32-bit words.
|
||||
*/
|
||||
|
||||
#define RR(a, n) (((a) >> (n)) | ((a) << (32 - (n))))
|
||||
#define S0(a) (RR((a), 2) ^ RR((a), 13) ^ RR((a), 22))
|
||||
#define S1(a) (RR((a), 6) ^ RR((a), 11) ^ RR((a), 25))
|
||||
#define s0(a) (RR((a), 7) ^ RR((a), 18) ^ ((a) >> 3))
|
||||
#define s1(a) (RR((a), 17) ^ RR((a), 19) ^ ((a) >> 10))
|
||||
|
||||
static void
|
||||
sha2_blk(
|
||||
uint32_t const *data, /* in - ptr to 16 32-bit word input block */
|
||||
uint32_t *state) /* in/out - ptr to 8 32-bit word chaining state */
|
||||
{
|
||||
uint32_t A, B, C, D, E, F, G, H;
|
||||
uint32_t w[16];
|
||||
|
||||
/* init A - H */
|
||||
|
||||
A = H0;
|
||||
B = H1;
|
||||
C = H2;
|
||||
D = H3;
|
||||
E = H4;
|
||||
F = H5;
|
||||
G = H6;
|
||||
H = H7;
|
||||
|
||||
/* rounds 0 - 15 */
|
||||
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0x428A2F98UL + data[0];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0x71374491UL + data[1];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0xB5C0FBCFUL + data[2];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0xE9B5DBA5UL + data[3];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x3956C25BUL + data[4];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0x59F111F1UL + data[5];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x923F82A4UL + data[6];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0xAB1C5ED5UL + data[7];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0xD807AA98UL + data[8];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0x12835B01UL + data[9];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0x243185BEUL + data[10];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0x550C7DC3UL + data[11];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x72BE5D74UL + data[12];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0x80DEB1FEUL + data[13];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x9BDC06A7UL + data[14];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0xC19BF174UL + data[15];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
|
||||
/* rounds 16 - 63 */
|
||||
|
||||
w[0] = data[0] + s0(data[1]) + data[9] + s1(data[14]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0xE49B69C1UL + w[0];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[1] = data[1] + s0(data[2]) + data[10] + s1(data[15]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0xEFBE4786UL + w[1];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[2] = data[2] + s0(data[3]) + data[11] + s1(w[0]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0x0FC19DC6UL + w[2];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[3] = data[3] + s0(data[4]) + data[12] + s1(w[1]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0x240CA1CCUL + w[3];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[4] = data[4] + s0(data[5]) + data[13] + s1(w[2]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x2DE92C6FUL + w[4];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[5] = data[5] + s0(data[6]) + data[14] + s1(w[3]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0x4A7484AAUL + w[5];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[6] = data[6] + s0(data[7]) + data[15] + s1(w[4]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x5CB0A9DCUL + w[6];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[7] = data[7] + s0(data[8]) + w[0] + s1(w[5]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0x76F988DAUL + w[7];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
w[8] = data[8] + s0(data[9]) + w[1] + s1(w[6]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0x983E5152UL + w[8];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[9] = data[9] + s0(data[10]) + w[2] + s1(w[7]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0xA831C66DUL + w[9];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[10] = data[10] + s0(data[11]) + w[3] + s1(w[8]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0xB00327C8UL + w[10];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[11] = data[11] + s0(data[12]) + w[4] + s1(w[9]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0xBF597FC7UL + w[11];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[12] = data[12] + s0(data[13]) + w[5] + s1(w[10]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0xC6E00BF3UL + w[12];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[13] = data[13] + s0(data[14]) + w[6] + s1(w[11]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0xD5A79147UL + w[13];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[14] = data[14] + s0(data[15]) + w[7] + s1(w[12]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x06CA6351UL + w[14];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[15] = data[15] + s0(w[0]) + w[8] + s1(w[13]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0x14292967UL + w[15];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
w[0] = w[0] + s0(w[1]) + w[9] + s1(w[14]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0x27B70A85UL + w[0];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[1] = w[1] + s0(w[2]) + w[10] + s1(w[15]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0x2E1B2138UL + w[1];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[2] = w[2] + s0(w[3]) + w[11] + s1(w[0]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0x4D2C6DFCUL + w[2];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[3] = w[3] + s0(w[4]) + w[12] + s1(w[1]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0x53380D13UL + w[3];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[4] = w[4] + s0(w[5]) + w[13] + s1(w[2]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x650A7354UL + w[4];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[5] = w[5] + s0(w[6]) + w[14] + s1(w[3]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0x766A0ABBUL + w[5];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[6] = w[6] + s0(w[7]) + w[15] + s1(w[4]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x81C2C92EUL + w[6];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[7] = w[7] + s0(w[8]) + w[0] + s1(w[5]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0x92722C85UL + w[7];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
w[8] = w[8] + s0(w[9]) + w[1] + s1(w[6]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0xA2BFE8A1UL + w[8];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[9] = w[9] + s0(w[10]) + w[2] + s1(w[7]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0xA81A664BUL + w[9];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[10] = w[10] + s0(w[11]) + w[3] + s1(w[8]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0xC24B8B70UL + w[10];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[11] = w[11] + s0(w[12]) + w[4] + s1(w[9]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0xC76C51A3UL + w[11];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[12] = w[12] + s0(w[13]) + w[5] + s1(w[10]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0xD192E819UL + w[12];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[13] = w[13] + s0(w[14]) + w[6] + s1(w[11]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0xD6990624UL + w[13];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[14] = w[14] + s0(w[15]) + w[7] + s1(w[12]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0xF40E3585UL + w[14];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[15] = w[15] + s0(w[0]) + w[8] + s1(w[13]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0x106AA070UL + w[15];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
w[0] = w[0] + s0(w[1]) + w[9] + s1(w[14]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0x19A4C116UL + w[0];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[1] = w[1] + s0(w[2]) + w[10] + s1(w[15]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0x1E376C08UL + w[1];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[2] = w[2] + s0(w[3]) + w[11] + s1(w[0]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0x2748774CUL + w[2];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[3] = w[3] + s0(w[4]) + w[12] + s1(w[1]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0x34B0BCB5UL + w[3];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[4] = w[4] + s0(w[5]) + w[13] + s1(w[2]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x391C0CB3UL + w[4];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[5] = w[5] + s0(w[6]) + w[14] + s1(w[3]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0x4ED8AA4AUL + w[5];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[6] = w[6] + s0(w[7]) + w[15] + s1(w[4]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0x5B9CCA4FUL + w[6];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[7] = w[7] + s0(w[8]) + w[0] + s1(w[5]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0x682E6FF3UL + w[7];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
w[8] = w[8] + s0(w[9]) + w[1] + s1(w[6]);
|
||||
H += S1(E) + ((E & (F ^ G)) ^ G) + 0x748F82EEUL + w[8];
|
||||
D += H;
|
||||
H += S0(A) + ((A & B) | (C & (A | B)));
|
||||
w[9] = w[9] + s0(w[10]) + w[2] + s1(w[7]);
|
||||
G += S1(D) + ((D & (E ^ F)) ^ F) + 0x78A5636FUL + w[9];
|
||||
C += G;
|
||||
G += S0(H) + ((H & A) | (B & (H | A)));
|
||||
w[10] = w[10] + s0(w[11]) + w[3] + s1(w[8]);
|
||||
F += S1(C) + ((C & (D ^ E)) ^ E) + 0x84C87814UL + w[10];
|
||||
B += F;
|
||||
F += S0(G) + ((G & H) | (A & (G | H)));
|
||||
w[11] = w[11] + s0(w[12]) + w[4] + s1(w[9]);
|
||||
E += S1(B) + ((B & (C ^ D)) ^ D) + 0x8CC70208UL + w[11];
|
||||
A += E;
|
||||
E += S0(F) + ((F & G) | (H & (F | G)));
|
||||
w[12] = w[12] + s0(w[13]) + w[5] + s1(w[10]);
|
||||
D += S1(A) + ((A & (B ^ C)) ^ C) + 0x90BEFFFAUL + w[12];
|
||||
H += D;
|
||||
D += S0(E) + ((E & F) | (G & (E | F)));
|
||||
w[13] = w[13] + s0(w[14]) + w[6] + s1(w[11]);
|
||||
C += S1(H) + ((H & (A ^ B)) ^ B) + 0xA4506CEBUL + w[13];
|
||||
G += C;
|
||||
C += S0(D) + ((D & E) | (F & (D | E)));
|
||||
w[14] = w[14] + s0(w[15]) + w[7] + s1(w[12]);
|
||||
B += S1(G) + ((G & (H ^ A)) ^ A) + 0xBEF9A3F7UL + w[14];
|
||||
F += B;
|
||||
B += S0(C) + ((C & D) | (E & (C | D)));
|
||||
w[15] = w[15] + s0(w[0]) + w[8] + s1(w[13]);
|
||||
A += S1(F) + ((F & (G ^ H)) ^ H) + 0xC67178F2UL + w[15];
|
||||
E += A;
|
||||
A += S0(B) + ((B & C) | (D & (B | C)));
|
||||
|
||||
/* update H0 - H7 */
|
||||
|
||||
H0 += A;
|
||||
H1 += B;
|
||||
H2 += C;
|
||||
H3 += D;
|
||||
H4 += E;
|
||||
H5 += F;
|
||||
H6 += G;
|
||||
H7 += H;
|
||||
|
||||
/* clear temp variables */
|
||||
|
||||
A = B = C = D = E = F = G = H = 0;
|
||||
memset(w, 0, sizeof(w));
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha2()
|
||||
*
|
||||
* This routine provides all operations for a SHA-256 hash,
|
||||
* and the use of SHA-256 for DSA signing and key generation.
|
||||
* It may be used to initialize, update, or complete a message digest,
|
||||
* or any combination of those actions, as determined by the SHA_INIT flag,
|
||||
* the in_len parameter, and the SHA_FINISH flag, respectively.
|
||||
*
|
||||
* When in_len == 0 (no data to hash), the parameter, in, may be NULL.
|
||||
* When the SHA_FINISH flag is not set, the parameter, md, may be NULL.
|
||||
*
|
||||
* Initialization may be standard or use a specified initialization vector,
|
||||
* and is indicated by setting the SHA_INIT flag.
|
||||
* Setting init = NULL specifies standard initialization. Otherwise, init
|
||||
* points to the array of eight alternate initialization 32-bit words.
|
||||
*
|
||||
* The hash operation can be updated with any number of input bytes, including
|
||||
* zero.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha2(
|
||||
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm ID */
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint32_t const *init, /* in - pointer to alternate */
|
||||
/* initialization - may be NULL */
|
||||
uint8_t const *in, /* in - pointer to input data - */
|
||||
/* may be NULL if in_len == 0 */
|
||||
uint32_t in_len, /* in - number of input data bytes */
|
||||
uint32_t flags, /* in - INIT, FINISH flags */
|
||||
uint8_t *md) /* out - address for message digest -
|
||||
* may be NULL if not FINISH */
|
||||
{
|
||||
uint32_t in_blk[16]; /* input block */
|
||||
uint32_t space;
|
||||
uint8_t *d = NULL;
|
||||
|
||||
/* check error conditions */
|
||||
|
||||
if (algid != NTRU_CRYPTO_HASH_ALGID_SHA256) {
|
||||
SHA_RET(SHA_BAD_PARAMETER)
|
||||
}
|
||||
|
||||
if (!c || (in_len && !in) || ((flags & SHA_FINISH) && !md)) {
|
||||
SHA_RET(SHA_BAD_PARAMETER)
|
||||
}
|
||||
|
||||
/* initialize context if requested */
|
||||
|
||||
if (flags & SHA_INIT) {
|
||||
/* init chaining state */
|
||||
|
||||
if (!init) /* standard initialization */
|
||||
{
|
||||
|
||||
c->state[0] = H0_SHA256_INIT; /* standard SHA-256 init */
|
||||
c->state[1] = H1_SHA256_INIT;
|
||||
c->state[2] = H2_SHA256_INIT;
|
||||
c->state[3] = H3_SHA256_INIT;
|
||||
c->state[4] = H4_SHA256_INIT;
|
||||
c->state[5] = H5_SHA256_INIT;
|
||||
c->state[6] = H6_SHA256_INIT;
|
||||
c->state[7] = H7_SHA256_INIT;
|
||||
|
||||
} else {
|
||||
/* Support for SHA-224 etc is disabled */
|
||||
SHA_RET(SHA_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
/* init bit count and number of unhashed data bytes */
|
||||
|
||||
c->num_bits_hashed[0] = 0;
|
||||
c->num_bits_hashed[1] = 0;
|
||||
c->unhashed_len = 0;
|
||||
}
|
||||
|
||||
/* determine space left in unhashed data buffer */
|
||||
|
||||
if (c->unhashed_len > 63) {
|
||||
SHA_RET(SHA_FAIL)
|
||||
}
|
||||
|
||||
space = 64 - c->unhashed_len;
|
||||
|
||||
/* process input if it exists */
|
||||
|
||||
if (in_len) {
|
||||
/* update count of bits hashed */
|
||||
|
||||
{
|
||||
uint32_t bits0, bits1;
|
||||
|
||||
bits0 = in_len << 3;
|
||||
bits1 = in_len >> 29;
|
||||
|
||||
if ((c->num_bits_hashed[0] += bits0) < bits0) {
|
||||
bits1++;
|
||||
}
|
||||
|
||||
if ((c->num_bits_hashed[1] += bits1) < bits1) {
|
||||
memset((uint8_t *) c, 0, sizeof(NTRU_CRYPTO_SHA2_CTX));
|
||||
memset((char *) in_blk, 0, sizeof(in_blk));
|
||||
SHA_RET(SHA_OVERFLOW)
|
||||
}
|
||||
}
|
||||
|
||||
/* process input bytes */
|
||||
|
||||
if (in_len < space) {
|
||||
|
||||
/* input does not fill block buffer:
|
||||
* add input to buffer
|
||||
*/
|
||||
|
||||
memcpy(c->unhashed + c->unhashed_len, in, in_len);
|
||||
c->unhashed_len += in_len;
|
||||
|
||||
} else {
|
||||
uint32_t blks;
|
||||
|
||||
/* input will fill block buffer:
|
||||
* fill unhashed data buffer,
|
||||
* convert to block buffer,
|
||||
* and process block
|
||||
*/
|
||||
|
||||
in_len -= space;
|
||||
|
||||
for (d = c->unhashed + c->unhashed_len; space; space--) {
|
||||
*d++ = *in++;
|
||||
}
|
||||
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
16);
|
||||
sha2_blk((uint32_t const *) in_blk, c->state);
|
||||
|
||||
/* process any remaining full blocks */
|
||||
|
||||
for (blks = in_len >> 6; blks--; in += 64) {
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, in, 16);
|
||||
sha2_blk((uint32_t const *) in_blk, c->state);
|
||||
}
|
||||
|
||||
/* put any remaining input in the unhashed data buffer */
|
||||
|
||||
in_len &= 0x3f;
|
||||
memcpy(c->unhashed, in, in_len);
|
||||
c->unhashed_len = in_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* complete message digest if requested */
|
||||
|
||||
if (flags & SHA_FINISH) {
|
||||
space = 64 - c->unhashed_len;
|
||||
|
||||
/* add 0x80 padding byte to the unhashed data buffer
|
||||
* (there is always space since the buffer can't be full)
|
||||
*/
|
||||
|
||||
d = c->unhashed + c->unhashed_len;
|
||||
*d++ = 0x80;
|
||||
space--;
|
||||
|
||||
/* check for space for bit count */
|
||||
|
||||
if (space < 8) {
|
||||
/* no space for count:
|
||||
* fill remainder of unhashed data buffer with zeros,
|
||||
* convert to input block,
|
||||
* process block,
|
||||
* fill all but 8 bytes of unhashed data buffer with zeros
|
||||
*/
|
||||
|
||||
memset(d, 0, space);
|
||||
ntru_crypto_msbyte_2_uint32(in_blk,
|
||||
(uint8_t const *) c->unhashed, 16);
|
||||
sha2_blk((uint32_t const *) in_blk, c->state);
|
||||
memset(c->unhashed, 0, 56);
|
||||
|
||||
} else {
|
||||
/* fill unhashed data buffer with zeros,
|
||||
* leaving space for bit count
|
||||
*/
|
||||
|
||||
for (space -= 8; space; space--) {
|
||||
*d++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert partially filled unhashed data buffer to input block and
|
||||
* add bit count to input block
|
||||
*/
|
||||
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
14);
|
||||
in_blk[14] = c->num_bits_hashed[1];
|
||||
in_blk[15] = c->num_bits_hashed[0];
|
||||
|
||||
/* process last block */
|
||||
|
||||
sha2_blk((uint32_t const *) in_blk, c->state);
|
||||
|
||||
/* copy result to message digest buffer */
|
||||
|
||||
ntru_crypto_uint32_2_msbyte(md, c->state, 8);
|
||||
|
||||
/* clear context and stack variables */
|
||||
|
||||
memset((uint8_t *) c, 0, sizeof(NTRU_CRYPTO_SHA2_CTX));
|
||||
memset((char *) in_blk, 0, sizeof(in_blk));
|
||||
}
|
||||
|
||||
SHA_RET(SHA_OK)
|
||||
}
|
||||
@ -1,91 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha2.h
|
||||
*
|
||||
* Contents: Definitions and declarations for the SHA-256 implementation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_SHA2_H
|
||||
#define NTRU_CRYPTO_SHA2_H
|
||||
|
||||
#include "ntru_crypto_platform.h"
|
||||
#include "ntru_crypto_sha.h"
|
||||
|
||||
/*************************
|
||||
* structure definitions *
|
||||
*************************/
|
||||
|
||||
/* SHA-256 context structure */
|
||||
|
||||
typedef struct {
|
||||
uint32_t state[8]; /* chaining state */
|
||||
uint32_t num_bits_hashed[2]; /* number of bits hashed */
|
||||
uint8_t unhashed[64]; /* input data not yet hashed */
|
||||
uint32_t unhashed_len; /* number of bytes of unhashed input data */
|
||||
} NTRU_CRYPTO_SHA2_CTX;
|
||||
|
||||
/*************************
|
||||
* function declarations *
|
||||
*************************/
|
||||
|
||||
/* ntru_crypto_sha2()
|
||||
*
|
||||
* This routine provides all operations for a SHA-256 hash,
|
||||
* and the use of SHA-256 for DSA signing and key generation.
|
||||
* It may be used to initialize, update, or complete a message digest,
|
||||
* or any combination of those actions, as determined by the SHA_INIT flag,
|
||||
* the in_len parameter, and the SHA_FINISH flag, respectively.
|
||||
*
|
||||
* When in_len == 0 (no data to hash), the parameter, in, may be NULL.
|
||||
* When the SHA_FINISH flag is not set, the parameter, md, may be NULL.
|
||||
*
|
||||
* Initialization may be standard or use a specified initialization vector,
|
||||
* and is indicated by setting the SHA_INIT flag.
|
||||
* Setting init = NULL specifies standard initialization. Otherwise, init
|
||||
* points to the array of eight alternate initialization 32-bit words.
|
||||
*
|
||||
* The hash operation can be updated with any number of input bytes, including
|
||||
* zero.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha2(
|
||||
NTRU_CRYPTO_HASH_ALGID algid, /* in - hash algorithm ID */
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint32_t const *init, /* in - pointer to alternate */
|
||||
/* initialization - may be NULL */
|
||||
uint8_t const *in, /* in - pointer to input data -
|
||||
may be NULL if in_len == 0 */
|
||||
uint32_t in_len, /* in - number of input data bytes */
|
||||
uint32_t flags, /* in - INIT, FINISH */
|
||||
uint8_t *md); /* out - address for message digest -
|
||||
may be NULL if not FINISH */
|
||||
|
||||
#endif /* NTRU_CRYPTO_SHA2_H */
|
||||
@ -1,109 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha256.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-256 hash calculations.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "ntru_crypto_sha256.h"
|
||||
|
||||
/* ntru_crypto_sha256_init
|
||||
*
|
||||
* This routine performs standard initialization of the SHA-256 state.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha256_init(
|
||||
NTRU_CRYPTO_SHA2_CTX *c) /* in/out - pointer to SHA-2 context */
|
||||
{
|
||||
return ntru_crypto_sha2(NTRU_CRYPTO_HASH_ALGID_SHA256, c, NULL, NULL, 0,
|
||||
SHA_INIT, NULL);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha256_update
|
||||
*
|
||||
* This routine processes input data and updates the SHA-256 hash calculation.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha256_update(
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint8_t const *data, /* in - pointer to input data */
|
||||
uint32_t data_len) /* in - no. of bytes of input data */
|
||||
{
|
||||
return ntru_crypto_sha2(NTRU_CRYPTO_HASH_ALGID_SHA256, c, NULL, data,
|
||||
data_len, SHA_DATA_ONLY, NULL);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha256_final
|
||||
*
|
||||
* This routine completes the SHA-256 hash calculation and returns the
|
||||
* message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha256_final(
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint8_t *md) /* out - address for message digest */
|
||||
{
|
||||
return ntru_crypto_sha2(NTRU_CRYPTO_HASH_ALGID_SHA256, c, NULL, NULL, 0,
|
||||
SHA_FINISH, md);
|
||||
}
|
||||
|
||||
/* ntru_crypto_sha256_digest
|
||||
*
|
||||
* This routine computes a SHA-256 message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
ntru_crypto_sha256_digest(
|
||||
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_SHA2_CTX c;
|
||||
|
||||
return ntru_crypto_sha2(NTRU_CRYPTO_HASH_ALGID_SHA256, &c, NULL, data,
|
||||
data_len, SHA_INIT | SHA_FINISH, md);
|
||||
}
|
||||
@ -1,114 +0,0 @@
|
||||
/******************************************************************************
|
||||
* 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_sha256.h
|
||||
*
|
||||
* Contents: Definitions and declarations for the SHA-256 implementation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_SHA256_H
|
||||
#define NTRU_CRYPTO_SHA256_H
|
||||
|
||||
#include "ntru_crypto_platform.h"
|
||||
#include "ntru_crypto_sha2.h"
|
||||
|
||||
/******************************************
|
||||
* macros needed for generic hash objects *
|
||||
******************************************/
|
||||
|
||||
#define SHA_256_CTX_LEN sizeof(NTRU_CRYPTO_SHA2_CTX)
|
||||
/* no. bytes in SHA-2 ctx */
|
||||
#define SHA_256_BLK_LEN 64 /* 64 bytes in input block */
|
||||
#define SHA_256_MD_LEN 32 /* 32 bytes in msg digest */
|
||||
#define SHA_256_INIT_FN &ntru_crypto_sha256_init /* init function */
|
||||
#define SHA_256_UPDATE_FN &ntru_crypto_sha256_update /* update function */
|
||||
#define SHA_256_FINAL_FN &ntru_crypto_sha256_final /* final function */
|
||||
#define SHA_256_DIGEST_FN &ntru_crypto_sha256_digest /* digest function */
|
||||
|
||||
/*************************
|
||||
* function declarations *
|
||||
*************************/
|
||||
|
||||
/* ntru_crypto_sha256_init
|
||||
*
|
||||
* This routine performs standard initialization of the SHA-256 state.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha256_init(
|
||||
NTRU_CRYPTO_SHA2_CTX *c); /* in/out - pointer to SHA-2 context */
|
||||
|
||||
/* ntru_crypto_sha256_update
|
||||
*
|
||||
* This routine processes input data and updates the SHA-256 hash calculation.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha256_update(
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint8_t const *data, /* in - pointer to input data */
|
||||
uint32_t data_len); /* in - no. of bytes of input data */
|
||||
|
||||
/* ntru_crypto_sha256_final
|
||||
*
|
||||
* This routine completes the SHA-256 hash calculation and returns the
|
||||
* message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha256_final(
|
||||
NTRU_CRYPTO_SHA2_CTX *c, /* in/out - pointer to SHA-2 context */
|
||||
uint8_t *md); /* out - address for message digest */
|
||||
|
||||
/* ntru_crypto_sha256_digest
|
||||
*
|
||||
* This routine computes a SHA-256 message digest.
|
||||
*
|
||||
* Returns SHA_OK on success.
|
||||
* Returns SHA_FAIL with corrupted context.
|
||||
* Returns SHA_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
* Returns SHA_OVERFLOW if more than 2^64 - 1 bytes are hashed.
|
||||
*/
|
||||
|
||||
extern uint32_t
|
||||
ntru_crypto_sha256_digest(
|
||||
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_SHA256_H */
|
||||
@ -19,7 +19,6 @@
|
||||
#include <oqs/aes.h>
|
||||
#include <oqs/sha3.h>
|
||||
#include <oqs/rand.h>
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/kem.h>
|
||||
#include <oqs/sig.h>
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ if ENABLE_SHARED
|
||||
check_PROGRAMS = example_kem
|
||||
else
|
||||
check_PROGRAMS = example_kem speed_kem test_kem \
|
||||
minimal_kex_oqs test_kex \
|
||||
example_sig speed_sig test_sig \
|
||||
test_aes test_rand test_sha3 kat_kem
|
||||
endif
|
||||
@ -14,10 +13,8 @@ example_kem_SOURCES = example_kem.c
|
||||
example_sig_SOURCES = example_sig.c
|
||||
speed_kem_SOURCES = speed_kem.c
|
||||
speed_sig_SOURCES = speed_sig.c
|
||||
minimal_kex_oqs_SOURCES = minimal_kex_oqs.c
|
||||
test_aes_SOURCES = test_aes.c
|
||||
test_kem_SOURCES = test_kem.c
|
||||
test_kex_SOURCES = test_kex.c
|
||||
test_rand_SOURCES = test_rand.c
|
||||
test_sha3_SOURCES = test_sha3.c
|
||||
test_sig_SOURCES = test_sig.c
|
||||
@ -25,12 +22,10 @@ kat_kem_SOURCES = kat_kem.c
|
||||
|
||||
example_kem_LDADD = ${LIB_FLAGS}
|
||||
example_sig_LDADD = ${LIB_FLAGS}
|
||||
minimal_kex_oqs_LDADD = ${LIB_FLAGS}
|
||||
speed_kem_LDADD = ${LIB_FLAGS}
|
||||
speed_sig_LDADD = ${LIB_FLAGS}
|
||||
test_aes_LDADD = ${LIB_FLAGS}
|
||||
test_kem_LDADD = ${LIB_FLAGS}
|
||||
test_kex_LDADD = ${LIB_FLAGS}
|
||||
test_rand_LDADD = ${LIB_FLAGS}
|
||||
test_sha3_LDADD = ${LIB_FLAGS}
|
||||
test_sig_LDADD = ${LIB_FLAGS}
|
||||
@ -39,12 +34,10 @@ kat_kem_LDADD = ${LIB_FLAGS}
|
||||
if USE_OPENSSL
|
||||
example_kem_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
example_sig_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
minimal_kex_oqs_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
speed_kem_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
speed_sig_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_aes_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_kem_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_kex_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_rand_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_sha3_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
test_sig_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
|
||||
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* minimal_kex_oqs.c
|
||||
*
|
||||
* Minimal example of a Diffie-Hellman post-quantum key exchange method
|
||||
* implemented in liboqs.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <oqs/oqs.h>
|
||||
|
||||
/* Cleaning up memory etc */
|
||||
void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
|
||||
size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
|
||||
uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
|
||||
OQS_KEX *kex, OQS_RAND *rnd);
|
||||
|
||||
#ifdef ENABLE_KEX_NTRU
|
||||
int main(void) {
|
||||
/* Key exchange parameters */
|
||||
void *alice_priv = NULL; // Alice's private key
|
||||
uint8_t *alice_msg = NULL; // Alice's message
|
||||
size_t alice_msg_len = 0; // Alice's message length
|
||||
uint8_t *alice_key = NULL; // Alice's final key
|
||||
size_t alice_key_len = 0; // Alice's final key length
|
||||
|
||||
uint8_t *bob_msg = NULL; // Bob's message
|
||||
size_t bob_msg_len = 0; // Bob's message length
|
||||
uint8_t *bob_key = NULL; // Bob's final key
|
||||
size_t bob_key_len = 0; // Bob's final key length
|
||||
|
||||
/* Setup the key exchange protocol */
|
||||
enum OQS_KEX_alg_name alg_name = OQS_KEX_alg_default; // Alg. name
|
||||
OQS_RAND *rnd = NULL; // Source of randomness
|
||||
OQS_KEX *kex = NULL; // OQS_KEX structure
|
||||
|
||||
/* Setup the source of randomness */
|
||||
rnd = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
|
||||
if (rnd == NULL) {
|
||||
eprintf("ERROR: Setting up the randomness source!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Populate the OQS_KEX structure, here's where liboqs sets up
|
||||
* the specific details of the selected KEX implementation */
|
||||
kex = OQS_KEX_new(rnd, alg_name, NULL, 0, NULL);
|
||||
if (kex == NULL) {
|
||||
eprintf("ERROR: OQS_KEX_new failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Proceed with the Diffie-Hellman key exchange mechanism */
|
||||
printf("===============================================================\n");
|
||||
printf("Diffie-Hellman post-quantum key exchange: %s\n", kex->method_name);
|
||||
printf("===============================================================\n");
|
||||
|
||||
/* Alice's initial message */
|
||||
OQS_STATUS success = OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_alice_0 failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
OQS_print_part_hex_string("Alice message", alice_msg, alice_msg_len, 20);
|
||||
|
||||
/* Bob's response */
|
||||
success = OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len,
|
||||
&bob_key, &bob_key_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_bob failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
OQS_print_part_hex_string("Bob message", bob_msg, bob_msg_len, 20);
|
||||
OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
|
||||
|
||||
/* Alice processes Bob's response */
|
||||
success = OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key,
|
||||
&alice_key_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_alice_1 failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
|
||||
|
||||
/* Compare key lengths */
|
||||
if (alice_key_len != bob_key_len) {
|
||||
eprintf("ERROR: Alice's session key and Bob's session keys "
|
||||
"have different lengths (%zu vs %zu)!\n",
|
||||
alice_key_len, bob_key_len);
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Compare key values */
|
||||
success = memcmp(alice_key, bob_key, alice_key_len);
|
||||
if (success != 0) {
|
||||
eprintf("ERROR: Alice's session key and Bob's session "
|
||||
"key are not equal!\n");
|
||||
OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
|
||||
OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Success and clean-up */
|
||||
printf("Alice and Bob's session keys match.\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
#else // !ENABLE_KEX_LWE_FRODO
|
||||
int main(void) {
|
||||
printf("KEX algorithm not available. Make sure configure was run properly; see Readme.md.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
|
||||
size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
|
||||
uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
|
||||
OQS_KEX *kex, OQS_RAND *rnd) {
|
||||
/* Secure cleaning */
|
||||
OQS_MEM_secure_free(alice_msg, alice_msg_len);
|
||||
OQS_MEM_secure_free(alice_key, alice_key_len);
|
||||
OQS_MEM_secure_free(bob_msg, bob_msg_len);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
OQS_KEX_alice_priv_free(kex, alice_priv);
|
||||
OQS_KEX_free(kex);
|
||||
OQS_RAND_free(rnd);
|
||||
}
|
||||
404
tests/test_kex.c
404
tests/test_kex.c
@ -1,404 +0,0 @@
|
||||
#if defined(_WIN32)
|
||||
#pragma warning(disable : 4244 4293)
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <oqs/oqs.h>
|
||||
|
||||
#include "ds_benchmark.h"
|
||||
|
||||
struct kex_testcase {
|
||||
enum OQS_KEX_alg_name alg_name;
|
||||
unsigned char *seed;
|
||||
size_t seed_len;
|
||||
const char *named_parameters;
|
||||
const char *id;
|
||||
int run;
|
||||
int iter;
|
||||
};
|
||||
|
||||
/* Add new testcases here */
|
||||
struct kex_testcase kex_testcases[] = {
|
||||
#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
|
||||
#ifdef ENABLE_KEX_NTRU
|
||||
{OQS_KEX_alg_ntru, NULL, 0, NULL, "ntru", 0, 25},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#define KEX_TEST_ITERATIONS 100
|
||||
#define KEX_BENCH_SECONDS_DEFAULT 1
|
||||
|
||||
static OQS_STATUS 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;
|
||||
OQS_STATUS 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 = 0;
|
||||
|
||||
uint8_t *bob_msg = NULL;
|
||||
size_t bob_msg_len;
|
||||
uint8_t *bob_key = NULL;
|
||||
size_t bob_key_len = 0;
|
||||
|
||||
/* 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 != OQS_SUCCESS) {
|
||||
eprintf("OQS_KEX_alice_0 failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
OQS_print_part_hex_string("Alice message", alice_msg, alice_msg_len, 20);
|
||||
}
|
||||
|
||||
/* 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 != OQS_SUCCESS) {
|
||||
eprintf("OQS_KEX_bob failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
OQS_print_part_hex_string("Bob message", bob_msg, bob_msg_len, 20);
|
||||
OQS_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 != OQS_SUCCESS) {
|
||||
eprintf("OQS_KEX_alice_1 failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (print) {
|
||||
OQS_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;
|
||||
}
|
||||
if (memcmp(alice_key, bob_key, alice_key_len) != 0) {
|
||||
eprintf("ERROR: Alice's session key and Bob's session key are not equal\n");
|
||||
OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
|
||||
OQS_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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
rc = OQS_ERROR;
|
||||
|
||||
cleanup:
|
||||
OQS_MEM_insecure_free(alice_msg);
|
||||
OQS_MEM_secure_free(alice_key, alice_key_len);
|
||||
OQS_MEM_insecure_free(bob_msg);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
OQS_KEX_alice_priv_free(kex, alice_priv);
|
||||
OQS_KEX_free(kex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static OQS_STATUS 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;
|
||||
OQS_STATUS 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 != OQS_SUCCESS) {
|
||||
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 != OQS_SUCCESS) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
printf("All session keys matched.\n");
|
||||
OQS_RAND_report_statistics(occurrences, "");
|
||||
printf("\n\n");
|
||||
|
||||
ret = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
ret = OQS_ERROR;
|
||||
|
||||
cleanup:
|
||||
OQS_KEX_free(kex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cleanup_alice_0(OQS_KEX *kex, void *alice_priv, uint8_t *alice_msg) {
|
||||
OQS_MEM_insecure_free(alice_msg);
|
||||
OQS_KEX_alice_priv_free(kex, alice_priv);
|
||||
}
|
||||
|
||||
static void cleanup_bob(uint8_t *bob_msg, uint8_t *bob_key, size_t bob_key_len) {
|
||||
OQS_MEM_insecure_free(bob_msg);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
}
|
||||
|
||||
static OQS_STATUS 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 size_t seconds) {
|
||||
|
||||
OQS_KEX *kex = NULL;
|
||||
OQS_STATUS 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 = 0;
|
||||
|
||||
uint8_t *bob_msg = NULL;
|
||||
size_t bob_msg_len;
|
||||
uint8_t *bob_key = NULL;
|
||||
size_t bob_key_len = 0;
|
||||
|
||||
/* 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_key_len); }, "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); OQS_MEM_secure_free(alice_key, alice_key_len); }, "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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
rc = OQS_ERROR;
|
||||
|
||||
cleanup:
|
||||
OQS_MEM_insecure_free(alice_msg);
|
||||
OQS_MEM_secure_free(alice_key, alice_key_len);
|
||||
OQS_MEM_insecure_free(bob_msg);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
OQS_KEX_alice_priv_free(kex, alice_priv);
|
||||
OQS_KEX_free(kex);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static OQS_STATUS 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;
|
||||
OQS_STATUS 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 = 0;
|
||||
|
||||
uint8_t *bob_msg = NULL;
|
||||
size_t bob_msg_len;
|
||||
uint8_t *bob_key = NULL;
|
||||
size_t bob_key_len = 0;
|
||||
|
||||
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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
rc = OQS_ERROR;
|
||||
|
||||
cleanup:
|
||||
OQS_MEM_insecure_free(alice_msg);
|
||||
OQS_MEM_secure_free(alice_key, alice_key_len);
|
||||
OQS_MEM_insecure_free(bob_msg);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
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) {
|
||||
|
||||
OQS_STATUS success = OQS_SUCCESS;
|
||||
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 != OQS_SUCCESS) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
printf("memory benchmarks done, exiting..\n");
|
||||
success = OQS_SUCCESS;
|
||||
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 != OQS_SUCCESS) {
|
||||
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 = OQS_SUCCESS;
|
||||
goto cleanup;
|
||||
|
||||
err:
|
||||
success = OQS_ERROR;
|
||||
eprintf("ERROR!\n");
|
||||
|
||||
cleanup:
|
||||
OQS_RAND_free(rand);
|
||||
|
||||
return (success == OQS_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user