libstrongswan_ntru_la_SOURCES = \
ntru_plugin.h ntru_plugin.c \
+ ntru_convert.h ntru_convert.c \
ntru_drbg.h ntru_drbg.c \
ntru_ke.h ntru_ke.c \
ntru_mgf1.h ntru_mgf1.c \
ntru_poly.h ntru_poly.c \
ntru_public_key.h ntru_public_key.c \
ntru_private_key.h ntru_private_key.c \
- ntru_trits.h ntru_trits.c \
- ntru_crypto/ntru_crypto.h \
- 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_poly.h \
- ntru_crypto/ntru_crypto_ntru_poly.c
+ ntru_trits.h ntru_trits.c
libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
--- /dev/null
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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. 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 <stdlib.h>
+#include <string.h>
+
+#include "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};
+
+/**
+ * See header.
+ */
+void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits, uint8_t *trits)
+{
+ uint32_t bits24, bits3, shift;
+
+ while (num_trits >= 16)
+ {
+ /* get next three octets */
+ bits24 = ((uint32_t)(*octets++)) << 16;
+ bits24 |= ((uint32_t)(*octets++)) << 8;
+ bits24 |= (uint32_t)(*octets++);
+
+ /* for each 3 bits in the three octets, output 2 trits */
+ bits3 = (bits24 >> 21) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 18) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 15) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 12) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 9) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 6) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = (bits24 >> 3) & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ bits3 = bits24 & 0x7;
+ *trits++ = bits_2_trit1[bits3];
+ *trits++ = bits_2_trit2[bits3];
+
+ num_trits -= 16;
+ }
+ if (num_trits == 0)
+ {
+ return;
+ }
+
+ /* get three octets */
+ bits24 = ((uint32_t)(*octets++)) << 16;
+ bits24 |= ((uint32_t)(*octets++)) << 8;
+ bits24 |= (uint32_t)(*octets++);
+
+ shift = 21;
+ while (num_trits)
+ {
+ /**
+ * for each 3 bits in the three octets, output up to 2 trits
+ * until all trits needed are produced
+ */
+ bits3 = (bits24 >> shift) & 0x7;
+ shift -= 3;
+ *trits++ = bits_2_trit1[bits3];
+ if (--num_trits)
+ {
+ *trits++ = bits_2_trit2[bits3];
+ --num_trits;
+ }
+ }
+}
+
+/**
+ * See header.
+ */
+bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits, uint8_t *octets)
+{
+ bool all_trits_valid = TRUE;
+ uint32_t bits24, bits3, shift;
+
+ while (num_trits >= 16)
+ {
+ /* convert each 2 trits to 3 bits and pack */
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 = (bits3 << 21);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 18);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 15);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 12);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 9);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 6);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << 3);
+
+ bits3 = *trits++ * 3;
+ bits3 += *trits++;
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= bits3;
+
+ num_trits -= 16;
+
+ /* output three octets */
+ *octets++ = (uint8_t)((bits24 >> 16) & 0xff);
+ *octets++ = (uint8_t)((bits24 >> 8) & 0xff);
+ *octets++ = (uint8_t)(bits24 & 0xff);
+ }
+
+ bits24 = 0;
+ shift = 21;
+ while (num_trits)
+ {
+ /* convert each 2 trits to 3 bits and pack */
+ bits3 = *trits++ * 3;
+ if (--num_trits)
+ {
+ bits3 += *trits++;
+ --num_trits;
+ }
+ if (bits3 > 7)
+ {
+ bits3 = 7;
+ all_trits_valid = FALSE;
+ }
+ bits24 |= (bits3 << shift);
+ shift -= 3;
+ }
+
+ /* output three octets */
+ *octets++ = (uint8_t)((bits24 >> 16) & 0xff);
+ *octets++ = (uint8_t)((bits24 >> 8) & 0xff);
+ *octets++ = (uint8_t)(bits24 & 0xff);
+
+ return all_trits_valid;
+}
+
+/**
+ * See header
+ */
+void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs, uint8_t *octets)
+{
+ uint8_t bits2;
+ int shift, i;
+
+ *octets = 0;
+ shift = 6;
+ for (i = 0; i < num_coeffs; i++)
+ {
+ bits2 = (uint8_t)(coeffs[i] & 0x3);
+ *octets |= bits2 << shift;
+ shift -= 2;
+ if (shift < 0)
+ {
+ ++octets;
+ *octets = 0;
+ shift = 6;
+ }
+ }
+}
+
+/**
+ * See header.
+ */
+void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet)
+{
+ int i;
+
+ *octet = 0;
+ for (i = 4; i >= 0; i--)
+ {
+ *octet = (*octet * 3) + trits[i];
+ }
+}
+
+/**
+ * See header.
+ */
+void ntru_octet_2_trits(uint8_t octet, uint8_t *trits)
+{
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ trits[i] = octet % 3;
+ octet = (octet - trits[i]) / 3;
+ }
+}
+
+/**
+ * See header.
+ */
+void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1,
+ uint8_t *out)
+{
+ uint8_t trit = plus1 ? 1 : 2;
+ int i;
+
+ for (i = 0; i < in_len; i++)
+ {
+ out[in[i]] = trit;
+ }
+}
+
+/**
+ * See header.
+ */
+void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits,
+ uint16_t *indices_plus1,
+ uint16_t *indices_minus1)
+{
+ uint8_t trits[5];
+ uint16_t i = 0;
+ int j;
+
+ while (num_trits >= 5)
+ {
+ ntru_octet_2_trits(*in++, trits);
+ num_trits -= 5;
+ for (j = 0; j < 5; j++, i++)
+ {
+ if (trits[j] == 1)
+ {
+ *indices_plus1 = i;
+ ++indices_plus1;
+ }
+ else if (trits[j] == 2)
+ {
+ *indices_minus1 = i;
+ ++indices_minus1;
+ }
+ }
+ }
+ 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;
+ }
+ }
+}
+
+/**
+ * See header.
+ */
+void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1,
+ uint16_t num_minus1, uint16_t num_trits,
+ uint8_t *buf, uint8_t *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);
+ }
+}
+
+/**
+ * See header
+ */
+void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits,
+ uint8_t *out)
+{
+ uint16_t temp;
+ int shift, i;
+
+ /* pack */
+ temp = 0;
+ shift = n_bits - 8;
+ i = 0;
+ while (i < in_len)
+ {
+ /* add bits to temp to fill an octet and output the octet */
+ temp |= in[i] >> shift;
+ *out++ = (uint8_t)(temp & 0xff);
+ 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);
+ }
+}
+
+
+/**
+ * See header.
+ */
+void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits,
+ uint16_t *out)
+{
+ uint16_t temp;
+ uint16_t mask = (1 << n_bits) - 1;
+ int shift, i;
+
+ /* 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;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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. 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_convert ntru_convert
+ * @{ @ingroup ntru_p
+ */
+
+#ifndef NTRU_CONVERT_H_
+#define NTRU_CONVERT_H_
+
+#include <library.h>
+
+/**
+ * Each 3 bits in an array of octets is converted to 2 trits in an array
+ * of trits.
+ *
+ * @param octets pointer to array of octets
+ * @param num_trits number of trits to produce
+ * @param trits address for array of trits
+ */
+void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits,
+ uint8_t *trits);
+
+/**
+ * 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.
+ *
+ * @param trits pointer to array of trits
+ * @param num_trits number of trits to convert
+ * @param octets address for array of octets
+ * @return TRUE if all trits were valid
+ * FALSE if invalid trits were found
+ */
+bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits,
+ uint8_t *octets);
+
+/**
+ * Takes an array of coefficients mod 4 and packs the results into an
+ * octet string.
+ *
+ * @param num_coeffs number of coefficients
+ * @param coeffs pointer to coefficients
+ * @param octets address for octets
+ */
+void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs,
+ uint8_t *octets);
+
+/**
+ * Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
+ *
+ * @param trits pointer to trits
+ * @param octet address for octet
+ */
+void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet);
+
+/**
+ * Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
+ *
+ * @param octet octet to be unpacked
+ * @param trits address for trits
+ */
+void ntru_octet_2_trits(uint8_t octet, uint8_t *trits);
+
+/**
+ *
+ * Converts a list of the nonzero indices of a polynomial into an array of
+ * trits.
+ *
+ * @param in_len no. of indices
+ * @param in pointer to list of indices
+ * @param plus1 if list is +1 coefficients
+ * @param out address of output polynomial
+ */
+void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1,
+ uint8_t *out);
+
+/**
+ * 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.
+ *
+ * @param in pointer to packed-trit octets
+ * @param num_trits no. of packed trits
+ * @param indices_plus1 address for indices of +1 trits
+ * @param indices_minus1 address for indices of -1 trits
+ */
+void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits,
+ uint16_t *indices_plus1,
+ uint16_t *indices_minus1);
+
+/**
+ * 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.
+ *
+ * @param indices pointer to indices
+ * @param num_plus1 no. of indices for +1 trits
+ * @param num_minus1 no. of indices for -1 trits
+ * @param num_trits N, no. of trits in array
+ * @param buf temp buf, N octets
+ * @param out address for packed octet
+ */
+void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1,
+ uint16_t num_minus1, uint16_t num_trits,
+ uint8_t *buf, uint8_t *out);
+
+/**
+ * Packs an array of n-bit elements into an array of
+ * ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
+ *
+ * @param in_len no. of elements to be packed
+ * @param in ptr to elements to be packed
+ * @param n_bits no. of bits in input element
+ * @param out addr for output octets
+ */
+void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits,
+ uint8_t *out);
+
+/**
+ * Unpacks an octet string into an array of ((in_len * 8) / n_bits)
+ * n-bit elements, 8 < n < 16. Any extra bits are discarded.
+ *
+ * @param in_len no. of octets to be unpacked
+ * @param in ptr to octets to be unpacked
+ * @param n_bits no. of bits in output element
+ * @param out addr for output elements
+ */
+void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits,
+ uint16_t *out);
+
+#endif /** NTRU_CONVERT_H_ @}*/
+++ /dev/null
-/******************************************************************************
- * 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 <library.h>
-
-#include "ntru_param_set.h"
-#include "ntru_drbg.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 */
-
-/* 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_DRBG_FAIL 11
-#define NTRU_MGF1_FAIL 12
-
-/* 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 NTRU_DRBG_FAIL if the DRBG handle is invalid.
- * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
- * Returns 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_BAD_PUBLIC_KEY if the public-key blob is invalid
- * (unknown format, corrupt, bad length).
- * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
- * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
- */
-
-NTRUCALL
-ntru_crypto_ntru_encrypt(
- ntru_drbg_t *drbg , /* 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 */
-
-#endif /* NTRU_CRYPTO_H */
+++ /dev/null
-/******************************************************************************
- * 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;
- }
-}
-
-
+++ /dev/null
-/******************************************************************************
- * 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 */
-
-
+++ /dev/null
-/******************************************************************************
- * NTRU Cryptography Reference Source Code
- * Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
- *
- * ntru_crypto_ntru_encrypt.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.c
- *
- * Contents: Routines implementing NTRUEncrypt encryption and decryption and
- * key generation.
- *
- *****************************************************************************/
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "ntru_crypto.h"
-#include "ntru_crypto_ntru_encrypt_key.h"
-#include "ntru_crypto_ntru_convert.h"
-#include "ntru_crypto_ntru_poly.h"
-
-#include "ntru_param_set.h"
-#include "ntru_trits.h"
-#include "ntru_poly.h"
-
-/* 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 NTRU_DRBG_FAIL if the DRBG handle is invalid.
- * Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
- * Returns 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_BAD_PUBLIC_KEY if the public-key blob is invalid
- * (unknown format, corrupt, bad length).
- * Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
- * Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
- */
-
-uint32_t
-ntru_crypto_ntru_encrypt(
- ntru_drbg_t *drbg, /* in - handle of 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_param_set_t *params = NULL;
- uint8_t const *pubkey_packed = NULL;
- uint8_t pubkey_pack_type = 0x00;
- uint16_t packed_ct_len;
- size_t scratch_buf_len;
- uint32_t dr;
- uint32_t dr1 = 0;
- uint32_t dr2 = 0;
- uint32_t dr3 = 0;
- uint16_t ring_mult_tmp_len;
- int16_t m1;
- uint16_t *scratch_buf = NULL;
- uint16_t *ringel_buf = NULL;
- uint8_t *b_buf = NULL;
- uint8_t *tmp_buf = NULL;
- bool msg_rep_good = FALSE;
- hash_algorithm_t hash_algid;
- uint16_t mprime_len = 0;
- uint16_t mod_q_mask;
- uint32_t result = NTRU_OK;
- ntru_trits_t *mask;
- uint8_t *mask_trits;
- chunk_t seed;
- ntru_poly_t *r_poly;
-
- /* check for bad parameters */
-
- if (!pubkey_blob || !pt || !ct_len)
- {
- return NTRU_BAD_PARAMETER;
- }
- if ((pubkey_blob_len == 0) || (pt_len == 0))
- {
- return NTRU_BAD_LENGTH;
- }
-
- /* get a pointer to the parameter-set parameters, the packing type for
- * the public key, and a pointer to the packed public key
- */
-
- if (!ntru_crypto_ntru_encrypt_key_parse(TRUE /* pubkey */, pubkey_blob_len,
- pubkey_blob, &pubkey_pack_type,
- NULL, ¶ms, &pubkey_packed,
- NULL))
- {
- return NTRU_BAD_PUBLIC_KEY;
- }
-
- /* return the ciphertext size if requested */
-
- packed_ct_len = (params->N * params->q_bits + 7) >> 3;
- if (!ct)
- {
- *ct_len = packed_ct_len;
- return NTRU_OK;
- }
-
- /* check the ciphertext buffer size */
-
- if (*ct_len < packed_ct_len)
- {
- return NTRU_BUFFER_TOO_SMALL;
- }
-
- /* check the plaintext length */
-
- if (pt_len > params->m_len_max)
- {
- return NTRU_BAD_LENGTH;
- }
-
- /* allocate memory for all operations */
-
- if (params->is_product_form)
- {
- ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */
- dr1 = params->dF_r & 0xff;
- dr2 = (params->dF_r >> 8) & 0xff;
- dr3 = (params->dF_r >> 16) & 0xff;
- dr = dr1 + dr2 + dr3;
- }
- else
- {
- ring_mult_tmp_len = params->N; /* N 16-bit word buffer */
- dr = params->dF_r;
- }
- scratch_buf_len = (ring_mult_tmp_len << 1) +
- /* X-byte temp buf for ring mult and
- other intermediate results */
- (params->N << 1) + /* 2N-byte buffer for ring elements
- and overflow from temp buffer */
- (dr << 2) + /* buffer for r indices */
- params->sec_strength_len;
- /* buffer for b */
- scratch_buf = malloc(scratch_buf_len);
- if (!scratch_buf)
- {
- return NTRU_OUT_OF_MEMORY;
- }
- ringel_buf = scratch_buf + ring_mult_tmp_len;
- b_buf = (uint8_t *)(ringel_buf + params->N);
- tmp_buf = (uint8_t *)scratch_buf;
-
- /* set hash algorithm based on security strength */
- hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256;
-
- /* set constants */
- mod_q_mask = params->q - 1;
-
- /* loop until a message representative with proper weight is achieved */
-
- do {
- uint8_t *ptr = tmp_buf;
-
- /* get b */
- if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE,
- params->sec_strength_len, b_buf))
- {
- result = NTRU_OK;
- }
- else
- {
- result = NTRU_FAIL;
- }
-
- if (result == NTRU_OK)
- {
-
- /* form sData (OID || m || b || hTrunc) */
- memcpy(ptr, params->oid, 3);
- ptr += 3;
- memcpy(ptr, pt, pt_len);
- ptr += pt_len;
- memcpy(ptr, b_buf, params->sec_strength_len);
- ptr += params->sec_strength_len;
- memcpy(ptr, pubkey_packed, params->sec_strength_len);
- ptr += params->sec_strength_len;
-
- DBG2(DBG_LIB, "generate polynomial r");
-
- seed = chunk_create(tmp_buf, ptr - tmp_buf);
- r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
- params->N, params->q,
- params->dF_r, params->dF_r,
- params->is_product_form);
- if (!r_poly)
- {
- result = NTRU_MGF1_FAIL;
- }
- }
-
- if (result == NTRU_OK)
- {
- uint16_t pubkey_packed_len;
-
- /* unpack the public key */
- assert(pubkey_pack_type == NTRU_KEY_PACKED_COEFFICIENTS);
- pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
- ntru_octets_2_elements(pubkey_packed_len, pubkey_packed,
- params->q_bits, ringel_buf);
-
- /* form R = h * r */
- r_poly->ring_mult(r_poly, ringel_buf, ringel_buf);
- r_poly->destroy(r_poly);
-
- /* form R mod 4 */
- ntru_coeffs_mod4_2_octets(params->N, ringel_buf, tmp_buf);
-
- /* form mask */
- seed = chunk_create(tmp_buf, (params->N + 3)/4);
- mask = ntru_trits_create(params->N, hash_algid, seed);
- if (!mask)
- {
- result = NTRU_MGF1_FAIL;
- }
- }
-
- if (result == NTRU_OK)
- {
- uint8_t *Mtrin_buf = tmp_buf + params->N;
- uint8_t *M_buf = Mtrin_buf + params->N -
- (params->sec_strength_len + params->m_len_len +
- params->m_len_max + 2);
- uint16_t i;
-
- /* form the padded message M */
- ptr = M_buf;
- memcpy(ptr, b_buf, params->sec_strength_len);
- ptr += params->sec_strength_len;
- if (params->m_len_len == 2)
- *ptr++ = (uint8_t)((pt_len >> 8) & 0xff);
- *ptr++ = (uint8_t)(pt_len & 0xff);
- memcpy(ptr, pt, pt_len);
- ptr += pt_len;
-
- /* add an extra zero byte in case without it the bit string
- * is not a multiple of 3 bits and therefore might not be
- * able to produce enough trits
- */
-
- memset(ptr, 0, params->m_len_max - pt_len + 2);
-
- /* convert M to trits (Mbin to Mtrin) */
- mprime_len = params->N;
- if (params->is_product_form)
- {
- --mprime_len;
- }
-
- ntru_bits_2_trits(M_buf, mprime_len, Mtrin_buf);
- mask_trits = mask->get_trits(mask);
-
- /* form the msg representative m' by adding Mtrin to mask, mod p */
- if (params->is_product_form)
- {
- m1 = 0;
- for (i = 0; i < mprime_len; i++)
- {
- tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
- if (tmp_buf[i] >= 3)
- {
- tmp_buf[i] -= 3;
- }
- if (tmp_buf[i] == 1)
- {
- ++m1;
- }
- else if (tmp_buf[i] == 2)
- {
- --m1;
- }
- }
- }
- else
- {
- for (i = 0; i < mprime_len; i++)
- {
- tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
- if (tmp_buf[i] >= 3)
- {
- tmp_buf[i] -= 3;
- }
- }
- }
- mask->destroy(mask);
-
- /* check that message representative meets minimum weight
- * requirements
- */
-
- if (params->is_product_form)
- msg_rep_good = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) :
- (bool)( m1 <= params->min_msg_rep_wt);
- else
- msg_rep_good = ntru_poly_check_min_weight(mprime_len, tmp_buf,
- params->min_msg_rep_wt);
- }
- } while ((result == NTRU_OK) && !msg_rep_good);
-
- if (result == NTRU_OK)
- {
- uint16_t i;
-
- /* form ciphertext e by adding m' to R mod q */
-
- for (i = 0; i < mprime_len; i++) {
- if (tmp_buf[i] == 1)
- ringel_buf[i] = (ringel_buf[i] + 1) & mod_q_mask;
- else if (tmp_buf[i] == 2)
- ringel_buf[i] = (ringel_buf[i] - 1) & mod_q_mask;
- }
- if (params->is_product_form)
- ringel_buf[i] = (ringel_buf[i] - m1) & mod_q_mask;
-
- /* pack ciphertext */
- ntru_elements_2_octets(params->N, ringel_buf, params->q_bits, ct);
- *ct_len = packed_ct_len;
- }
-
- /* cleanup */
- memset(scratch_buf, 0, scratch_buf_len);
- free(scratch_buf);
-
- return result;
-}
+++ /dev/null
-/******************************************************************************
- * 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_param_set_t **params, /* out - addr for ptr to
- parameter set */
- uint8_t const **pubkey, /* out - addr for ptr to
- packed pubkey */
- uint8_t const **privkey) /* out - addr for ptr to
- packed privkey */
-{
- uint8_t tag;
-
- /* parse key blob based on tag */
- tag = key_blob[0];
- switch (tag) {
- case NTRU_PUBKEY_TAG:
- if (!pubkey_parse)
- return FALSE;
- break;
- case NTRU_PRIVKEY_DEFAULT_TAG:
- case NTRU_PRIVKEY_TRITS_TAG:
- case NTRU_PRIVKEY_INDICES_TAG:
- assert(privkey_pack_type);
- assert(privkey);
- if (pubkey_parse)
- return FALSE;
- break;
- default:
- return FALSE;
- }
-
- switch (tag) {
- case NTRU_PUBKEY_TAG:
- case NTRU_PRIVKEY_DEFAULT_TAG:
- case NTRU_PRIVKEY_TRITS_TAG:
- case NTRU_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_param_set_t *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 */
- p = ntru_param_set_get_by_oid(key_blob + 2);
- if (!p)
- {
- 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_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_PRIVKEY_DEFAULT_TAG) {
- if (p->is_product_form ||
- (privkey_packed_indices_len <=
- privkey_packed_trits_len))
- tag = NTRU_PRIVKEY_INDICES_TAG;
- else
- tag = NTRU_PRIVKEY_TRITS_TAG;
- }
-
- if (tag == NTRU_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_PRIVKEY_TRITS_TAG) ?
- NTRU_KEY_PACKED_TRITS :
- NTRU_KEY_PACKED_INDICES;
- }
-
- /* return parameter set pointer */
-
- *pubkey_pack_type = NTRU_KEY_PACKED_COEFFICIENTS;
- *params = p;
- }
- default:
- break; /* can't get here */
- }
- return TRUE;
-}
+++ /dev/null
-/******************************************************************************
- * 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_param_set.h"
-
-/* 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_param_set_t **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 */
-
-#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H */
+++ /dev/null
-/******************************************************************************
- * 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.
- *
- *****************************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-#include "ntru_crypto_ntru_poly.h"
-
-/* 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;
-}
-
+++ /dev/null
-/******************************************************************************
- * 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 <crypto/hashers/hasher.h>
-
-
-/* function declarations */
-
-/* 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 */
-
-#endif /* NTRU_CRYPTO_NTRU_POLY_H */
*/
chunk_t value;
+ /**
+ * reference count
+ */
+ refcount_t ref;
};
/**
return TRUE;
}
+METHOD(ntru_drbg_t, get_ref, ntru_drbg_t*,
+ private_ntru_drbg_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
METHOD(ntru_drbg_t, destroy, void,
private_ntru_drbg_t *this)
{
- this->hmac->destroy(this->hmac);
- chunk_clear(&this->key);
- chunk_clear(&this->value);
- free(this);
+ if (ref_put(&this->ref))
+ {
+ this->hmac->destroy(this->hmac);
+ chunk_clear(&this->key);
+ chunk_clear(&this->value);
+ free(this);
+ }
}
/*
.get_strength = _get_strength,
.reseed = _reseed,
.generate = _generate,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.strength = strength,
.value = chunk_alloc(hmac->get_block_size(hmac)),
.max_requests = max_requests,
.reseed_counter = 1,
+ .ref = 1,
);
memset(this->key.ptr, 0x00, this->key.len);
bool (*generate)(ntru_drbg_t *this, u_int32_t strength, u_int32_t len,
u_int8_t *out);
+ /**
+ * Get a reference on an ntru_drbg_t object increasing the count by one
+ *
+ * @return reference to the ntru_drbg_t object
+ */
+ ntru_drbg_t* (*get_ref)(ntru_drbg_t *this);
+
/**
* Uninstantiate and destroy the DRBG object
*/
#include "ntru_private_key.h"
#include "ntru_public_key.h"
-#include "ntru_crypto/ntru_crypto.h"
-
#include <crypto/diffie_hellman.h>
#include <utils/debug.h>
*/
ntru_private_key_t *privkey;
- /**
- * NTRU Public Key Encoding
- */
- chunk_t pubkey_enc;
-
/**
* NTRU encrypted shared secret
*/
return;
}
this->pubkey = this->privkey->get_public_key(this->privkey);
- this->pubkey_enc = this->pubkey->get_encoding(this->pubkey);
- this->pubkey_enc = chunk_clone(this->pubkey_enc);
- DBG3(DBG_LIB, "NTRU public key: %B", &this->pubkey_enc);
}
- *value = chunk_clone(this->pubkey_enc);
+ *value = chunk_clone(this->pubkey->get_encoding(this->pubkey));
+ DBG3(DBG_LIB, "NTRU public key: %B", value);
}
}
METHOD(diffie_hellman_t, set_other_public_value, void,
private_ntru_ke_t *this, chunk_t value)
{
- u_int16_t ciphertext_len;
-
if (this->privkey)
{
/* initiator decrypting shared secret */
}
else
{
+ ntru_public_key_t *pubkey;
+
/* responder generating and encrypting the shared secret */
this->responder = TRUE;
- /* check the NTRU public key format */
- if (value.len < 5 ||
- value.ptr[0] != NTRU_PUBKEY_TAG ||
- value.ptr[1] != NTRU_OID_LEN)
+ DBG3(DBG_LIB, "NTRU public key: %B", &value);
+ pubkey = ntru_public_key_create_from_data(this->drbg, value);
+ if (!pubkey)
{
- DBG1(DBG_LIB, "received NTRU public key with invalid header");
return;
}
- if (!memeq(value.ptr + 2, this->param_set->oid, NTRU_OID_LEN))
+ if (pubkey->get_id(pubkey) != this->param_set->id)
{
- DBG1(DBG_LIB, "received NTRU public key with wrong OID");
+ DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
+ pubkey->destroy(pubkey);
return;
}
- this->pubkey_enc = chunk_clone(value);
+ this->pubkey = pubkey;
/* shared secret size is chosen as twice the cryptographical strength */
this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
}
this->computed = TRUE;
- /* determine the size of the ciphertext */
- if (ntru_crypto_ntru_encrypt(this->drbg,
- this->pubkey_enc.len, this->pubkey_enc.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);
-
/* encrypt the shared secret */
- if (ntru_crypto_ntru_encrypt(this->drbg,
- this->pubkey_enc.len, this->pubkey_enc.ptr,
- this->shared_secret.len, this->shared_secret.ptr,
- &ciphertext_len, this->ciphertext.ptr) != NTRU_OK)
+ if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
{
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
- chunk_free(&this->ciphertext);
return;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
DESTROY_IF(this->pubkey);
this->drbg->destroy(this->drbg);
this->entropy->destroy(this->entropy);
- chunk_free(&this->pubkey_enc);
chunk_free(&this->ciphertext);
chunk_clear(&this->shared_secret);
free(this);
ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid);
#endif /** NTRU_PARAM_SET_H_ @}*/
-
#include "ntru_private_key.h"
#include "ntru_trits.h"
#include "ntru_poly.h"
-
-#include "ntru_crypto/ntru_crypto_ntru_convert.h"
+#include "ntru_convert.h"
#include <utils/debug.h>
#include <utils/test.h>
*/
chunk_t encoding;
+ /**
+ * Deterministic Random Bit Generator
+ */
+ ntru_drbg_t *drbg;
+
};
+METHOD(ntru_private_key_t, get_id, ntru_param_set_id_t,
+ private_ntru_private_key_t *this)
+{
+ return this->params->id;
+}
+
METHOD(ntru_private_key_t, get_public_key, ntru_public_key_t*,
private_ntru_private_key_t *this)
{
- return ntru_public_key_create(this->params, this->pubkey);
+ return ntru_public_key_create(this->drbg, this->params, this->pubkey);
}
/**
* @param min_wt minimum weight
* @return TRUE if minimum weight met or exceeded
*/
-static bool check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
+bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
{
uint16_t wt[3];
+ bool success;
int i;
wt[0] = wt[1] = wt[2] = 0;
{
++wt[t[i]];
}
+ success = (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt);
+
+ DBG2(DBG_LIB, "minimum weight = %u, so -1: %u, 0: %u, +1: %u is %sok",
+ min_wt, wt[2], wt[0], wt[1], success ? "" : "not ");
- return (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt);
+ return success;
}
METHOD(ntru_private_key_t, decrypt, bool,
chunk_t seed = chunk_empty;
ntru_trits_t *mask;
ntru_poly_t *r_poly;
- bool success = TRUE;
+ bool msg_rep_good, success = TRUE;
int i;
*plaintext = chunk_empty;
*/
if (this->params->is_product_form)
{
- success = (abs(m1) <= this->params->min_msg_rep_wt);
+ msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt);
}
else
{
- success = check_min_weight(cmprime_len, Mtrin,
- this->params->min_msg_rep_wt);
+ msg_rep_good = ntru_check_min_weight(cmprime_len, Mtrin,
+ this->params->min_msg_rep_wt);
}
- if (!success)
+ if (!msg_rep_good)
{
DBG1(DBG_LIB, "decryption failed due to unsufficient minimum weight");
+ success = FALSE;
}
/* form cR = e - cm' mod q */
if (t[i] != t2[i])
{
DBG1(DBG_LIB, "cR' does not equal cR'");
+ chunk_clear(plaintext);
success = FALSE;
+ break;
}
}
memwipe(t, t_len);
private_ntru_private_key_t *this)
{
DESTROY_IF(this->privkey);
+ this->drbg->destroy(this->drbg);
chunk_clear(&this->encoding);
free(this->pubkey);
free(this);
/*
* Described in header.
*/
-ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params)
+ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
+ ntru_param_set_t *params)
{
private_ntru_private_key_t *this;
size_t t_len;
INIT(this,
.public = {
+ .get_id = _get_id,
.get_public_key = _get_public_key,
.get_encoding = _get_encoding,
.decrypt = _decrypt,
},
.params = params,
.pubkey = malloc(params->N * sizeof(uint16_t)),
+ .drbg = drbg->get_ref(drbg),
);
/* set hash algorithm and seed length based on security strength */
return NULL;
}
+/*
+ * Described in header.
+ */
+ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg,
+ chunk_t data)
+{
+ private_ntru_private_key_t *this;
+ size_t header_len, pubkey_packed_len, privkey_packed_len;
+ size_t privkey_packed_trits_len, privkey_packed_indices_len;
+ uint8_t *privkey_packed, tag;
+ uint16_t *indices, dF;
+ ntru_param_set_t *params;
+
+ header_len = 2 + NTRU_OID_LEN;
+
+ /* check the NTRU public key header format */
+ if (data.len < header_len ||
+ !(data.ptr[0] == NTRU_PRIVKEY_DEFAULT_TAG ||
+ data.ptr[0] == NTRU_PRIVKEY_TRITS_TAG ||
+ data.ptr[0] == NTRU_PRIVKEY_INDICES_TAG) ||
+ data.ptr[1] != NTRU_OID_LEN)
+ {
+ DBG1(DBG_LIB, "loaded NTRU private key with invalid header");
+ return NULL;
+ }
+ tag = data.ptr[0];
+ params = ntru_param_set_get_by_oid(data.ptr + 2);
+
+ if (!params)
+ {
+ DBG1(DBG_LIB, "loaded NTRU private key with unknown OID");
+ return NULL;
+ }
+
+ pubkey_packed_len = (params->N * params->q_bits + 7) / 8;
+ privkey_packed_trits_len = (params->N + 4) / 5;
+
+ /* check packing type for product-form private keys */
+ if (params->is_product_form && tag == NTRU_PRIVKEY_TRITS_TAG)
+ {
+ DBG1(DBG_LIB, "a product-form NTRU private key cannot be trits-encoded");
+ return NULL;
+ }
+
+ /* set packed-key length for packed indices */
+ 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 = (2 * dF * params->N_bits + 7) / 8;
+
+ /* set private-key packing type if defaulted */
+ if (tag == NTRU_PRIVKEY_DEFAULT_TAG)
+ {
+ if (params->is_product_form ||
+ privkey_packed_indices_len <= privkey_packed_trits_len)
+ {
+ tag = NTRU_PRIVKEY_INDICES_TAG;
+ }
+ else
+ {
+ tag = NTRU_PRIVKEY_TRITS_TAG;
+ }
+ }
+ privkey_packed_len = (tag == NTRU_PRIVKEY_TRITS_TAG) ?
+ privkey_packed_trits_len : privkey_packed_indices_len;
+
+ if (data.len < header_len + pubkey_packed_len + privkey_packed_len)
+ {
+ DBG1(DBG_LIB, "loaded NTRU private key with wrong packed key size");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_id = _get_id,
+ .get_public_key = _get_public_key,
+ .get_encoding = _get_encoding,
+ .decrypt = _decrypt,
+ .destroy = _destroy,
+ },
+ .params = params,
+ .pubkey = malloc(params->N * sizeof(uint16_t)),
+ .encoding = chunk_clone(data),
+ .drbg = drbg->get_ref(drbg),
+ );
+
+ /* unpack the encoded public key */
+ ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len,
+ params->q_bits, this->pubkey);
+
+ /* allocate temporary memory for indices */
+ indices = malloc(2 * dF * sizeof(uint16_t));
+
+ /* unpack the private key */
+ privkey_packed = data.ptr + header_len + pubkey_packed_len;
+ if (tag == NTRU_PRIVKEY_TRITS_TAG)
+ {
+ ntru_packed_trits_2_indices(privkey_packed, params->N,
+ indices, indices + dF);
+ }
+ else
+ {
+ ntru_octets_2_elements(privkey_packed_indices_len, privkey_packed,
+ params->N_bits, indices);
+ }
+ this->privkey = ntru_poly_create_from_data(indices, params->N, params->q,
+ params->dF_r, params->dF_r,
+ params->is_product_form);
+
+ /* cleanup */
+ memwipe(indices, 2 * dF * sizeof(uint16_t));
+ free(indices);
+
+ return &this->public;
+}
+
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create);
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data);
*/
struct ntru_private_key_t {
+ /**
+ * Returns NTRU parameter set ID of the private key
+ *
+ * @return NTRU parameter set ID
+ */
+ ntru_param_set_id_t (*get_id)(ntru_private_key_t *this);
/**
* Returns the NTRU encryption public key as an encoded binary blob
*/
ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params);
+/**
+ * Creates an NTRU encryption private key from encoding
+ *
+ * @param drbg Deterministic random bit generator
+ * @param data Encoded NTRU private key
+ */
+ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg,
+ chunk_t data);
#endif /** NTRU_PRIVATE_KEY_H_ @}*/
*/
#include "ntru_public_key.h"
-
-#include "ntru_crypto/ntru_crypto_ntru_convert.h"
+#include "ntru_trits.h"
+#include "ntru_poly.h"
+#include "ntru_convert.h"
#include <utils/debug.h>
+#include <utils/test.h>
typedef struct private_ntru_public_key_t private_ntru_public_key_t;
*/
chunk_t encoding;
+ /**
+ * Deterministic Random Bit Generator
+ */
+ ntru_drbg_t *drbg;
+
};
+METHOD(ntru_public_key_t, get_id, ntru_param_set_id_t,
+ private_ntru_public_key_t *this)
+{
+ return this->params->id;
+}
+
+/**
+ * Generate NTRU encryption public key encoding
+ */
+static void generate_encoding(private_ntru_public_key_t *this)
+{
+ size_t pubkey_len;
+ u_char *enc;
+
+ /* compute public key length encoded as packed coefficients */
+ pubkey_len = (this->params->N * this->params->q_bits + 7) / 8;
+
+ /* allocate memory for public key encoding */
+ this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len);
+ enc = this->encoding.ptr;
+
+ /* format header and packed public key */
+ *enc++ = NTRU_PUBKEY_TAG;
+ *enc++ = NTRU_OID_LEN;
+ memcpy(enc, this->params->oid, NTRU_OID_LEN);
+ enc += NTRU_OID_LEN;
+ ntru_elements_2_octets(this->params->N, this->pubkey,
+ this->params->q_bits, enc);
+}
+
METHOD(ntru_public_key_t, get_encoding, chunk_t,
private_ntru_public_key_t *this)
{
- if (!this->encoding.len)
- {
- size_t pubkey_len;
- u_char *enc;
-
- /* compute public key length encoded as packed coefficients */
- pubkey_len = (this->params->N * this->params->q_bits + 7) / 8;
-
- /* allocate memory for public key encoding */
- this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len);
- enc = this->encoding.ptr;
-
- /* format header and packed public key */
- *enc++ = NTRU_PUBKEY_TAG;
- *enc++ = NTRU_OID_LEN;
- memcpy(enc, this->params->oid, NTRU_OID_LEN);
- enc += NTRU_OID_LEN;
- ntru_elements_2_octets(this->params->N, this->pubkey,
- this->params->q_bits, enc);
- }
return this->encoding;
}
+#define MAX_SEC_STRENGTH_LEN 32 /* bytes */
+
+/**
+ * Shared with ntru_private_key.c
+ */
+extern bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt);
+
+METHOD(ntru_public_key_t, encrypt, bool,
+ private_ntru_public_key_t *this, chunk_t plaintext, chunk_t *ciphertext)
+{
+ hash_algorithm_t hash_algid;
+ size_t t_len, seed1_len, seed2_len;
+ uint16_t *t1, *t = NULL;
+ uint8_t b[MAX_SEC_STRENGTH_LEN];
+ uint8_t *t2, *Mtrin, *M, *mask_trits, *ptr;
+ uint16_t mod_q_mask, mprime_len = 0;
+ int16_t m1;
+ chunk_t seed = chunk_empty;
+ ntru_trits_t *mask;
+ ntru_poly_t *r_poly;
+ bool msg_rep_good, success = FALSE;
+ int i;
+
+ *ciphertext = chunk_empty;
+
+ if (plaintext.len > this->params->m_len_max)
+ {
+ DBG1(DBG_LIB, "plaintext exceeds maximum size");
+ return FALSE;
+ }
+
+ if (this->params->sec_strength_len > MAX_SEC_STRENGTH_LEN)
+ {
+ DBG1(DBG_LIB, "required security strength exceeds %d bits",
+ MAX_SEC_STRENGTH_LEN * BITS_PER_BYTE);
+ return FALSE;
+ }
+
+ /* allocate temporary array t */
+ t_len = (sizeof(uint16_t) + 3*sizeof(uint8_t)) * this->params->N;
+ t = malloc(t_len);
+ t1 = t;
+ t2 = (uint8_t *)(t1 + this->params->N);
+ Mtrin = t2 + this->params->N;
+ M = Mtrin + this->params->N;
+
+ /* set hash algorithm based on security strength */
+ hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 :
+ HASH_SHA256;
+ /* set constants */
+ mod_q_mask = this->params->q - 1;
+
+ /* allocate memory for the larger of the two seeds */
+ seed1_len = (this->params->N + 3)/4;
+ seed2_len = 3 + 2*this->params->sec_strength_len + plaintext.len;
+ seed = chunk_alloc(max(seed1_len, seed2_len));
+
+ /* loop until a message representative with proper weight is achieved */
+ do
+ {
+ if (!this->drbg->generate(this->drbg,
+ this->params->sec_strength_len * BITS_PER_BYTE,
+ this->params->sec_strength_len, b))
+ {
+ goto err;
+ }
+
+ /* form sData (OID || m || b || hTrunc) */
+ ptr = seed.ptr;
+ memcpy(ptr, this->params->oid, NTRU_OID_LEN);
+ ptr += NTRU_OID_LEN;
+ memcpy(ptr, plaintext.ptr, plaintext.len);
+ ptr += plaintext.len;
+ memcpy(ptr, b, this->params->sec_strength_len);
+ ptr += this->params->sec_strength_len;
+ memcpy(ptr, this->encoding.ptr + 2 + NTRU_OID_LEN,
+ this->params->sec_strength_len);
+ ptr += this->params->sec_strength_len;
+ seed.len = seed2_len;
+
+ DBG2(DBG_LIB, "generate polynomial r");
+ r_poly = ntru_poly_create_from_seed(hash_algid, seed, this->params->c_bits,
+ this->params->N, this->params->q,
+ this->params->dF_r, this->params->dF_r,
+ this->params->is_product_form);
+ if (!r_poly)
+ {
+ goto err;
+ }
+
+ /* form R = h * r */
+ r_poly->ring_mult(r_poly, this->pubkey, t1);
+ r_poly->destroy(r_poly);
+
+ /* form R mod 4 */
+ ntru_coeffs_mod4_2_octets(this->params->N, t1, seed.ptr);
+ seed.len = seed1_len;
+
+ /* form mask */
+ mask = ntru_trits_create(this->params->N, hash_algid, seed);
+ if (!mask)
+ {
+ DBG1(DBG_LIB, "mask creation failed");
+ goto err;
+ }
+
+ /* form the padded message M */
+ ptr = M;
+ memcpy(ptr, b, this->params->sec_strength_len);
+ ptr += this->params->sec_strength_len;
+ if (this->params->m_len_len == 2)
+ {
+ *ptr++ = (uint8_t)((plaintext.len >> 8) & 0xff);
+ }
+ *ptr++ = (uint8_t)(plaintext.len & 0xff);
+ memcpy(ptr, plaintext.ptr, plaintext.len);
+ ptr += plaintext.len;
+
+ /* add an extra zero byte in case without it the bit string
+ * is not a multiple of 3 bits and therefore might not be
+ * able to produce enough trits
+ */
+ memset(ptr, 0, this->params->m_len_max - plaintext.len + 2);
+
+ /* convert M to trits (Mbin to Mtrin) */
+ mprime_len = this->params->N;
+ if (this->params->is_product_form)
+ {
+ --mprime_len;
+ }
+ ntru_bits_2_trits(M, mprime_len, Mtrin);
+ mask_trits = mask->get_trits(mask);
+
+
+ /* form the msg representative m' by adding Mtrin to mask, mod p */
+ if (this->params->is_product_form)
+ {
+ m1 = 0;
+ for (i = 0; i < mprime_len; i++)
+ {
+ t2[i] = mask_trits[i] + Mtrin[i];
+ if (t2[i] >= 3)
+ {
+ t2[i] -= 3;
+ }
+ if (t2[i] == 1)
+ {
+ ++m1;
+ }
+ else if (t2[i] == 2)
+ {
+ --m1;
+ }
+ }
+ }
+ else
+ {
+ for (i = 0; i < mprime_len; i++)
+ {
+ t2[i] = mask_trits[i] + Mtrin[i];
+ if (t2[i] >= 3)
+ {
+ t2[i] -= 3;
+ }
+ }
+ }
+ mask->destroy(mask);
+
+ /* check that message representative meets minimum weight
+ * requirements
+ */
+ if (this->params->is_product_form)
+ {
+ msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt);
+ }
+ else
+ {
+ msg_rep_good = ntru_check_min_weight(mprime_len, t2,
+ this->params->min_msg_rep_wt);
+ }
+ }
+ while (!msg_rep_good);
+
+ /* form ciphertext e by adding m' to R mod q */
+ for (i = 0; i < mprime_len; i++)
+ {
+ if (t2[i] == 1)
+ {
+ t1[i] = (t1[i] + 1) & mod_q_mask;
+ }
+ else if (t2[i] == 2)
+ {
+ t1[i] = (t1[i] - 1) & mod_q_mask;
+ }
+ }
+ if (this->params->is_product_form)
+ {
+ t1[i] = (t1[i] - m1) & mod_q_mask;
+ }
+
+ /* pack ciphertext */
+ *ciphertext = chunk_alloc((this->params->N * this->params->q_bits + 7) / 8);
+ ntru_elements_2_octets(this->params->N, t1, this->params->q_bits,
+ ciphertext->ptr);
+
+ memwipe(t, t_len);
+ success = TRUE;
+
+err:
+ /* cleanup */
+ chunk_clear(&seed);
+ free(t);
+
+ return success;
+}
METHOD(ntru_public_key_t, destroy, void,
private_ntru_public_key_t *this)
{
+ this->drbg->destroy(this->drbg);
chunk_clear(&this->encoding);
free(this->pubkey);
free(this);
/*
* Described in header.
*/
-ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
+ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg,
+ ntru_param_set_t *params,
uint16_t *pubkey)
{
private_ntru_public_key_t *this;
INIT(this,
.public = {
+ .get_id = _get_id,
.get_encoding = _get_encoding,
+ .encrypt = _encrypt,
.destroy = _destroy,
},
.params = params,
.pubkey = malloc(params->N * sizeof(uint16_t)),
+ .drbg = drbg->get_ref(drbg),
);
for (i = 0; i < params->N; i++)
this->pubkey[i] = pubkey[i];
}
+ /* generate public key encoding */
+ generate_encoding(this);
+
return &this->public;
}
+
+/*
+ * Described in header.
+ */
+ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg,
+ chunk_t data)
+{
+ private_ntru_public_key_t *this;
+ size_t header_len, pubkey_packed_len;
+ ntru_param_set_t *params;
+
+ header_len = 2 + NTRU_OID_LEN;
+
+ /* check the NTRU public key header format */
+ if (data.len < header_len ||
+ data.ptr[0] != NTRU_PUBKEY_TAG ||
+ data.ptr[1] != NTRU_OID_LEN)
+ {
+ DBG1(DBG_LIB, "received NTRU public key with invalid header");
+ return NULL;
+ }
+ params = ntru_param_set_get_by_oid(data.ptr + 2);
+
+ if (!params)
+ {
+ DBG1(DBG_LIB, "received NTRU public key with unknown OID");
+ return NULL;
+ }
+
+ pubkey_packed_len = (params->N * params->q_bits + 7) / 8;
+
+ if (data.len < header_len + pubkey_packed_len)
+ {
+ DBG1(DBG_LIB, "received NTRU public key with wrong packed key size");
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_id = _get_id,
+ .get_encoding = _get_encoding,
+ .encrypt = _encrypt,
+ .destroy = _destroy,
+ },
+ .params = params,
+ .pubkey = malloc(params->N * sizeof(uint16_t)),
+ .encoding = chunk_clone(data),
+ .drbg = drbg->get_ref(drbg),
+ );
+
+ /* unpack the encoded public key */
+ ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len,
+ params->q_bits, this->pubkey);
+
+ return &this->public;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data);
typedef struct ntru_public_key_t ntru_public_key_t;
#include "ntru_param_set.h"
+#include "ntru_drbg.h"
#include <library.h>
*/
struct ntru_public_key_t {
+ /**
+ * Returns NTRU parameter set ID of the public key
+ *
+ * @return NTRU parameter set ID
+ */
+ ntru_param_set_id_t (*get_id)(ntru_public_key_t *this);
+
/**
* Returns the packed encoding of the NTRU encryption public key
*
*/
chunk_t (*get_encoding)(ntru_public_key_t *this);
+ /**
+ * Encrypts a plaintext with the NTRU public key
+ *
+ * @param ciphertext Plaintext
+ * @param plaintext Ciphertext
+ * @return TRUE if encryption was successful
+ */
+ bool (*encrypt)(ntru_public_key_t *this, chunk_t plaintext,
+ chunk_t *ciphertext);
+
/**
* Destroy ntru_public_key_t object
*/
};
/**
- * Creates an NTRU encryption public key
+ * Creates an NTRU encryption public key from coefficients
*
+ * @param drbg Deterministic random bit generator
* @param params NTRU encryption parameter set to be used
* @param pubkey Coefficients of public key polynomial h
*/
-ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
+ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg,
+ ntru_param_set_t *params,
uint16_t *pubkey);
+/**
+ * Creates an NTRU encryption public key from encoding
+ *
+ * @param drbg Deterministic random bit generator
+ * @param data Encoded NTRU public key
+ */
+ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg,
+ chunk_t data);
+
#endif /** NTRU_PUBLIC_KEY_H_ @}*/
#include "ntru_trits.h"
#include "ntru_mgf1.h"
-
-#include "ntru_crypto/ntru_crypto_ntru_convert.h"
+#include "ntru_convert.h"
#include <utils/debug.h>
#include <utils/test.h>
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create, ntru_private_key_t*,
ntru_drbg_t *drbg, ntru_param_set_t *params)
+IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data, ntru_private_key_t*,
+ ntru_drbg_t *drbg, chunk_t data)
+
+IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data, ntru_public_key_t*,
+ ntru_drbg_t *drbg, chunk_t data)
+
/**
* NTRU parameter sets to test
*/
privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params);
ck_assert(privkey);
+ ck_assert(privkey->get_id(privkey) == privkey_tests[_i].id);
privkey_encoding = privkey->get_encoding(privkey);
encoding = privkey_tests[_i].encoding;
ck_assert(chunk_equals(privkey_encoding, encoding));
+ /* load private key as a packed blob */
+ privkey->destroy(privkey);
+ privkey = ntru_private_key_create_from_data(drbg, chunk_empty);
+ ck_assert(privkey == NULL);
+
+ encoding = chunk_clone(encoding);
+ encoding.ptr[0] = NTRU_PUBKEY_TAG;
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ ck_assert(privkey == NULL);
+
+ encoding.ptr[0] = NTRU_PRIVKEY_TRITS_TAG;
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ if (params->is_product_form)
+ {
+ ck_assert(privkey == NULL);
+ }
+ else
+ {
+ ck_assert(privkey != NULL);
+ privkey->destroy(privkey);
+ }
+
+ encoding.ptr[0] = NTRU_PRIVKEY_INDICES_TAG;
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ if (params->is_product_form)
+ {
+ ck_assert(privkey != NULL);
+ privkey->destroy(privkey);
+ }
+ else
+ {
+ ck_assert(privkey == NULL);
+ }
+
+ encoding.ptr[0] = NTRU_PRIVKEY_DEFAULT_TAG;
+ encoding.ptr[1] = NTRU_OID_LEN - 1;
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ ck_assert(privkey == NULL);
+
+ encoding.ptr[1] = NTRU_OID_LEN;
+ encoding.ptr[2] = 0xff;
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ ck_assert(privkey == NULL);
- pubkey= privkey->get_public_key(privkey);
+ encoding.ptr[2] = params->oid[0];
+ privkey = ntru_private_key_create_from_data(drbg, encoding);
+ privkey_encoding = privkey->get_encoding(privkey);
+ ck_assert(chunk_equals(privkey_encoding, encoding));
+
+ pubkey = privkey->get_public_key(privkey);
pubkey_encoding = pubkey->get_encoding(pubkey);
- encoding = chunk_clone(encoding);
+
encoding.ptr[0] = NTRU_PUBKEY_TAG;
encoding.len = pubkey_encoding.len;
ck_assert(chunk_equals(pubkey_encoding, encoding));
- /* get encoding a second time without generating it again internally */
+ /* load public key as a packed blob */
+ pubkey->destroy(pubkey);
+ pubkey = ntru_public_key_create_from_data(drbg, encoding);
pubkey_encoding = pubkey->get_encoding(pubkey);
-
+ ck_assert(chunk_equals(pubkey_encoding, encoding));
+
chunk_free(&encoding);
privkey->destroy(privkey);
pubkey->destroy(pubkey);
--- /dev/null
+A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
+The key exchange is based on NTRU encryption with a security strength of 128 bits.
+The ANSI X9.98 NTRU encryption parameter set used is optimized for bandwidth.
+<p/>
+The authentication is based on <b>X.509 certificates</b>. Upon the successful
+establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
+inserts iptables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
+pings client <b>bob</b> located behind gateway <b>sun</b>.
--- /dev/null
+moon::ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
+sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
+moon::ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
+moon::ipsec statusall 2> /dev/null::net-net.*IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
+sun::ipsec statusall 2> /dev/null::net-net.*IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
+sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
+sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
--- /dev/null
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ charondebug="ike 4, lib 4"
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ ike=aes128-sha256-ntru128!
+ esp=aes128-sha256!
+ mobike=no
+
+conn net-net
+ left=PH_IP_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=PH_IP_SUN
+ rightid=@sun.strongswan.org
+ rightsubnet=10.2.0.0/16
+ auto=add
--- /dev/null
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+ load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 ntru revocation hmac stroke kernel-netlink socket-default updown
+
+ multiple_authentication = no
+ send_vendor_id = yes
+
+ plugins {
+ ntru {
+ parameter_set = x9_98_bandwidth
+ }
+ }
+}
--- /dev/null
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ charondebug="ike 4, lib 4"
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ ike=aes128-sha256-ntru128!
+ esp=aes128-sha256!
+ mobike=no
+
+conn net-net
+ left=PH_IP_SUN
+ leftcert=sunCert.pem
+ leftid=@sun.strongswan.org
+ leftsubnet=10.2.0.0/16
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ auto=add
--- /dev/null
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+ load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 ntru revocation hmac stroke kernel-netlink socket-default updown
+
+ multiple_authentication = no
+ send_vendor_id = yes
+
+ plugins {
+ ntru {
+ parameter_set = x9_98_bandwidth
+ }
+ }
+}
--- /dev/null
+moon::ipsec stop
+sun::ipsec stop
+moon::iptables-restore < /etc/iptables.flush
+sun::iptables-restore < /etc/iptables.flush
+
--- /dev/null
+moon::iptables-restore < /etc/iptables.rules
+sun::iptables-restore < /etc/iptables.rules
+moon::ipsec start
+sun::ipsec start
+moon::sleep 1
+moon::ipsec up net-net
--- /dev/null
+#!/bin/bash
+#
+# This configuration file provides information on the
+# guest instances used for this test
+
+# All guest instances that are required for this test
+#
+VIRTHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b.png"
+
+# Guest instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# Guest instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"