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:
Shravan Mishra 2018-10-03 21:16:49 -04:00 committed by Douglas Stebila
parent d6bfc7384c
commit 3dbd609e92
58 changed files with 5 additions and 11071 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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`

View File

@ -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/

View File

@ -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
-------------------------------

View File

@ -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

View File

@ -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>

View File

@ -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],

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -1,4 +0,0 @@
AUTOMAKE_OPTIONS = foreign
noinst_LTLIBRARIES = libkex.la
libkex_la_SOURCES = kex.c

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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)
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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>

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}