Completed integration of ntru_crypto library into ntru plugin

This commit is contained in:
Andreas Steffen 2014-03-22 09:50:39 +01:00
parent b517912848
commit 22e1aa51f9
30 changed files with 1356 additions and 1712 deletions

View File

@ -12,6 +12,7 @@ endif
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 \
@ -19,15 +20,7 @@ libstrongswan_ntru_la_SOURCES = \
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

View File

@ -0,0 +1,452 @@
/*
* 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;
}
}

View File

@ -0,0 +1,147 @@
/*
* 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_ @}*/

View File

@ -1,116 +0,0 @@
/******************************************************************************
* 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 */

View File

@ -1,581 +0,0 @@
/******************************************************************************
* 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;
}
}

View File

@ -1,183 +0,0 @@
/******************************************************************************
* 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 */

View File

@ -1,374 +0,0 @@
/******************************************************************************
* 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, &params, &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;
}

View File

@ -1,187 +0,0 @@
/******************************************************************************
* 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;
}

View File

@ -1,65 +0,0 @@
/******************************************************************************
* 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 */

View File

@ -1,53 +0,0 @@
/******************************************************************************
* 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;
}

View File

@ -1,58 +0,0 @@
/******************************************************************************
* 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 */

View File

@ -67,6 +67,10 @@ struct private_ntru_drbg_t {
*/
chunk_t value;
/**
* reference count
*/
refcount_t ref;
};
/**
@ -180,13 +184,23 @@ METHOD(ntru_drbg_t, generate, bool,
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);
}
}
/*
@ -238,6 +252,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
.get_strength = _get_strength,
.reseed = _reseed,
.generate = _generate,
.get_ref = _get_ref,
.destroy = _destroy,
},
.strength = strength,
@ -247,6 +262,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
.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);

View File

@ -57,6 +57,13 @@ struct ntru_drbg_t {
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
*/

View File

@ -19,8 +19,6 @@
#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>
@ -80,11 +78,6 @@ struct private_ntru_ke_t {
*/
ntru_private_key_t *privkey;
/**
* NTRU Public Key Encoding
*/
chunk_t pubkey_enc;
/**
* NTRU encrypted shared secret
*/
@ -140,11 +133,9 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
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);
}
}
@ -165,8 +156,6 @@ METHOD(diffie_hellman_t, get_shared_secret, status_t,
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 */
@ -187,23 +176,24 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
}
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);
@ -218,25 +208,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
}
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);
@ -256,7 +231,6 @@ METHOD(diffie_hellman_t, destroy, void,
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);

View File

@ -116,4 +116,3 @@ ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id);
ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid);
#endif /** NTRU_PARAM_SET_H_ @}*/

View File

@ -18,8 +18,7 @@
#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>
@ -56,12 +55,23 @@ struct private_ntru_private_key_t {
*/
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);
}
/**
@ -145,9 +155,10 @@ METHOD(ntru_private_key_t, get_encoding, chunk_t,
* @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;
@ -156,8 +167,12 @@ static bool check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
{
++wt[t[i]];
}
success = (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt);
return (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 success;
}
METHOD(ntru_private_key_t, decrypt, bool,
@ -172,7 +187,7 @@ 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;
@ -252,16 +267,17 @@ METHOD(ntru_private_key_t, decrypt, bool,
*/
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 */
@ -397,7 +413,9 @@ METHOD(ntru_private_key_t, decrypt, bool,
if (t[i] != t2[i])
{
DBG1(DBG_LIB, "cR' does not equal cR'");
chunk_clear(plaintext);
success = FALSE;
break;
}
}
memwipe(t, t_len);
@ -414,6 +432,7 @@ METHOD(ntru_private_key_t, destroy, void,
private_ntru_private_key_t *this)
{
DESTROY_IF(this->privkey);
this->drbg->destroy(this->drbg);
chunk_clear(&this->encoding);
free(this->pubkey);
free(this);
@ -622,7 +641,8 @@ static bool ring_inv(uint16_t *a, uint16_t N, uint16_t q, uint16_t *t,
/*
* 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;
@ -635,6 +655,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t
INIT(this,
.public = {
.get_id = _get_id,
.get_public_key = _get_public_key,
.get_encoding = _get_encoding,
.decrypt = _decrypt,
@ -642,6 +663,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t
},
.params = params,
.pubkey = malloc(params->N * sizeof(uint16_t)),
.drbg = drbg->get_ref(drbg),
);
/* set hash algorithm and seed length based on security strength */
@ -742,4 +764,129 @@ err:
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);

View File

@ -34,6 +34,12 @@ typedef struct ntru_private_key_t ntru_private_key_t;
*/
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
@ -73,6 +79,14 @@ struct ntru_private_key_t {
*/
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_ @}*/

View File

@ -16,10 +16,12 @@
*/
#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;
@ -47,37 +49,268 @@ struct 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);
@ -86,7 +319,8 @@ METHOD(ntru_public_key_t, destroy, void,
/*
* 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;
@ -94,11 +328,14 @@ ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
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++)
@ -106,5 +343,66 @@ ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
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);

View File

@ -24,6 +24,7 @@
typedef struct ntru_public_key_t ntru_public_key_t;
#include "ntru_param_set.h"
#include "ntru_drbg.h"
#include <library.h>
@ -32,6 +33,13 @@ typedef struct ntru_public_key_t ntru_public_key_t;
*/
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
*
@ -39,6 +47,16 @@ struct ntru_public_key_t {
*/
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
*/
@ -46,14 +64,25 @@ struct ntru_public_key_t {
};
/**
* 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_ @}*/

View File

@ -15,8 +15,7 @@
#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>

View File

@ -49,6 +49,12 @@ IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_param_set_get_by_id, ntru_param_set_t* ,
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
*/
@ -1086,22 +1092,74 @@ START_TEST(test_ntru_privkey)
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));
pubkey= privkey->get_public_key(privkey);
pubkey_encoding = pubkey->get_encoding(pubkey);
/* 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);
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.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);

View File

@ -0,0 +1,9 @@
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>.

View File

@ -0,0 +1,9 @@
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

View File

@ -0,0 +1,25 @@
# /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

View File

@ -0,0 +1,14 @@
# /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
}
}
}

View File

@ -0,0 +1,25 @@
# /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

View File

@ -0,0 +1,14 @@
# /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
}
}
}

View File

@ -0,0 +1,5 @@
moon::ipsec stop
sun::ipsec stop
moon::iptables-restore < /etc/iptables.flush
sun::iptables-restore < /etc/iptables.flush

View File

@ -0,0 +1,6 @@
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

View File

@ -0,0 +1,21 @@
#!/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"