Prototype implementation of IKE key exchange via NTRU encryption
This commit is contained in:
parent
e9b49d412b
commit
146ad86be5
|
@ -239,6 +239,7 @@ ARG_ENABL_SET([pkcs11], [enables the PKCS11 token support plugin.])
|
|||
ARG_ENABL_SET([ctr], [enables the Counter Mode wrapper crypto plugin.])
|
||||
ARG_ENABL_SET([ccm], [enables the CCM AEAD wrapper crypto plugin.])
|
||||
ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.])
|
||||
ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.])
|
||||
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
|
||||
ARG_ENABL_SET([unity], [enables Cisco Unity extension plugin.])
|
||||
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
|
||||
|
@ -1033,6 +1034,7 @@ ADD_PLUGIN([hmac], [s charon scripts nm cmd])
|
|||
ADD_PLUGIN([ctr], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([ccm], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([gcm], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([ntru], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([attr], [h charon])
|
||||
ADD_PLUGIN([attr-sql], [h charon])
|
||||
ADD_PLUGIN([load-tester], [c charon])
|
||||
|
@ -1170,6 +1172,7 @@ AM_CONDITIONAL(USE_CTR, test x$ctr = xtrue)
|
|||
AM_CONDITIONAL(USE_CCM, test x$ccm = xtrue)
|
||||
AM_CONDITIONAL(USE_GCM, test x$gcm = xtrue)
|
||||
AM_CONDITIONAL(USE_AF_ALG, test x$af_alg = xtrue)
|
||||
AM_CONDITIONAL(USE_NTRU, test x$ntru = xtrue)
|
||||
|
||||
# charon plugins
|
||||
# ----------------
|
||||
|
@ -1375,6 +1378,7 @@ AC_CONFIG_FILES([
|
|||
src/libstrongswan/plugins/ccm/Makefile
|
||||
src/libstrongswan/plugins/gcm/Makefile
|
||||
src/libstrongswan/plugins/af_alg/Makefile
|
||||
src/libstrongswan/plugins/ntru/Makefile
|
||||
src/libstrongswan/plugins/test_vectors/Makefile
|
||||
src/libstrongswan/tests/Makefile
|
||||
src/libhydra/Makefile
|
||||
|
|
|
@ -481,6 +481,13 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_NTRU
|
||||
SUBDIRS += plugins/ntru
|
||||
if MONOLITHIC
|
||||
libstrongswan_la_LIBADD += plugins/ntru/libstrongswan-ntru.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_TEST_VECTORS
|
||||
SUBDIRS += plugins/test_vectors
|
||||
if MONOLITHIC
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
0x04 "md5WithRSAEncryption" OID_MD5_WITH_RSA
|
||||
0x05 "sha-1WithRSAEncryption" OID_SHA1_WITH_RSA
|
||||
0x07 "id-RSAES-OAEP" OID_RSAES_OAEP
|
||||
0x08 "id-mgf1"
|
||||
0x09 "id-pSpecified"
|
||||
0x0B "sha256WithRSAEncryption" OID_SHA256_WITH_RSA
|
||||
0x0C "sha384WithRSAEncryption" OID_SHA384_WITH_RSA
|
||||
|
@ -211,6 +212,29 @@
|
|||
0x02 ""
|
||||
0x02 ""
|
||||
0x4B "TCGID" OID_TCGID
|
||||
0xc1 ""
|
||||
0x16 "ntruCryptosystems"
|
||||
0x01 "eess"
|
||||
0x01 "eess1"
|
||||
0x01 "eess1-algs"
|
||||
0x01 "ntru-EESS1v1-SVES"
|
||||
0x02 "ntru-EESS1v1-SVSSA"
|
||||
0x03 "ntru-EESS1v1-NTRUSign"
|
||||
0x02 "eess1-params"
|
||||
0x01 "ees251ep1"
|
||||
0x02 "ees347ep1"
|
||||
0x03 "ees503ep1"
|
||||
0x07 "ees251sp2"
|
||||
0x0C "ees251ep4"
|
||||
0x0D "ees251ep5"
|
||||
0x0E "ees251sp3"
|
||||
0x0F "ees251sp4"
|
||||
0x10 "ees251sp5"
|
||||
0x11 "ees251sp6"
|
||||
0x12 "ees251sp7"
|
||||
0x13 "ees251sp8"
|
||||
0x14 "ees251sp9"
|
||||
0x03 "eess1-encodingMethods"
|
||||
0x05 "security"
|
||||
0x05 "mechanisms"
|
||||
0x07 "id-pkix"
|
||||
|
|
|
@ -45,7 +45,12 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, ECP_512_BP, ECP_521_BIT,
|
|||
ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_CUSTOM, ECP_512_BP,
|
||||
"MODP_NULL",
|
||||
"MODP_CUSTOM");
|
||||
ENUM_END(diffie_hellman_group_names, MODP_CUSTOM);
|
||||
ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_CUSTOM,
|
||||
"NTRU_112",
|
||||
"NTRU_128",
|
||||
"NTRU_192",
|
||||
"NTRU_256");
|
||||
ENUM_END(diffie_hellman_group_names, NTRU_256_BIT);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,6 +64,11 @@ enum diffie_hellman_group_t {
|
|||
MODP_NULL = 1024,
|
||||
/** MODP group with custom generator/prime */
|
||||
MODP_CUSTOM = 1025,
|
||||
/** Parameters defined by IEEE 1363.1, in PRIVATE USE */
|
||||
NTRU_112_BIT = 1030,
|
||||
NTRU_128_BIT = 1031,
|
||||
NTRU_192_BIT = 1032,
|
||||
NTRU_256_BIT = 1033
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%{
|
||||
/*
|
||||
* Copyright (C) 2009 Andreas Steffen
|
||||
* Hochschule fuer Technik Rapperswil, Switzerland
|
||||
* Copyright (C) 2009-2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil, Switzerland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -161,5 +161,9 @@ ecp224bp, DIFFIE_HELLMAN_GROUP, ECP_224_BP, 0
|
|||
ecp256bp, DIFFIE_HELLMAN_GROUP, ECP_256_BP, 0
|
||||
ecp384bp, DIFFIE_HELLMAN_GROUP, ECP_384_BP, 0
|
||||
ecp512bp, DIFFIE_HELLMAN_GROUP, ECP_512_BP, 0
|
||||
ntru112, DIFFIE_HELLMAN_GROUP, NTRU_112_BIT, 0
|
||||
ntru128, DIFFIE_HELLMAN_GROUP, NTRU_128_BIT, 0
|
||||
ntru192, DIFFIE_HELLMAN_GROUP, NTRU_192_BIT, 0
|
||||
ntru256, DIFFIE_HELLMAN_GROUP, NTRU_256_BIT, 0
|
||||
noesn, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0
|
||||
esn, EXTENDED_SEQUENCE_NUMBERS, EXT_SEQ_NUMBERS, 0
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
-rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-ntru.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-ntru.la
|
||||
endif
|
||||
|
||||
libstrongswan_ntru_la_SOURCES = \
|
||||
ntru_plugin.h ntru_plugin.c \
|
||||
ntru_ke.h ntru_ke.c \
|
||||
ntru_crypto/ntru_crypto.h ntru_crypto/ntru_crypto_error.h \
|
||||
ntru_crypto/ntru_crypto_drbg.h ntru_crypto/ntru_crypto_drbg.c \
|
||||
ntru_crypto/ntru_crypto_hash_basics.h \
|
||||
ntru_crypto/ntru_crypto_hash.h ntru_crypto/ntru_crypto_hash.c \
|
||||
ntru_crypto/ntru_crypto_hmac.h ntru_crypto/ntru_crypto_hmac.c \
|
||||
ntru_crypto/ntru_crypto_msbyte_uint32.h \
|
||||
ntru_crypto/ntru_crypto_msbyte_uint32.c \
|
||||
ntru_crypto/ntru_crypto_ntru_convert.h \
|
||||
ntru_crypto/ntru_crypto_ntru_convert.c \
|
||||
ntru_crypto/ntru_crypto_ntru_encrypt.c \
|
||||
ntru_crypto/ntru_crypto_ntru_encrypt_key.h \
|
||||
ntru_crypto/ntru_crypto_ntru_encrypt_key.c \
|
||||
ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.h \
|
||||
ntru_crypto/ntru_crypto_ntru_encrypt_param_sets.c \
|
||||
ntru_crypto/ntru_crypto_ntru_mgf1.h ntru_crypto/ntru_crypto_ntru_mgf1.c \
|
||||
ntru_crypto/ntru_crypto_ntru_poly.h ntru_crypto/ntru_crypto_ntru_poly.c \
|
||||
ntru_crypto/ntru_crypto_platform.h ntru_crypto/ntru_crypto_sha.h\
|
||||
ntru_crypto/ntru_crypto_sha1.h ntru_crypto/ntru_crypto_sha1.c\
|
||||
ntru_crypto/ntru_crypto_sha2.h ntru_crypto/ntru_crypto_sha2.c\
|
||||
ntru_crypto/ntru_crypto_sha256.h ntru_crypto/ntru_crypto_sha256.c
|
||||
|
||||
libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_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_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_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 */
|
||||
|
||||
|
||||
#if defined ( __cplusplus )
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* NTRU_CRYPTO_H */
|
|
@ -0,0 +1,724 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_drbg.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 up to 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "ntru_crypto_drbg.h"
|
||||
#include "ntru_crypto_hmac.h"
|
||||
|
||||
|
||||
/************************
|
||||
* HMAC_DRBG parameters *
|
||||
************************/
|
||||
|
||||
/* Note: nonce size is sec_strength_bits/2 */
|
||||
#define HMAC_DRBG_MAX_MIN_ENTROPY_NONCE_BYTES \
|
||||
(DRBG_MAX_SEC_STRENGTH_BITS + DRBG_MAX_SEC_STRENGTH_BITS/2)/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;
|
||||
|
||||
|
||||
/* DRBG state structure
|
||||
* Note: this could contain a DRBG_TYPE to direct allocation, instantiation,
|
||||
* and generation to multiple types of DRBGs; at present only the
|
||||
* SHA256_HMAC_DRBG is implemented
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t handle;
|
||||
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 = (sec_strength_bits + sec_strength_bits/2) / 8;
|
||||
entropy_nonce_bytes = min_bytes_of_entropy * num_bytes_per_byte_of_entropy;
|
||||
for (i = 0; i < entropy_nonce_bytes; i++)
|
||||
if (entropy_fn(GET_BYTE_OF_ENTROPY, entropy_nonce+i) == 0)
|
||||
DRBG_RET(DRBG_ENTROPY_FAIL);
|
||||
|
||||
/* allocate SHA256_HMAC_DRBG state */
|
||||
|
||||
s = (SHA256_HMAC_DRBG_STATE*) malloc(sizeof(SHA256_HMAC_DRBG_STATE));
|
||||
if (s == NULL) {
|
||||
DRBG_RET(DRBG_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
/* allocate HMAC context */
|
||||
|
||||
memset(key, 0, sizeof(key));
|
||||
if ((result = ntru_crypto_hmac_create_ctx(NTRU_CRYPTO_HASH_ALGID_SHA256,
|
||||
key, sizeof(key),
|
||||
&s->hmac_ctx)) !=
|
||||
NTRU_CRYPTO_HMAC_OK) {
|
||||
free(s);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* init and update internal state */
|
||||
|
||||
memset(s->V, 0x01, sizeof(s->V));
|
||||
if ((result = sha256_hmac_drbg_update(s, key, sizeof(key),
|
||||
entropy_nonce, entropy_nonce_bytes,
|
||||
pers_str, pers_str_bytes)) != DRBG_OK) {
|
||||
(void) ntru_crypto_hmac_destroy_ctx(s->hmac_ctx);
|
||||
memset(s->V, 0, sizeof(s->V));
|
||||
free(s);
|
||||
}
|
||||
memset(entropy_nonce, 0, sizeof(entropy_nonce));
|
||||
|
||||
/* init instantiation parameters */
|
||||
|
||||
s->sec_strength = sec_strength_bits;
|
||||
s->requests_left = HMAC_DRBG_MAX_REQUESTS;
|
||||
s->entropy_fn = entropy_fn;
|
||||
*state = s;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* sha256_hmac_drbg_free
|
||||
*
|
||||
* This routine frees a SHA-256 HMAC_DRBG internal state.
|
||||
*
|
||||
* Returns DRBG_OK if successful.
|
||||
* Returns DRBG_BAD_PARAMETER if inappropriate NULL pointers are passed.
|
||||
*/
|
||||
|
||||
static void
|
||||
sha256_hmac_drbg_free(
|
||||
SHA256_HMAC_DRBG_STATE *s)
|
||||
{
|
||||
if (s->hmac_ctx) {
|
||||
(void) ntru_crypto_hmac_destroy_ctx(s->hmac_ctx);
|
||||
}
|
||||
memset(s->V, 0, sizeof(s->V));
|
||||
s->sec_strength = 0;
|
||||
s->requests_left = 0;
|
||||
s->entropy_fn = NULL;
|
||||
free(s);
|
||||
}
|
||||
|
||||
|
||||
/* sha256_hmac_drbg_reseed
|
||||
*
|
||||
* This function reseeds an instantiated SHA256_HMAC DRBG.
|
||||
*
|
||||
* Returns DRBG_OK if successful.
|
||||
* Returns HMAC errors if they occur.
|
||||
*/
|
||||
|
||||
static uint32_t
|
||||
sha256_hmac_drbg_reseed(
|
||||
SHA256_HMAC_DRBG_STATE *s)
|
||||
{
|
||||
uint8_t entropy[HMAC_DRBG_MAX_ENTROPY_NONCE_BYTES];
|
||||
uint32_t entropy_bytes;
|
||||
uint32_t min_bytes_of_entropy;
|
||||
uint8_t num_bytes_per_byte_of_entropy;
|
||||
uint8_t key[32]; // array of md_len size for sha256_hmac_drbg_update()
|
||||
uint32_t result;
|
||||
uint32_t i;
|
||||
|
||||
/* calculate number of bytes needed for the entropy input
|
||||
* for a SHA256_HMAC_DRBG, and get them from the entropy source
|
||||
*/
|
||||
|
||||
if (s->entropy_fn(GET_NUM_BYTES_PER_BYTE_OF_ENTROPY,
|
||||
&num_bytes_per_byte_of_entropy) == 0)
|
||||
DRBG_RET(DRBG_ENTROPY_FAIL);
|
||||
if ((num_bytes_per_byte_of_entropy == 0) ||
|
||||
(num_bytes_per_byte_of_entropy >
|
||||
DRBG_MAX_BYTES_PER_BYTE_OF_ENTROPY))
|
||||
DRBG_RET(DRBG_ENTROPY_FAIL);
|
||||
|
||||
min_bytes_of_entropy = 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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->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) {
|
||||
sha256_hmac_drbg_free((SHA256_HMAC_DRBG_STATE *)drbg->state);
|
||||
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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
return sha256_hmac_drbg_generate((SHA256_HMAC_DRBG_STATE *)drbg->state,
|
||||
sec_strength_bits, num_bytes, out);
|
||||
}
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_drbg.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 { /* 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 */
|
||||
|
||||
|
||||
/***************
|
||||
* 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_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 */
|
|
@ -0,0 +1,47 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_serror.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,335 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_hash.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_hash.c
|
||||
*
|
||||
* Contents: Routines implementing the hash object abstraction.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.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_FINAL_FN final_zero_pad;
|
||||
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_FINAL_FN) SHA_1_FINAL_ZERO_PAD_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_FINAL_FN) SHA_256_FINAL_ZERO_PAD_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 algoirithm 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_final_zero_pad
|
||||
*
|
||||
* This routine completes the hash calculation using zero padding 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_zero_pad(
|
||||
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_zero_pad(&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);
|
||||
}
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_hash.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 - addrfor 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_final_zero_pad
|
||||
*
|
||||
* This routine completes the hash calculation using zero padding 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_zero_pad(
|
||||
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 */
|
|
@ -0,0 +1,75 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_hash_basics.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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)
|
||||
#define HASH_ZERO_PAD (1 << 2)
|
||||
|
||||
|
||||
#endif /* NTRU_CRYPTO_HASH_BASICS_H */
|
|
@ -0,0 +1,320 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_hmac.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_hmac.c
|
||||
*
|
||||
* Contents: Routines implementing the HMAC hash calculation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.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 ((ctx = (NTRU_CRYPTO_HMAC_CTX*) malloc(sizeof(NTRU_CRYPTO_HMAC_CTX))) ==
|
||||
NULL)
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/*/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_hmac.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,92 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_mbyte_uint32.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 <stdlib.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++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_msbyte_uint32.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,581 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_convert.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_ntru_convert.c
|
||||
*
|
||||
* Contents: Conversion routines for NTRUEncrypt, including packing, unpacking,
|
||||
* and others.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.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;
|
||||
|
||||
assert(octets);
|
||||
assert(trits);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(octets);
|
||||
assert(trits);
|
||||
|
||||
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;
|
||||
|
||||
assert(coeffs);
|
||||
assert(octets);
|
||||
|
||||
*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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(trits);
|
||||
assert(octet);
|
||||
|
||||
*octet = 0;
|
||||
for (i = 4; i >= 0; i--) {
|
||||
*octet = (*octet * 3) + trits[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(trits);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
trits[i] = octet % 3;
|
||||
octet = (octet - trits[i]) / 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(in);
|
||||
assert(out);
|
||||
|
||||
for (i = 0; i < in_len; i++) {
|
||||
out[in[i]] = trit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(in);
|
||||
assert(indices_plus1);
|
||||
assert(indices_minus1);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
--num_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.
|
||||
*/
|
||||
|
||||
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 */
|
||||
{
|
||||
assert(indices);
|
||||
assert(buf);
|
||||
assert(out);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
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;
|
||||
int shift;
|
||||
uint16_t i;
|
||||
|
||||
assert(in_len);
|
||||
assert(in);
|
||||
assert((n_bits > 8) && (n_bits < 16));
|
||||
assert(out);
|
||||
|
||||
/* 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);
|
||||
shift = 8 - shift;
|
||||
if (shift < 1) {
|
||||
|
||||
/* next full octet is in current input word */
|
||||
|
||||
shift += n_bits;
|
||||
temp = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* put remaining bits of input word in temp as partial octet,
|
||||
* and increment index to next input word
|
||||
*/
|
||||
temp = in[i] << (uint16_t)shift;
|
||||
|
||||
++i;
|
||||
}
|
||||
shift = n_bits - shift;
|
||||
}
|
||||
|
||||
/* output any bits remaining in last input word */
|
||||
|
||||
if (shift != n_bits - 8) {
|
||||
*out++ = (uint8_t)(temp & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ntru_octets_2_elements
|
||||
*
|
||||
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
||||
* n-bit elements, 8 < n_bits < 16. Any extra bits are discarded.
|
||||
*/
|
||||
|
||||
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 = (1 << n_bits) - 1;
|
||||
int shift;
|
||||
uint16_t i;
|
||||
|
||||
assert(in_len > 1);
|
||||
assert(in);
|
||||
assert((n_bits > 8) && (n_bits < 16));
|
||||
assert(out);
|
||||
|
||||
/* unpack */
|
||||
|
||||
temp = 0;
|
||||
shift = n_bits;
|
||||
i = 0;
|
||||
while (i < in_len) {
|
||||
shift = 8 - shift;
|
||||
if (shift < 0) {
|
||||
|
||||
/* the current octet will not fill the current element */
|
||||
|
||||
shift += n_bits;
|
||||
|
||||
} else {
|
||||
|
||||
/* add bits from the current octet to fill the current element and
|
||||
* output the element
|
||||
*/
|
||||
|
||||
temp |= ((uint16_t)in[i]) >> shift;
|
||||
*out++ = temp & mask;
|
||||
temp = 0;
|
||||
}
|
||||
|
||||
/* add the remaining bits of the current octet to start an element */
|
||||
|
||||
shift = n_bits - shift;
|
||||
temp |= ((uint16_t)in[i]) << shift;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_convert.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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
|
@ -0,0 +1,397 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_ntru_encrypt_key.c
|
||||
*
|
||||
* Contents: Routines for exporting and importing public and private keys
|
||||
* for NTRUEncrypt.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.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;
|
||||
|
||||
assert(key_blob_len);
|
||||
assert(key_blob);
|
||||
assert(pubkey_pack_type);
|
||||
assert(params);
|
||||
assert(pubkey);
|
||||
|
||||
/* 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:
|
||||
assert(privkey_pack_type);
|
||||
assert(privkey);
|
||||
if (pubkey_parse)
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
assert(params);
|
||||
assert(pubkey_pack_type);
|
||||
assert(pubkey_blob_len);
|
||||
|
||||
*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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
void
|
||||
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 */
|
||||
{
|
||||
assert(params);
|
||||
assert(pubkey);
|
||||
assert(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:
|
||||
assert(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_recreate_pubkey_blob
|
||||
*
|
||||
* Returns a public key blob, recreated from an already-packed public key.
|
||||
*/
|
||||
|
||||
void
|
||||
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 */
|
||||
{
|
||||
assert(params);
|
||||
assert(packed_pubkey);
|
||||
assert(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:
|
||||
assert(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ntru_crypto_ntru_encrypt_key_create_privkey_blob
|
||||
*
|
||||
* Returns a private key blob, packed according to the packing type provided.
|
||||
*/
|
||||
|
||||
void
|
||||
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 */
|
||||
{
|
||||
assert(params);
|
||||
assert(pubkey);
|
||||
assert(privkey);
|
||||
assert(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:
|
||||
assert(FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_cencrypt_key.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#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 void
|
||||
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 void
|
||||
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 void
|
||||
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 */
|
|
@ -0,0 +1,457 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_param_sets.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_ntru_encrypt_param_sets.c
|
||||
*
|
||||
* Contents: Defines the NTRUEncrypt parameter sets.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "ntru_crypto_ntru_encrypt_param_sets.h"
|
||||
|
||||
|
||||
/* parameter sets */
|
||||
|
||||
static NTRU_ENCRYPT_PARAM_SET ntruParamSets[] = {
|
||||
|
||||
{
|
||||
NTRU_EES401EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
32, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES449EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
31, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES677EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
27, /* min. no. of hash calls for IGF-2 */
|
||||
9, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1087EP2, /* parameter-set id */
|
||||
{0x00, 0x06, 0x03}, /* OID */
|
||||
0x25, /* DER id */
|
||||
10, /* no. of bits in N (i.e., in an index) */
|
||||
1087, /* N */
|
||||
32, /* security strength in octets */
|
||||
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 */
|
||||
25, /* min. no. of hash calls for IGF-2 */
|
||||
14, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES541EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
15, /* min. no. of hash calls for IGF-2 */
|
||||
11, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES613EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
16, /* min. no. of hash calls for IGF-2 */
|
||||
13, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES887EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
13, /* min. no. of hash calls for IGF-2 */
|
||||
12, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1171EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
20, /* min. no. of hash calls for IGF-2 */
|
||||
15, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES659EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
14, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES761EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
13, /* min. no. of hash calls for IGF-2 */
|
||||
16, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1087EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
13, /* min. no. of hash calls for IGF-2 */
|
||||
14, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES1499EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
17, /* min. no. of hash calls for IGF-2 */
|
||||
19, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES401EP2, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
136, /* m(1)_max */
|
||||
2005, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
10, /* min. no. of hash calls for IGF-2 */
|
||||
6, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES439EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
126, /* m(1)_max */
|
||||
439, /* 2^c - (2^c mod N) */
|
||||
9, /* c */
|
||||
1, /* lLen */
|
||||
15, /* min. no. of hash calls for IGF-2 */
|
||||
6, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES593EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
90, /* m(1)_max */
|
||||
1779, /* 2^c - (2^c mod N) */
|
||||
11, /* c */
|
||||
1, /* lLen */
|
||||
12, /* min. no. of hash calls for IGF-2 */
|
||||
5, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
{
|
||||
NTRU_EES743EP1, /* parameter-set id */
|
||||
{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 */
|
||||
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 */
|
||||
60, /* m(1)_max */
|
||||
8173, /* 2^c - (2^c mod N) */
|
||||
13, /* c */
|
||||
1, /* lLen */
|
||||
12, /* min. no. of hash calls for IGF-2 */
|
||||
7, /* min. no. of hash calls for MGF-TP-1 */
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_encrypt_param_sets.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
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 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_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 */
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_mgf1.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_ntru_mgf1.c
|
||||
*
|
||||
* Contents: Routines implementing MGF-TP-1 and MGF-1.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.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;
|
||||
|
||||
assert(state);
|
||||
assert(out);
|
||||
|
||||
/* 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;
|
||||
|
||||
assert(seed);
|
||||
assert(buf);
|
||||
assert(mask);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_mgf1.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,586 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_poly.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_ntru_poly.c
|
||||
*
|
||||
* Contents: Routines for generating and operating on polynomials in the
|
||||
* NTRU algorithm.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.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;
|
||||
|
||||
assert(seed);
|
||||
assert(buf);
|
||||
assert(indices);
|
||||
|
||||
/* 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_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 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 mod_q_mask = q - 1;
|
||||
uint16_t i, j, k;
|
||||
|
||||
assert(a);
|
||||
assert(bi);
|
||||
assert(t);
|
||||
assert(c);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* 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 *a, /* in - pointer to ring element a */
|
||||
uint16_t b1i_len, /* in - no. of +1 or -1 coefficients in b1 */
|
||||
uint16_t b2i_len, /* in - no. of +1 or -1 coefficients in b2 */
|
||||
uint16_t 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 N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t *t2 = t + N;
|
||||
uint16_t mod_q_mask = q - 1;
|
||||
uint16_t i;
|
||||
|
||||
assert(a);
|
||||
assert(bi);
|
||||
assert(t);
|
||||
assert(c);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/* 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 - no. of coefficients in a, b, c */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *c) /* out - address for polynomial c */
|
||||
{
|
||||
uint16_t const *bptr = b;
|
||||
uint16_t mod_q_mask = q - 1;
|
||||
uint16_t i, k;
|
||||
|
||||
assert(a);
|
||||
assert(b);
|
||||
assert(c);
|
||||
|
||||
/* c[k] = sum(a[i] * b[k-i]) mod q */
|
||||
|
||||
memset(c, 0, N * sizeof(uint16_t));
|
||||
for (k = 0; k < N; k++) {
|
||||
i = 0;
|
||||
while (i <= k)
|
||||
c[k] += a[i++] * *bptr--;
|
||||
bptr += N;
|
||||
while (i < N)
|
||||
c[k] += a[i++] * *bptr--;
|
||||
c[k] &= mod_q_mask;
|
||||
++bptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
bool
|
||||
ntru_ring_inv(
|
||||
uint16_t *a, /* in - pointer to polynomial a */
|
||||
uint16_t N, /* in - no. of coefficients in a */
|
||||
uint16_t q, /* in - large modulus */
|
||||
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 *t2 = t + N;
|
||||
uint16_t deg_b;
|
||||
uint16_t deg_c;
|
||||
uint16_t deg_f;
|
||||
uint16_t deg_g;
|
||||
uint16_t k = 0;
|
||||
bool done = FALSE;
|
||||
uint16_t i, j;
|
||||
|
||||
assert(a);
|
||||
assert(t);
|
||||
assert(a_inv);
|
||||
|
||||
/* 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 */
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
f[i] = (uint8_t)(a[i] & 1);
|
||||
deg_f = N - 1;
|
||||
|
||||
/* 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 (!done) {
|
||||
|
||||
/* 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) {
|
||||
f = f + i;
|
||||
deg_f = deg_f - i;
|
||||
deg_c = deg_c + i;
|
||||
for (j = deg_c; j >= i; j--)
|
||||
c[j] = c[j-i];
|
||||
for (j = 0; j < i; j++)
|
||||
c[j] = 0;
|
||||
k = k + i;
|
||||
}
|
||||
|
||||
/* adjust degree of f(X) if the highest coefficients are zero
|
||||
* Note: f[0] = 1 from above so the loop will terminate.
|
||||
*/
|
||||
|
||||
while (f[deg_f] == 0)
|
||||
--deg_f;
|
||||
|
||||
/* if f(X) = 1, done
|
||||
* Note: f[0] = 1 from above, so only check the x term and up
|
||||
*/
|
||||
|
||||
for (i = 1; (i <= deg_f) && (f[i] == 0); ++i);
|
||||
if (i > deg_f) {
|
||||
done = TRUE;
|
||||
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), b(X) += c(X) */
|
||||
|
||||
for (i = 0; i <= deg_g; i++)
|
||||
f[i] ^= g[i];
|
||||
|
||||
if (deg_c > deg_b)
|
||||
deg_b = deg_c;
|
||||
for (i = 0; i <= deg_c; i++)
|
||||
b[i] ^= c[i];
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
|
||||
/* lift a^-1 in (Z/2Z)[X]/(X^N - 1) to a^-1 in (Z/qZ)[X]/(X^N -1) */
|
||||
|
||||
for (j = 0; j < 4; ++j) { /* assumes 256 < q <= 65536 */
|
||||
|
||||
/* a^-1 = a^-1 * (2 - a * a^-1) mod q */
|
||||
|
||||
memcpy(t2, a_inv, N * sizeof(uint16_t));
|
||||
ntru_ring_mult_coefficients(a, t2, N, q, t);
|
||||
for (i = 0; i < N; ++i)
|
||||
t[i] = q - t[i];
|
||||
t[0] = t[0] + 2;
|
||||
ntru_ring_mult_coefficients(t2, t, N, q, a_inv);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_poly.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
extern void
|
||||
ntru_ring_mult_indices(
|
||||
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 */
|
||||
|
||||
|
||||
/* 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 *a, /* in - pointer to ring element a */
|
||||
uint16_t b1i_len, /* in - no. of +1 or -1 coefficients in b1 */
|
||||
uint16_t b2i_len, /* in - no. of +1 or -1 coefficients in b2 */
|
||||
uint16_t 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 N, /* in - no. of coefficients in a, b, c */
|
||||
uint16_t q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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 - no. of coefficients in a, b, c */
|
||||
uint16_t q, /* in - large modulus */
|
||||
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 q, /* in - large modulus */
|
||||
uint16_t *t, /* in - temp buffer of 2N elements */
|
||||
uint16_t *a_inv); /* out - address for polynomial a^-1 */
|
||||
|
||||
|
||||
#endif /* NTRU_CRYPTO_NTRU_POLY_H */
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_platform.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_platform.h
|
||||
*
|
||||
* Contents: Platform-specific basic definitions.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef NTRU_CRYPTO_PLATFORM_H
|
||||
#define NTRU_CRYPTO_PLATFORM_H
|
||||
|
||||
#include <library.h>
|
||||
|
||||
#endif /* NTRU_CRYPTO_PLATFORM_H */
|
|
@ -0,0 +1,65 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_sha.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
#define SHA_ZERO_PAD HASH_ZERO_PAD
|
||||
|
||||
|
||||
#endif /* NTRU_CRYPTO_SHA_H */
|
||||
|
|
@ -0,0 +1,588 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_ntru_crypto_sha1.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_sha1.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-1 hash calculation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.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.
|
||||
*
|
||||
* The hash operation can be completed with normal padding or with zero
|
||||
* padding as required for parts of DSA parameter generation, and is indicated
|
||||
* by setting the SHA_FINISH flag. Using zero padding, indicated by setting
|
||||
* the SHA_ZERO_PAD flag, never creates an extra input block because the
|
||||
* bit count is not included in the hashed data.
|
||||
*
|
||||
* 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, zero-pad 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 {
|
||||
c->state[0] = init[0]; // alternate initialization
|
||||
c->state[1] = init[1];
|
||||
c->state[2] = init[2];
|
||||
c->state[3] = init[3];
|
||||
c->state[4] = init[4];
|
||||
}
|
||||
|
||||
/* 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));
|
||||
space = 0;
|
||||
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;
|
||||
|
||||
/* check padding type */
|
||||
|
||||
if (!(flags & SHA_ZERO_PAD)) {
|
||||
|
||||
/* 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];
|
||||
|
||||
} else {
|
||||
|
||||
/* pad unhashed data buffer with zeros and no bit count and
|
||||
* convert to input block
|
||||
*/
|
||||
|
||||
memset(c->unhashed + c->unhashed_len, 0, space);
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
16);
|
||||
}
|
||||
|
||||
/* 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));
|
||||
space = 0;
|
||||
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_final_zero_pad
|
||||
*
|
||||
* This routine completes the SHA-1 hash calculation using zero padding
|
||||
* 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_zero_pad(
|
||||
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 | SHA_ZERO_PAD, 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_crypto_sha1.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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_FINAL_ZERO_PAD_FN \
|
||||
&ntru_crypto_sha1_final_zero_pad
|
||||
/* final function using
|
||||
zero padding */
|
||||
#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.
|
||||
*
|
||||
* The hash operation can be completed with normal padding or with zero
|
||||
* padding as required for parts of DSA parameter generation, and is indicated
|
||||
* by setting the SHA_FINISH flag. Using zero padding, indicated by setting
|
||||
* the SHA_ZERO_PAD flag, never creates an extra input block because the
|
||||
* bit count is not included in the hashed data.
|
||||
*
|
||||
* 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, zero-pad flags */
|
||||
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_final_zero_pad
|
||||
*
|
||||
* This routine completes the SHA-1 hash calculation using zero padding
|
||||
* 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_zero_pad(
|
||||
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 */
|
|
@ -0,0 +1,532 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_sha2.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_sha2.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-256 hash calculation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.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.
|
||||
*
|
||||
* The hash operation can be completed with normal padding or with zero
|
||||
* padding as required for parts of DSA parameter generation, and is indicated
|
||||
* by setting the SHA_FINISH flag. Using zero padding, indicated by setting
|
||||
* the SHA_ZERO_PAD flag, never creates an extra input block because the
|
||||
* bit count is not included in the hashed data.
|
||||
*
|
||||
* 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, zero-pad 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 {
|
||||
c->state[0] = init[0]; // alternate initialization
|
||||
c->state[1] = init[1];
|
||||
c->state[2] = init[2];
|
||||
c->state[3] = init[3];
|
||||
c->state[4] = init[4];
|
||||
c->state[5] = init[5];
|
||||
c->state[6] = init[6];
|
||||
c->state[7] = init[7];
|
||||
}
|
||||
|
||||
/* 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));
|
||||
space = 0;
|
||||
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;
|
||||
|
||||
/* check padding type */
|
||||
|
||||
if (!(flags & SHA_ZERO_PAD)) {
|
||||
|
||||
/* 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];
|
||||
|
||||
} else {
|
||||
|
||||
/* pad unhashed data buffer with zeros and no bit count and
|
||||
* convert to input block
|
||||
*/
|
||||
|
||||
memset(c->unhashed + c->unhashed_len, 0, space);
|
||||
ntru_crypto_msbyte_2_uint32(in_blk, (uint8_t const *) c->unhashed,
|
||||
16);
|
||||
}
|
||||
|
||||
/* 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));
|
||||
space = 0;
|
||||
memset((char *) in_blk, 0, sizeof(in_blk));
|
||||
}
|
||||
|
||||
SHA_RET(SHA_OK)
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_crypto_sha2.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The hash operation can be completed with normal padding or with zero
|
||||
* padding as required for parts of DSA parameter generation, and is indicated
|
||||
* by setting the SHA_FINISH flag. Using zero padding, indicated by setting
|
||||
* the SHA_ZERO_PAD flag, never creates an extra input block because the
|
||||
* bit count is not included in the hashed data.
|
||||
*
|
||||
* 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, zero-pad flags */
|
||||
uint8_t *md); /* out - address for message digest -
|
||||
may be NULL if not FINISH */
|
||||
|
||||
|
||||
#endif /* NTRU_CRYPTO_SHA2_H */
|
|
@ -0,0 +1,140 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_sha256.c is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_sha256.c
|
||||
*
|
||||
* Contents: Routines implementing the SHA-256 hash calculations.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#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_final_zero_pad
|
||||
*
|
||||
* This routine completes the SHA-256 hash calculation using zero padding
|
||||
* 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_zero_pad(
|
||||
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 | SHA_ZERO_PAD, 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/******************************************************************************
|
||||
* NTRU Cryptography Reference Source Code
|
||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
||||
*
|
||||
* ntru_crypto_sha256.h is a component of ntru-crypto.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Security Innovation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* File: ntru_crypto_sha256.h
|
||||
*
|
||||
* Contents: Definitions and declarations for the SHA-256 implementation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CRYPTO_SHA256_H
|
||||
#define 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_FINAL_ZERO_PAD_FN \
|
||||
&ntru_crypto_sha256_final_zero_pad
|
||||
/* final function using
|
||||
zero padding */
|
||||
#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_final_zero_pad
|
||||
*
|
||||
* This routine completes the SHA-256 hash calculation using zero padding
|
||||
* 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_zero_pad(
|
||||
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 /* CRYPTO_SHA256_H */
|
|
@ -0,0 +1,314 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "ntru_ke.h"
|
||||
#include "ntru_plugin.h"
|
||||
|
||||
#include "ntru_crypto/ntru_crypto.h"
|
||||
|
||||
#include <crypto/diffie_hellman.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_ntru_ke_t private_ntru_ke_t;
|
||||
|
||||
/**
|
||||
* Private data of an ntru_ke_t object.
|
||||
*/
|
||||
struct private_ntru_ke_t {
|
||||
/**
|
||||
* Public ntru_ke_t interface.
|
||||
*/
|
||||
ntru_ke_t public;
|
||||
|
||||
/**
|
||||
* Diffie Hellman group number.
|
||||
*/
|
||||
u_int16_t group;
|
||||
|
||||
/**
|
||||
* NTRU Parameter Set ID
|
||||
*/
|
||||
NTRU_ENCRYPT_PARAM_SET_ID param_set_id;
|
||||
|
||||
/**
|
||||
* Cryptographical strength in bits of the NTRU Parameter Set
|
||||
*/
|
||||
u_int32_t strength;
|
||||
|
||||
/**
|
||||
* NTRU Public Key
|
||||
*/
|
||||
chunk_t pub_key;
|
||||
|
||||
/**
|
||||
* NTRU Private Key
|
||||
*/
|
||||
chunk_t priv_key;
|
||||
|
||||
/**
|
||||
* NTRU encrypted shared secret
|
||||
*/
|
||||
chunk_t ciphertext;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
chunk_t shared_secret;
|
||||
|
||||
/**
|
||||
* True if peer is responder
|
||||
*/
|
||||
bool responder;
|
||||
|
||||
/**
|
||||
* True if shared secret is computed
|
||||
*/
|
||||
bool computed;
|
||||
|
||||
/**
|
||||
* Deterministic Random Bit Generator
|
||||
*/
|
||||
DRBG_HANDLE drbg;
|
||||
};
|
||||
|
||||
METHOD(diffie_hellman_t, get_my_public_value, void,
|
||||
private_ntru_ke_t *this, chunk_t *value)
|
||||
{
|
||||
uint16_t pub_key_len, priv_key_len;
|
||||
|
||||
*value = chunk_empty;
|
||||
|
||||
if (this->responder)
|
||||
{
|
||||
if (this->ciphertext.len)
|
||||
{
|
||||
*value = chunk_clone(this->ciphertext);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->pub_key.len == 0)
|
||||
{
|
||||
/* determine the NTRU public and private key sizes */
|
||||
if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set_id,
|
||||
&pub_key_len, NULL,
|
||||
&priv_key_len, NULL) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "error determining NTRU public and private key "
|
||||
"sizes");
|
||||
return;
|
||||
}
|
||||
this->pub_key = chunk_alloc(pub_key_len);
|
||||
this->priv_key = chunk_alloc(priv_key_len);
|
||||
|
||||
/* generate a random NTRU public/private key pair */
|
||||
if (ntru_crypto_ntru_encrypt_keygen(this->drbg, this->param_set_id,
|
||||
&pub_key_len, this->pub_key.ptr,
|
||||
&priv_key_len, this->priv_key.ptr) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "NTRU keypair generation failed");
|
||||
chunk_free(&this->priv_key);
|
||||
chunk_free(&this->pub_key);
|
||||
return;
|
||||
}
|
||||
DBG3(DBG_LIB, "NTRU public key: %B", &this->pub_key);
|
||||
DBG4(DBG_LIB, "NTRU private key: %B", &this->priv_key);
|
||||
}
|
||||
*value = chunk_clone(this->pub_key);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_shared_secret, status_t,
|
||||
private_ntru_ke_t *this, chunk_t *secret)
|
||||
{
|
||||
if (!this->computed || !this->shared_secret.len)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
*secret = chunk_clone(this->shared_secret);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
METHOD(diffie_hellman_t, set_other_public_value, void,
|
||||
private_ntru_ke_t *this, chunk_t value)
|
||||
{
|
||||
u_int16_t plaintext_len, ciphertext_len;
|
||||
|
||||
if (this->priv_key.len)
|
||||
{
|
||||
/* initiator decrypting shared secret */
|
||||
this->ciphertext = chunk_clone(value);
|
||||
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
|
||||
|
||||
/* determine the size of the maximum plaintext */
|
||||
if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr,
|
||||
this->ciphertext.len, this->ciphertext.ptr,
|
||||
&plaintext_len, NULL) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "error determining maximum plaintext size");
|
||||
return;
|
||||
}
|
||||
this->shared_secret = chunk_alloc(plaintext_len);
|
||||
|
||||
/* decrypt the shared secret */
|
||||
if (ntru_crypto_ntru_decrypt(this->priv_key.len, this->priv_key.ptr,
|
||||
this->ciphertext.len, this->ciphertext.ptr,
|
||||
&plaintext_len, this->shared_secret.ptr) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
|
||||
chunk_free(&this->shared_secret);
|
||||
return;
|
||||
}
|
||||
this->shared_secret.len = plaintext_len;
|
||||
this->computed = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* responder generating and encrypting the shared secret */
|
||||
this->responder = TRUE;
|
||||
this->pub_key = chunk_clone(value);
|
||||
|
||||
/* shared secret size is chosen as twice the cryptographical strength */
|
||||
this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
|
||||
|
||||
/* generate the random shared secret */
|
||||
if (ntru_crypto_drbg_generate(this->drbg, this->strength,
|
||||
this->shared_secret.len, this->shared_secret.ptr) != DRBG_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "generation of shared secret failed");
|
||||
chunk_free(&this->shared_secret);
|
||||
return;
|
||||
}
|
||||
|
||||
/* determine the size of the ciphertext */
|
||||
if (ntru_crypto_ntru_encrypt(this->drbg,
|
||||
this->pub_key.len, this->pub_key.ptr,
|
||||
this->shared_secret.len, this->shared_secret.ptr,
|
||||
&ciphertext_len, NULL) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "error determining ciphertext size");
|
||||
return;
|
||||
}
|
||||
this->ciphertext = chunk_alloc(ciphertext_len);
|
||||
this->computed = TRUE;
|
||||
|
||||
/* encrypt the shared secret */
|
||||
if (ntru_crypto_ntru_encrypt(this->drbg,
|
||||
this->pub_key.len, this->pub_key.ptr,
|
||||
this->shared_secret.len, this->shared_secret.ptr,
|
||||
&ciphertext_len, this->ciphertext.ptr) != NTRU_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
|
||||
chunk_free(&this->ciphertext);
|
||||
return;
|
||||
}
|
||||
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t,
|
||||
private_ntru_ke_t *this)
|
||||
{
|
||||
return this->group;
|
||||
}
|
||||
|
||||
METHOD(diffie_hellman_t, destroy, void,
|
||||
private_ntru_ke_t *this)
|
||||
{
|
||||
if (ntru_crypto_drbg_uninstantiate(this->drbg) != DRBG_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "error uninstantiating DRBG");
|
||||
}
|
||||
chunk_free(&this->pub_key);
|
||||
chunk_free(&this->ciphertext);
|
||||
chunk_clear(&this->priv_key);
|
||||
chunk_clear(&this->shared_secret);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
|
||||
{
|
||||
private_ntru_ke_t *this;
|
||||
char personalization_str[] = "strongSwan NTRU-KE";
|
||||
NTRU_ENCRYPT_PARAM_SET_ID param_set_id;
|
||||
DRBG_HANDLE drbg;
|
||||
u_int32_t strength;
|
||||
|
||||
/**
|
||||
* We are selecting the X9.98 / IEEE 1363.1 parameter sets
|
||||
* which balance speed and bandwidth
|
||||
*/
|
||||
switch (group)
|
||||
{
|
||||
case NTRU_112_BIT:
|
||||
strength = 112;
|
||||
/* param_set_id = NTRU_EES541EP1; */
|
||||
param_set_id = NTRU_EES401EP2;
|
||||
break;
|
||||
case NTRU_128_BIT:
|
||||
strength = 128;
|
||||
/* param_set_id = NTRU_EES613EP1; */
|
||||
param_set_id = NTRU_EES439EP1;
|
||||
break;
|
||||
case NTRU_192_BIT:
|
||||
strength = 192;
|
||||
/* param_set_id = NTRU_EES887EP1; */
|
||||
param_set_id = NTRU_EES593EP1;
|
||||
break;
|
||||
case NTRU_256_BIT:
|
||||
strength = 256;
|
||||
/* param_set_id = NTRU_EES1171EP1; */
|
||||
param_set_id = NTRU_EES743EP1;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ntru_crypto_drbg_instantiate(strength,
|
||||
personalization_str, strlen(personalization_str),
|
||||
(ENTROPY_FN) &ntru_plugin_get_entropy, &drbg) != DRBG_OK)
|
||||
{
|
||||
DBG1(DBG_LIB, "error instantiating DRBG at %u bit security", strength);
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_LIB, "instantiated DRBG at %u bit security", strength);
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.dh = {
|
||||
.get_shared_secret = _get_shared_secret,
|
||||
.set_other_public_value = _set_other_public_value,
|
||||
.get_my_public_value = _get_my_public_value,
|
||||
.get_dh_group = _get_dh_group,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.group = group,
|
||||
.param_set_id = param_set_id,
|
||||
.strength = strength,
|
||||
.drbg = drbg,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ntru_ke ntru_ke
|
||||
* @{ @ingroup ntru_p
|
||||
*/
|
||||
|
||||
#ifndef NTRU_KE_H_
|
||||
#define NTRU_KE_H_
|
||||
|
||||
typedef struct ntru_ke_t ntru_ke_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Implementation of a key exchange algorithm using NTRU encryption
|
||||
*/
|
||||
struct ntru_ke_t {
|
||||
|
||||
/**
|
||||
* Implements diffie_hellman_t interface.
|
||||
*/
|
||||
diffie_hellman_t dh;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new ntru_ke_t object.
|
||||
*
|
||||
* @param group NTRU group number to use
|
||||
* @param g not used
|
||||
* @param p not used
|
||||
* @return ntru_ke_t object, NULL if not supported
|
||||
*/
|
||||
ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p);
|
||||
|
||||
#endif /** NTRU_KE_H_ @}*/
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "ntru_plugin.h"
|
||||
#include "ntru_ke.h"
|
||||
|
||||
#include <library.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_ntru_plugin_t private_ntru_plugin_t;
|
||||
|
||||
rng_t *rng;
|
||||
|
||||
bool ntru_plugin_get_entropy(ENTROPY_CMD cmd, uint8_t *out)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case INIT:
|
||||
return TRUE;
|
||||
case GET_NUM_BYTES_PER_BYTE_OF_ENTROPY:
|
||||
/* Here we return the number of bytes needed from the entropy
|
||||
* source to obtain 8 bits of entropy. Maximum is 8.
|
||||
*/
|
||||
if (!out)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*out = 1; /* this is a perfectly random source */
|
||||
return TRUE;
|
||||
case GET_BYTE_OF_ENTROPY:
|
||||
if (!out)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!rng || !rng->get_bytes(rng, 1, out))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DBG2(DBG_LIB, "read one byte of entropy");
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create/Destroy True Random Generator
|
||||
*/
|
||||
static bool create_random(private_ntru_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
|
||||
if (!rng)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rng->destroy(rng);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* private data of ntru_plugin
|
||||
*/
|
||||
struct private_ntru_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
ntru_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_ntru_plugin_t *this)
|
||||
{
|
||||
return "ntru";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_ntru_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
static plugin_feature_t f_ke[] = {
|
||||
PLUGIN_REGISTER(DH, ntru_ke_create),
|
||||
PLUGIN_PROVIDE(DH, NTRU_112_BIT),
|
||||
PLUGIN_PROVIDE(DH, NTRU_128_BIT),
|
||||
PLUGIN_PROVIDE(DH, NTRU_192_BIT),
|
||||
PLUGIN_PROVIDE(DH, NTRU_256_BIT),
|
||||
};
|
||||
static plugin_feature_t f_rng[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)create_random, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "ntru-rng"),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
};
|
||||
static plugin_feature_t f[countof(f_ke) + countof(f_rng)] = {};
|
||||
|
||||
plugin_features_add(f, f_ke, countof(f_ke), &count);
|
||||
plugin_features_add(f, f_rng, countof(f_rng), &count);
|
||||
|
||||
*features = f;
|
||||
return count;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_ntru_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *ntru_plugin_create()
|
||||
{
|
||||
private_ntru_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ntru_p ntru
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup ntru_plugin ntru_plugin
|
||||
* @{ @ingroup ntru_p
|
||||
*/
|
||||
|
||||
#ifndef NTRU_PLUGIN_H_
|
||||
#define NTRU_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
#include "ntru_crypto/ntru_crypto_drbg.h"
|
||||
|
||||
typedef struct ntru_plugin_t ntru_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing NTRU-base key exchange
|
||||
*/
|
||||
struct ntru_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true random bytes
|
||||
*
|
||||
* @param cmd command to be executed
|
||||
* @param out output variable
|
||||
* @result return code
|
||||
*/
|
||||
bool ntru_plugin_get_entropy(ENTROPY_CMD cmd, uint8_t *out);
|
||||
|
||||
#endif /** NTRU_PLUGIN_H_ @}*/
|
|
@ -79,7 +79,8 @@ CONFIG_OPTS = \
|
|||
--enable-cmd \
|
||||
--enable-libipsec \
|
||||
--enable-kernel-libipsec \
|
||||
--enable-tkm
|
||||
--enable-tkm \
|
||||
--enable-ntru
|
||||
|
||||
export ADA_PROJECT_PATH=/usr/local/ada/lib/gnat
|
||||
|
||||
|
|
Loading…
Reference in New Issue