ntru: Removed legacy NTRU key exchange method

This commit is contained in:
Andreas Steffen 2020-11-18 10:39:28 +01:00
parent 00520b3ae8
commit c75a20f6f5
52 changed files with 18 additions and 5077 deletions

View File

@ -77,7 +77,6 @@ plugins = \
plugins/kernel-pfroute.opt \
plugins/load-tester.opt \
plugins/lookip.opt \
plugins/ntru.opt \
plugins/openssl.opt \
plugins/osx-attr.opt \
plugins/p-cscf.opt \

View File

@ -1,4 +0,0 @@
charon.plugins.ntru.parameter_set = optimum
The following parameter sets are available: **x9_98_speed**,
**x9_98_bandwidth**, **x9_98_balance** and **optimum**, the last set not
being part of the X9.98 standard but having the best performance.

View File

@ -151,7 +151,6 @@ ARG_ENABL_SET([md4], [enable MD4 software implementation plugin.])
ARG_DISBL_SET([md5], [disable MD5 software implementation plugin.])
ARG_ENABL_SET([mgf1], [enable the MGF1 software implementation plugin.])
ARG_DISBL_SET([nonce], [disable nonce generation plugin.])
ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.])
ARG_ENABL_SET([frodo], [enable FrodoKEM Post Quantum Safe plugin.])
ARG_ENABL_SET([oqs], [enable Open Quantum Safe (liboqs) plugin.])
ARG_ENABL_SET([openssl], [enables the OpenSSL crypto plugin.])
@ -504,7 +503,7 @@ if test x$tpm = xtrue; then
tss_tss2=true
fi
if test x$gmp = xtrue -o x$ntru = xtrue; then
if test x$gmp = xtrue; then
mgf1=true
fi
@ -1505,7 +1504,6 @@ ADD_PLUGIN([hmac], [s charon pki scripts nm cmd])
ADD_PLUGIN([ctr], [s charon scripts nm cmd])
ADD_PLUGIN([ccm], [s charon scripts nm cmd])
ADD_PLUGIN([gcm], [s charon scripts nm cmd])
ADD_PLUGIN([ntru], [s charon scripts nm cmd])
ADD_PLUGIN([frodo], [s charon scripts nm cmd])
ADD_PLUGIN([oqs], [s charon scripts nm cmd])
ADD_PLUGIN([drbg], [s charon pki scripts nm cmd])
@ -1673,7 +1671,6 @@ AM_CONDITIONAL(USE_CTR, test x$ctr = xtrue)
AM_CONDITIONAL(USE_CCM, test x$ccm = xtrue)
AM_CONDITIONAL(USE_GCM, test x$gcm = xtrue)
AM_CONDITIONAL(USE_AF_ALG, test x$af_alg = xtrue)
AM_CONDITIONAL(USE_NTRU, test x$ntru = xtrue)
AM_CONDITIONAL(USE_DRBG, test x$drbg = xtrue)
AM_CONDITIONAL(USE_OQS, test x$oqs = xtrue)
AM_CONDITIONAL(USE_FRODO, test x$frodo = xtrue)
@ -1952,7 +1949,6 @@ AC_CONFIG_FILES([
src/libstrongswan/plugins/gcm/Makefile
src/libstrongswan/plugins/af_alg/Makefile
src/libstrongswan/plugins/drbg/Makefile
src/libstrongswan/plugins/ntru/Makefile
src/libstrongswan/plugins/frodo/Makefile
src/libstrongswan/plugins/oqs/Makefile
src/libstrongswan/plugins/oqs/tests/Makefile

View File

@ -639,13 +639,6 @@ if MONOLITHIC
endif
endif
if USE_NTRU
SUBDIRS += plugins/ntru
if MONOLITHIC
libstrongswan_la_LIBADD += plugins/ntru/libstrongswan-ntru.la
endif
endif
if USE_DRBG
SUBDIRS += plugins/drbg
if MONOLITHIC

View File

@ -50,12 +50,7 @@ ENUM_NEXT(key_exchange_method_names, MODP_1024_160, CURVE_448, ECP_521_BIT,
"CURVE_448");
ENUM_NEXT(key_exchange_method_names, MODP_NULL, MODP_NULL, CURVE_448,
"MODP_NULL");
ENUM_NEXT(key_exchange_method_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL,
"NTRU_112",
"NTRU_128",
"NTRU_192",
"NTRU_256");
ENUM_NEXT(key_exchange_method_names, KE_KYBER_L1, KE_SIKE_L5, NTRU_256_BIT,
ENUM_NEXT(key_exchange_method_names, KE_KYBER_L1, KE_SIKE_L5, MODP_NULL,
"KYBER_L1",
"KYBER_L3",
"KYBER_L5",
@ -115,12 +110,7 @@ ENUM_NEXT(key_exchange_method_names_short, MODP_1024_160, CURVE_448, ECP_521_BIT
"curve448");
ENUM_NEXT(key_exchange_method_names_short, MODP_NULL, MODP_NULL, CURVE_448,
"modpnull");
ENUM_NEXT(key_exchange_method_names_short, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL,
"ntru112",
"ntru128",
"ntru192",
"ntru256");
ENUM_NEXT(key_exchange_method_names_short, KE_KYBER_L1, KE_SIKE_L5, NTRU_256_BIT,
ENUM_NEXT(key_exchange_method_names_short, KE_KYBER_L1, KE_SIKE_L5, MODP_NULL,
"kyber1",
"kyber3",
"kyber5",
@ -759,10 +749,6 @@ bool key_exchange_verify_pubkey(key_exchange_method_t ke, chunk_t value)
case CURVE_448:
valid = value.len == 56;
break;
case NTRU_112_BIT:
case NTRU_128_BIT:
case NTRU_192_BIT:
case NTRU_256_BIT:
case KE_KYBER_L1:
case KE_KYBER_L3:
case KE_KYBER_L5:

View File

@ -67,11 +67,6 @@ enum key_exchange_method_t {
CURVE_448 = 32,
/** insecure NULL diffie hellman group for testing, in PRIVATE USE */
MODP_NULL = 1024,
/** Parameters defined by IEEE 1363.1, in PRIVATE USE */
NTRU_112_BIT = 1030,
NTRU_128_BIT = 1031,
NTRU_192_BIT = 1032,
NTRU_256_BIT = 1033,
/** NIST round 3 KEM candidates, in PRIVATE USE */
KE_KYBER_L1 = 1050,
KE_KYBER_L3 = 1051,

View File

@ -1199,7 +1199,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
}
enumerator->destroy(enumerator);
/* Round 1 adds ECC and NTRU algorithms with at least 128 bit security strength */
/* Round 1 adds ECC with at least 128 bit security strength */
enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
while (enumerator->enumerate(enumerator, &group, &plugin_name))
{
@ -1213,9 +1213,6 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
case ECP_512_BP:
case CURVE_25519:
case CURVE_448:
case NTRU_128_BIT:
case NTRU_192_BIT:
case NTRU_256_BIT:
add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0);
break;
default:
@ -1264,7 +1261,6 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
case ECP_224_BIT:
case ECP_224_BP:
case ECP_192_BIT:
case NTRU_112_BIT:
/* rarely used */
break;
case MODP_2048_BIT:

View File

@ -175,10 +175,6 @@ curve25519, KEY_EXCHANGE_METHOD, CURVE_25519, 0
x25519, KEY_EXCHANGE_METHOD, CURVE_25519, 0
curve448, KEY_EXCHANGE_METHOD, CURVE_448, 0
x448, KEY_EXCHANGE_METHOD, CURVE_448, 0
ntru112, KEY_EXCHANGE_METHOD, NTRU_112_BIT, 0
ntru128, KEY_EXCHANGE_METHOD, NTRU_128_BIT, 0
ntru192, KEY_EXCHANGE_METHOD, NTRU_192_BIT, 0
ntru256, KEY_EXCHANGE_METHOD, NTRU_256_BIT, 0
kyber1, KEY_EXCHANGE_METHOD, KE_KYBER_L1, 0
kyber3, KEY_EXCHANGE_METHOD, KE_KYBER_L3, 0
kyber5, KEY_EXCHANGE_METHOD, KE_KYBER_L5, 0

View File

@ -1,23 +0,0 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan
AM_CFLAGS = \
$(PLUGIN_CFLAGS)
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-ntru.la
else
plugin_LTLIBRARIES = libstrongswan-ntru.la
endif
libstrongswan_ntru_la_SOURCES = \
ntru_plugin.h ntru_plugin.c \
ntru_convert.h ntru_convert.c \
ntru_ke.h ntru_ke.c \
ntru_param_set.h ntru_param_set.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
libstrongswan_ntru_la_LDFLAGS = -module -avoid-version

View File

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

@ -1,147 +0,0 @@
/*
* 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,331 +0,0 @@
/*
* Copyright (C) 2013-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "ntru_ke.h"
#include "ntru_param_set.h"
#include "ntru_private_key.h"
#include "ntru_public_key.h"
#include <crypto/key_exchange.h>
#include <crypto/drbgs/drbg.h>
#include <utils/debug.h>
typedef struct private_ntru_ke_t private_ntru_ke_t;
/* Best bandwidth and speed, no X9.98 compatibility */
static const ntru_param_set_id_t param_sets_optimum[] = {
NTRU_EES401EP2, NTRU_EES439EP1, NTRU_EES593EP1, NTRU_EES743EP1
};
/* X9.98/IEEE 1363.1 parameter sets for best speed */
static const ntru_param_set_id_t param_sets_x9_98_speed[] = {
NTRU_EES659EP1, NTRU_EES761EP1, NTRU_EES1087EP1, NTRU_EES1499EP1
};
/* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */
static const ntru_param_set_id_t param_sets_x9_98_bandwidth[] = {
NTRU_EES401EP1, NTRU_EES449EP1, NTRU_EES677EP1, NTRU_EES1087EP2
};
/* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */
static const ntru_param_set_id_t param_sets_x9_98_balance[] = {
NTRU_EES541EP1, NTRU_EES613EP1, NTRU_EES887EP1, NTRU_EES1171EP1
};
/**
* Private data of an ntru_ke_t object.
*/
struct private_ntru_ke_t {
/**
* Public ntru_ke_t interface.
*/
ntru_ke_t public;
/**
* Diffie Hellman group number.
*/
key_exchange_method_t group;
/**
* NTRU Parameter Set
*/
const ntru_param_set_t *param_set;
/**
* Cryptographical strength in bits of the NTRU Parameter Set
*/
uint32_t strength;
/**
* NTRU Public Key
*/
ntru_public_key_t *pubkey;
/**
* NTRU Private Key
*/
ntru_private_key_t *privkey;
/**
* NTRU encrypted shared secret
*/
chunk_t ciphertext;
/**
* Shared secret
*/
chunk_t shared_secret;
/**
* True if peer is responder
*/
bool responder;
/**
* True if shared secret is computed
*/
bool computed;
/**
* True Random Generator
*/
rng_t *entropy;
/**
* Deterministic Random Bit Generator
*/
drbg_t *drbg;
};
METHOD(key_exchange_t, get_public_key, bool,
private_ntru_ke_t *this, chunk_t *value)
{
*value = chunk_empty;
if (this->responder)
{
if (this->ciphertext.len)
{
*value = chunk_clone(this->ciphertext);
}
}
else
{
if (!this->pubkey)
{
/* generate a random NTRU public/private key pair */
this->privkey = ntru_private_key_create(this->drbg, this->param_set);
if (!this->privkey)
{
DBG1(DBG_LIB, "NTRU key pair generation failed");
return FALSE;
}
this->pubkey = this->privkey->get_public_key(this->privkey);
}
*value = chunk_clone(this->pubkey->get_encoding(this->pubkey));
DBG3(DBG_LIB, "NTRU public key: %B", value);
}
return TRUE;
}
METHOD(key_exchange_t, get_shared_secret, bool,
private_ntru_ke_t *this, chunk_t *secret)
{
if (!this->computed || !this->shared_secret.len)
{
*secret = chunk_empty;
return FALSE;
}
*secret = chunk_clone(this->shared_secret);
return TRUE;
}
METHOD(key_exchange_t, set_public_key, bool,
private_ntru_ke_t *this, chunk_t value)
{
if (this->privkey)
{
/* initiator decrypting shared secret */
if (value.len == 0)
{
DBG1(DBG_LIB, "empty NTRU ciphertext");
return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &value);
/* decrypt the shared secret */
if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret))
{
DBG1(DBG_LIB, "NTRU decryption of shared secret failed");
return FALSE;
}
this->computed = TRUE;
}
else
{
ntru_public_key_t *pubkey;
/* responder generating and encrypting the shared secret */
this->responder = TRUE;
DBG3(DBG_LIB, "NTRU public key: %B", &value);
pubkey = ntru_public_key_create_from_data(this->drbg, value);
if (!pubkey)
{
return FALSE;
}
if (pubkey->get_id(pubkey) != this->param_set->id)
{
DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
pubkey->destroy(pubkey);
return FALSE;
}
this->pubkey = pubkey;
/* shared secret size is chosen as twice the cryptographical strength */
this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
/* generate the random shared secret */
if (!this->drbg->generate(this->drbg, this->shared_secret.len,
this->shared_secret.ptr))
{
DBG1(DBG_LIB, "generation of shared secret failed");
chunk_free(&this->shared_secret);
return FALSE;
}
this->computed = TRUE;
/* encrypt the shared secret */
if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
{
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
return FALSE;
}
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
}
return this->computed;
}
METHOD(key_exchange_t, get_method, key_exchange_method_t,
private_ntru_ke_t *this)
{
return this->group;
}
METHOD(key_exchange_t, destroy, void,
private_ntru_ke_t *this)
{
DESTROY_IF(this->privkey);
DESTROY_IF(this->pubkey);
this->drbg->destroy(this->drbg);
chunk_free(&this->ciphertext);
chunk_clear(&this->shared_secret);
free(this);
}
/*
* Described in header.
*/
ntru_ke_t *ntru_ke_create(key_exchange_method_t group, chunk_t g, chunk_t p)
{
private_ntru_ke_t *this;
const ntru_param_set_id_t *param_sets;
ntru_param_set_id_t param_set_id;
rng_t *entropy;
drbg_t *drbg;
char *parameter_set;
uint32_t strength;
parameter_set = lib->settings->get_str(lib->settings,
"%s.plugins.ntru.parameter_set", "optimum", lib->ns);
if (streq(parameter_set, "x9_98_speed"))
{
param_sets = param_sets_x9_98_speed;
}
else if (streq(parameter_set, "x9_98_bandwidth"))
{
param_sets = param_sets_x9_98_bandwidth;
}
else if (streq(parameter_set, "x9_98_balance"))
{
param_sets = param_sets_x9_98_balance;
}
else
{
param_sets = param_sets_optimum;
}
switch (group)
{
case NTRU_112_BIT:
strength = 112;
param_set_id = param_sets[0];
break;
case NTRU_128_BIT:
strength = 128;
param_set_id = param_sets[1];
break;
case NTRU_192_BIT:
strength = 192;
param_set_id = param_sets[2];
break;
case NTRU_256_BIT:
strength = 256;
param_set_id = param_sets[3];
break;
default:
return NULL;
}
DBG1(DBG_LIB, "%u bit %s NTRU parameter set %N selected", strength,
parameter_set, ntru_param_set_id_names, param_set_id);
/* entropy will be owned by drbg */
entropy = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
if (!entropy)
{
DBG1(DBG_LIB, "could not attach entropy source for DRBG");
return NULL;
}
drbg = lib->crypto->create_drbg(lib->crypto, DRBG_HMAC_SHA256, strength,
entropy, chunk_from_str("IKE NTRU-KE"));
if (!drbg)
{
DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
entropy->destroy(entropy);
return NULL;
}
INIT(this,
.public = {
.ke = {
.get_shared_secret = _get_shared_secret,
.set_public_key = _set_public_key,
.get_public_key = _get_public_key,
.get_method = _get_method,
.destroy = _destroy,
},
},
.group = group,
.param_set = ntru_param_set_get_by_id(param_set_id),
.strength = strength,
.entropy = entropy,
.drbg = drbg,
);
return &this->public;
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2013 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_ke ntru_ke
* @{ @ingroup ntru_p
*/
#ifndef NTRU_KE_H_
#define NTRU_KE_H_
typedef struct ntru_ke_t ntru_ke_t;
#include <library.h>
/**
* Implementation of a key exchange algorithm using NTRU encryption
*/
struct ntru_ke_t {
/**
* Implements key_exchange_t interface.
*/
key_exchange_t ke;
};
/**
* Creates a new ntru_ke_t object.
*
* @param group NTRU group number to use
* @param g not used
* @param p not used
* @return ntru_ke_t object, NULL if not supported
*/
ntru_ke_t *ntru_ke_create(key_exchange_method_t group, chunk_t g, chunk_t p);
#endif /** NTRU_KE_H_ @}*/

View File

@ -1,375 +0,0 @@
/*
* 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 "ntru_param_set.h"
#include <utils/test.h>
ENUM(ntru_param_set_id_names, NTRU_EES401EP1, NTRU_EES743EP1,
"ees401ep1",
"ees449ep1",
"ees677ep1",
"ees1087ep2",
"ees541ep1",
"ees613ep1",
"ees887ep1",
"ees1171ep1",
"ees659ep1",
"ees761ep1",
"ees1087ep1",
"ees1499ep1",
"ees401ep2",
"ees439ep1",
"ees593ep1",
"ees743ep1"
);
/**
* NTRU encryption parameter set definitions
*/
static const ntru_param_set_t ntru_param_sets[] = {
/* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */
{
NTRU_EES401EP1, /* parameter-set id */
{0x00, 0x02, 0x04}, /* OID */
0x22, /* DER id */
9, /* no. of bits in N (i.e., in an index) */
401, /* N */
14, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
113, /* df, dr */
133, /* dg */
60, /* maxMsgLenBytes */
113, /* dm0 */
11, /* c */
1, /* lLen */
},
{
NTRU_EES449EP1, /* parameter-set id */
{0x00, 0x03, 0x03}, /* OID */
0x23, /* DER id */
9, /* no. of bits in N (i.e., in an index) */
449, /* N */
16, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
134, /* df, dr */
149, /* dg */
67, /* maxMsgLenBytes */
134, /* dm0 */
9, /* c */
1, /* lLen */
},
{
NTRU_EES677EP1, /* parameter-set id */
{0x00, 0x05, 0x03}, /* OID */
0x24, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
677, /* N */
24, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
157, /* df, dr */
225, /* dg */
101, /* maxMsgLenBytes */
157, /* dm0 */
11, /* c */
1, /* lLen */
},
{
NTRU_EES1087EP2, /* parameter-set id */
{0x00, 0x06, 0x03}, /* OID */
0x25, /* DER id */
11, /* no. of bits in N (i.e., in an index) */
1087, /* N */
32, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
120, /* df, dr */
362, /* dg */
170, /* maxMsgLenBytes */
120, /* dm0 */
13, /* c */
1, /* lLen */
},
/* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */
{
NTRU_EES541EP1, /* parameter-set id */
{0x00, 0x02, 0x05}, /* OID */
0x26, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
541, /* N */
14, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
49, /* df, dr */
180, /* dg */
86, /* maxMsgLenBytes */
49, /* dm0 */
12, /* c */
1, /* lLen */
},
{
NTRU_EES613EP1, /* parameter-set id */
{0x00, 0x03, 0x04}, /* OID */
0x27, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
613, /* N */
16, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
55, /* df, dr */
204, /* dg */
97, /* maxMsgLenBytes */
55, /* dm0 */
11, /* c */
1, /* lLen */
},
{
NTRU_EES887EP1, /* parameter-set id */
{0x00, 0x05, 0x04}, /* OID */
0x28, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
887, /* N */
24, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
81, /* df, dr */
295, /* dg */
141, /* maxMsgLenBytes */
81, /* dm0 */
10, /* c */
1, /* lLen */
},
{
NTRU_EES1171EP1, /* parameter-set id */
{0x00, 0x06, 0x04}, /* OID */
0x29, /* DER id */
11, /* no. of bits in N (i.e., in an index) */
1171, /* N */
32, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
106, /* df, dr */
390, /* dg */
186, /* maxMsgLenBytes */
106, /* dm0 */
12, /* c */
1, /* lLen */
},
/* X9.98/IEEE 1363.1 parameter sets for best speed */
{
NTRU_EES659EP1, /* parameter-set id */
{0x00, 0x02, 0x06}, /* OID */
0x2a, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
659, /* N */
14, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
38, /* df, dr */
219, /* dg */
108, /* maxMsgLenBytes */
38, /* dm0 */
11, /* c */
1, /* lLen */
},
{
NTRU_EES761EP1, /* parameter-set id */
{0x00, 0x03, 0x05}, /* OID */
0x2b, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
761, /* N */
16, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
42, /* df, dr */
253, /* dg */
125, /* maxMsgLenBytes */
42, /* dm0 */
12, /* c */
1, /* lLen */
},
{
NTRU_EES1087EP1, /* parameter-set id */
{0x00, 0x05, 0x05}, /* OID */
0x2c, /* DER id */
11, /* no. of bits in N (i.e., in an index) */
1087, /* N */
24, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
63, /* df, dr */
362, /* dg */
178, /* maxMsgLenBytes */
63, /* dm0 */
13, /* c */
1, /* lLen */
},
{
NTRU_EES1499EP1, /* parameter-set id */
{0x00, 0x06, 0x05}, /* OID */
0x2d, /* DER id */
11, /* no. of bits in N (i.e., in an index) */
1499, /* N */
32, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
FALSE, /* product form */
79, /* df, dr */
499, /* dg */
247, /* maxMsgLenBytes */
79, /* dm0 */
13, /* c */
1, /* lLen */
},
/* Best bandwidth and speed, no X9.98 compatibility */
{
NTRU_EES401EP2, /* parameter-set id */
{0x00, 0x02, 0x10}, /* OID */
0x2e, /* DER id */
9, /* no. of bits in N (i.e., in an index) */
401, /* N */
14, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
TRUE, /* product form */
8 + (8 << 8) + (6 << 16), /* df, dr */
133, /* dg */
60, /* maxMsgLenBytes */
136, /* m(1)_max */
11, /* c */
1, /* lLen */
},
{
NTRU_EES439EP1, /* parameter-set id */
{0x00, 0x03, 0x10}, /* OID */
0x2f, /* DER id */
9, /* no. of bits in N (i.e., in an index) */
439, /* N */
16, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
TRUE, /* product form */
9 + (8 << 8) + (5 << 16), /* df, dr */
146, /* dg */
65, /* maxMsgLenBytes */
126, /* m(1)_max */
9, /* c */
1, /* lLen */
},
{
NTRU_EES593EP1, /* parameter-set id */
{0x00, 0x05, 0x10}, /* OID */
0x30, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
593, /* N */
24, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
TRUE, /* product form */
10 + (10 << 8) + (8 << 16), /* df, dr */
197, /* dg */
86, /* maxMsgLenBytes */
90, /* m(1)_max */
11, /* c */
1, /* lLen */
},
{
NTRU_EES743EP1, /* parameter-set id */
{0x00, 0x06, 0x10}, /* OID */
0x31, /* DER id */
10, /* no. of bits in N (i.e., in an index) */
743, /* N */
32, /* security strength in octets */
2048, /* q */
11, /* no. of bits in q (i.e., in a coeff) */
TRUE, /* product form */
11 + (11 << 8) + (15 << 16), /* df, dr */
247, /* dg */
106, /* maxMsgLenBytes */
60, /* m(1)_max */
13, /* c */
1, /* lLen */
},
};
/**
* See header.
*/
const ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id)
{
int i;
for (i = 0; i < countof(ntru_param_sets); i++)
{
if (ntru_param_sets[i].id == id)
{
return &ntru_param_sets[i];
}
}
return NULL;
}
/**
* See header.
*/
const ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid)
{
int i;
for (i = 0; i < countof(ntru_param_sets); i++)
{
if (memeq(ntru_param_sets[i].oid, oid, 3))
{
return &ntru_param_sets[i];
}
}
return NULL;
}
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_param_set_get_by_id);

View File

@ -1,176 +0,0 @@
/*
* 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_param_set ntru_param_set
* @{ @ingroup ntru_p
*/
#ifndef NTRU_PARAM_SET_H_
#define NTRU_PARAM_SET_H_
typedef enum ntru_param_set_id_t ntru_param_set_id_t;
typedef struct ntru_param_set_t ntru_param_set_t;
#include <library.h>
/**
* Encoding types for NTRU encryption public/private key blobs
*/
#define NTRU_PUBKEY_TAG 0x01
#define NTRU_PRIVKEY_DEFAULT_TAG 0x02
#define NTRU_PRIVKEY_TRITS_TAG 0xfe
#define NTRU_PRIVKEY_INDICES_TAG 0xff
/**
* Size in octets of the OID designating the NTRU encryption parameter set
*/
#define NTRU_OID_LEN 3
/**
* Packing types for NTRU encryption public/private keys
*/
#define NTRU_KEY_PACKED_COEFFICIENTS 0x01
#define NTRU_KEY_PACKED_INDICES 0x02
#define NTRU_KEY_PACKED_TRITS 0x03
/**
* NTRU encryption parameter set ID list
*/
enum ntru_param_set_id_t {
/* X9.98/IEEE 1363.1 parameter sets for best bandwidth (smallest size) */
NTRU_EES401EP1,
NTRU_EES449EP1,
NTRU_EES677EP1,
NTRU_EES1087EP2,
/* X9.98/IEEE 1363.1 parameter sets balancing speed and bandwidth */
NTRU_EES541EP1,
NTRU_EES613EP1,
NTRU_EES887EP1,
NTRU_EES1171EP1,
/* X9.98/IEEE 1363.1 parameter sets for best speed */
NTRU_EES659EP1,
NTRU_EES761EP1,
NTRU_EES1087EP1,
NTRU_EES1499EP1,
/* Best bandwidth and speed, no X9.98 compatibility */
NTRU_EES401EP2,
NTRU_EES439EP1,
NTRU_EES593EP1,
NTRU_EES743EP1,
};
extern enum_name_t *ntru_param_set_id_names;
/**
* NTRU encryption parameter set definitions
*/
struct ntru_param_set_t {
/**
* NTRU parameter set ID
*/
const ntru_param_set_id_t id;
/**
* pointer to OID
*/
const uint8_t oid[NTRU_OID_LEN];
/**
* parameter-set DER id
*/
const uint8_t der_id;
/**
* no. of bits in N (i.e. in an index
*/
const uint8_t N_bits;
/**
* ring dimension
*/
const uint16_t N;
/**
* no. of octets of security strength
*/
const uint16_t sec_strength_len;
/**
* big modulus
*/
const uint16_t q;
/**
* no. of bits in q (i.e. in a coefficient)
*/
const uint8_t q_bits;
/**
* if product form used
*/
const bool is_product_form;
/**
* no. of +1 or -1 coefficients in ring elements F, r
*/
const uint32_t dF_r;
/**
* no. - 1 of +1 coefficients or no. of -1 coefficients in ring element g
*/
const uint16_t dg;
/**
* max no. of plaintext octets
*/
const uint16_t m_len_max;
/**
* min. message representative weight
*/
const uint16_t min_msg_rep_wt;
/**
* no. bits in candidate for deriving an index
*/
const uint8_t c_bits;
/**
* no. of octets to hold mLenOctets
*/
const uint8_t m_len_len;
};
/**
* Get NTRU encryption parameter set by NTRU parameter set ID
*
* @param id NTRU parameter set ID
* @return NTRU parameter set
*/
const ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id);
/**
* Get NTRU encryption parameter set by NTRU parameter set OID
*
* @param oid NTRU parameter set OID
* @return NTRU parameter set
*/
const ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid);
#endif /** NTRU_PARAM_SET_H_ @}*/

View File

@ -1,91 +0,0 @@
/*
* Copyright (C) 2013-2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "ntru_plugin.h"
#include "ntru_ke.h"
#include <library.h>
typedef struct private_ntru_plugin_t private_ntru_plugin_t;
/**
* private data of ntru_plugin
*/
struct private_ntru_plugin_t {
/**
* public functions
*/
ntru_plugin_t public;
};
METHOD(plugin_t, get_name, char*,
private_ntru_plugin_t *this)
{
return "ntru";
}
METHOD(plugin_t, get_features, int,
private_ntru_plugin_t *this, plugin_feature_t *features[])
{
static plugin_feature_t f[] = {
PLUGIN_REGISTER(KE, ntru_ke_create),
PLUGIN_PROVIDE(KE, NTRU_112_BIT),
PLUGIN_DEPENDS(RNG, RNG_TRUE),
PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256),
PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA1),
PLUGIN_PROVIDE(KE, NTRU_128_BIT),
PLUGIN_DEPENDS(RNG, RNG_TRUE),
PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256),
PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA1),
PLUGIN_PROVIDE(KE, NTRU_192_BIT),
PLUGIN_DEPENDS(RNG, RNG_TRUE),
PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256),
PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA256),
PLUGIN_PROVIDE(KE, NTRU_256_BIT),
PLUGIN_DEPENDS(RNG, RNG_TRUE),
PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_SHA2_256_256),
PLUGIN_DEPENDS(XOF, XOF_MGF1_SHA256),
};
*features = f;
return countof(f);
}
METHOD(plugin_t, destroy, void,
private_ntru_plugin_t *this)
{
free(this);
}
/*
* see header file
*/
plugin_t *ntru_plugin_create()
{
private_ntru_plugin_t *this;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
.get_features = _get_features,
.destroy = _destroy,
},
},
);
return &this->public.plugin;
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (C) 2013 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_p ntru
* @ingroup plugins
*
* @defgroup ntru_plugin ntru_plugin
* @{ @ingroup ntru_p
*/
#ifndef NTRU_PLUGIN_H_
#define NTRU_PLUGIN_H_
#include <plugins/plugin.h>
typedef struct ntru_plugin_t ntru_plugin_t;
/**
* Plugin implementing NTRU-base key exchange
*/
struct ntru_plugin_t {
/**
* implements plugin interface
*/
plugin_t plugin;
};
#endif /** NTRU_PLUGIN_H_ @}*/

View File

@ -1,377 +0,0 @@
/*
* Copyright (C) 2014-2016 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 "ntru_poly.h"
#include <crypto/xofs/xof_bitspender.h>
#include <utils/debug.h>
#include <utils/test.h>
typedef struct private_ntru_poly_t private_ntru_poly_t;
typedef struct indices_len_t indices_len_t;
/**
* Stores number of +1 and -1 coefficients
*/
struct indices_len_t {
int p;
int m;
};
/**
* Private data of an ntru_poly_t object.
*/
struct private_ntru_poly_t {
/**
* Public ntru_poly_t interface.
*/
ntru_poly_t public;
/**
* Ring dimension equal to the number of polynomial coefficients
*/
uint16_t N;
/**
* Large modulus
*/
uint16_t q;
/**
* Array containing the indices of the non-zero coefficients
*/
uint16_t *indices;
/**
* Number of indices of the non-zero coefficients
*/
size_t num_indices;
/**
* Number of sparse polynomials
*/
int num_polynomials;
/**
* Number of nonzero coefficients for up to 3 sparse polynomials
*/
indices_len_t indices_len[3];
};
METHOD(ntru_poly_t, get_size, size_t,
private_ntru_poly_t *this)
{
return this->num_indices;
}
METHOD(ntru_poly_t, get_indices, uint16_t*,
private_ntru_poly_t *this)
{
return this->indices;
}
/**
* Multiplication of polynomial a with a sparse polynomial b given by
* the indices of its +1 and -1 coefficients results in polynomial c.
* This is a convolution operation
*/
static void ring_mult_i(uint16_t *a, indices_len_t len, uint16_t *indices,
uint16_t N, uint16_t mod_q_mask, uint16_t *t,
uint16_t *c)
{
int i, j, k;
/* initialize temporary array t */
for (k = 0; k < N; k++)
{
t[k] = 0;
}
/* t[(i+k)%N] = sum i=0 through N-1 of a[i], for b[k] = -1 */
for (j = len.p; j < len.p + len.m; j++)
{
k = indices[j];
for (i = 0; k < N; ++i, ++k)
{
t[k] += a[i];
}
for (k = 0; i < N; ++i, ++k)
{
t[k] += a[i];
}
}
/* t[(i+k)%N] = -(sum i=0 through N-1 of a[i] for b[k] = -1) */
for (k = 0; k < N; k++)
{
t[k] = -t[k];
}
/* t[(i+k)%N] += sum i=0 through N-1 of a[i] for b[k] = +1 */
for (j = 0; j < len.p; j++)
{
k = indices[j];
for (i = 0; k < N; ++i, ++k)
{
t[k] += a[i];
}
for (k = 0; i < N; ++i, ++k)
{
t[k] += a[i];
}
}
/* c = (a * b) mod q */
for (k = 0; k < N; k++)
{
c[k] = t[k] & mod_q_mask;
}
}
METHOD(ntru_poly_t, get_array, void,
private_ntru_poly_t *this, uint16_t *array)
{
uint16_t *t, *bi;
uint16_t mod_q_mask = this->q - 1;
indices_len_t len;
int i;
/* form polynomial F or F1 */
memset(array, 0x00, this->N * sizeof(uint16_t));
bi = this->indices;
len = this->indices_len[0];
for (i = 0; i < len.p + len.m; i++)
{
array[bi[i]] = (i < len.p) ? 1 : mod_q_mask;
}
if (this->num_polynomials == 3)
{
/* allocate temporary array t */
t = malloc(this->N * sizeof(uint16_t));
/* form F1 * F2 */
bi += len.p + len.m;
len = this->indices_len[1];
ring_mult_i(array, len, bi, this->N, mod_q_mask, t, array);
/* form (F1 * F2) + F3 */
bi += len.p + len.m;
len = this->indices_len[2];
for (i = 0; i < len.p + len.m; i++)
{
if (i < len.p)
{
array[bi[i]] += 1;
}
else
{
array[bi[i]] -= 1;
}
array[bi[i]] &= mod_q_mask;
}
free(t);
}
}
METHOD(ntru_poly_t, ring_mult, void,
private_ntru_poly_t *this, uint16_t *a, uint16_t *c)
{
uint16_t *t1, *t2;
uint16_t *bi = this->indices;
uint16_t mod_q_mask = this->q - 1;
int i;
/* allocate temporary array t1 */
t1 = malloc(this->N * sizeof(uint16_t));
if (this->num_polynomials == 1)
{
ring_mult_i(a, this->indices_len[0], bi, this->N, mod_q_mask, t1, c);
}
else
{
/* allocate temporary array t2 */
t2 = malloc(this->N * sizeof(uint16_t));
/* t1 = a * b1 */
ring_mult_i(a, this->indices_len[0], bi, this->N, mod_q_mask, t1, t1);
/* t1 = (a * b1) * b2 */
bi += this->indices_len[0].p + this->indices_len[0].m;
ring_mult_i(t1, this->indices_len[1], bi, this->N, mod_q_mask, t2, t1);
/* t2 = a * b3 */
bi += this->indices_len[1].p + this->indices_len[1].m;
ring_mult_i(a, this->indices_len[2], bi, this->N, mod_q_mask, t2, t2);
/* c = (a * b1 * b2) + (a * b3) */
for (i = 0; i < this->N; i++)
{
c[i] = (t1[i] + t2[i]) & mod_q_mask;
}
free(t2);
}
free(t1);
}
METHOD(ntru_poly_t, destroy, void,
private_ntru_poly_t *this)
{
memwipe(this->indices, sizeof(uint16_t) * get_size(this));
free(this->indices);
free(this);
}
/**
* Creates an empty ntru_poly_t object with space allocated for indices
*/
static private_ntru_poly_t* ntru_poly_create(uint16_t N, uint16_t q,
uint32_t indices_len_p,
uint32_t indices_len_m,
bool is_product_form)
{
private_ntru_poly_t *this;
int n;
INIT(this,
.public = {
.get_size = _get_size,
.get_indices = _get_indices,
.get_array = _get_array,
.ring_mult = _ring_mult,
.destroy = _destroy,
},
.N = N,
.q = q,
);
if (is_product_form)
{
this->num_polynomials = 3;
for (n = 0; n < 3; n++)
{
this->indices_len[n].p = 0xff & indices_len_p;
this->indices_len[n].m = 0xff & indices_len_m;
this->num_indices += this->indices_len[n].p +
this->indices_len[n].m;
indices_len_p >>= 8;
indices_len_m >>= 8;
}
}
else
{
this->num_polynomials = 1;
this->indices_len[0].p = indices_len_p;
this->indices_len[0].m = indices_len_m;
this->num_indices = indices_len_p + indices_len_m;
}
this->indices = malloc(sizeof(uint16_t) * this->num_indices);
return this;
}
/*
* Described in header.
*/
ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t mgf1_type,
chunk_t seed, uint8_t c_bits,
uint16_t N, uint16_t q,
uint32_t indices_len_p,
uint32_t indices_len_m,
bool is_product_form)
{
private_ntru_poly_t *this;
int n, num_indices, index_i = 0;
uint32_t index, limit;
uint8_t *used;
xof_bitspender_t *bitspender;
bitspender = xof_bitspender_create(mgf1_type, seed, TRUE);
if (!bitspender)
{
return NULL;
}
this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form);
used = malloc(N);
limit = N * ((1 << c_bits) / N);
/* generate indices for all polynomials */
for (n = 0; n < this->num_polynomials; n++)
{
memset(used, 0, N);
num_indices = this->indices_len[n].p + this->indices_len[n].m;
/* generate indices for a single polynomial */
while (num_indices)
{
/* generate a random candidate index with a size of c_bits */
do
{
if (!bitspender->get_bits(bitspender, c_bits, &index))
{
bitspender->destroy(bitspender);
destroy(this);
free(used);
return NULL;
}
}
while (index >= limit);
/* form index and check if unique */
index %= N;
if (!used[index])
{
used[index] = 1;
this->indices[index_i++] = index;
num_indices--;
}
}
}
bitspender->destroy(bitspender);
free(used);
return &this->public;
}
/*
* Described in header.
*/
ntru_poly_t *ntru_poly_create_from_data(uint16_t *data, uint16_t N, uint16_t q,
uint32_t indices_len_p,
uint32_t indices_len_m,
bool is_product_form)
{
private_ntru_poly_t *this;
int i;
this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form);
for (i = 0; i < this->num_indices; i++)
{
this->indices[i] = data[i];
}
return &this->public;
}
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_seed);
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_poly_create_from_data);

View File

@ -1,100 +0,0 @@
/*
* Copyright (C) 2014-2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_poly ntru_poly
* @{ @ingroup ntru_p
*/
#ifndef NTRU_POLY_H_
#define NTRU_POLY_H_
typedef struct ntru_poly_t ntru_poly_t;
#include <library.h>
#include <crypto/xofs/xof.h>
/**
* Implements a trinary polynomial storing the indices of non-zero coefficients
*/
struct ntru_poly_t {
/**
* Get the size of the indices array
*
* @return number of indices
*/
size_t (*get_size)(ntru_poly_t *this);
/**
* @return array containing the indices of the non-zero coefficients
*/
uint16_t* (*get_indices)(ntru_poly_t *this);
/**
* @param array array containing all N coefficients of the polynomial
*/
void (*get_array)(ntru_poly_t *this, uint16_t *array);
/**
* Multiply polynomial a with ntru_poly_t object b having sparse coefficients
* to form result polynomial c = a * b
*
* @param a input polynomial a
* @param b output polynomial c
*/
void (*ring_mult)(ntru_poly_t *this, uint16_t *a, uint16_t *c);
/**
* Destroy ntru_poly_t object
*/
void (*destroy)(ntru_poly_t *this);
};
/**
* Create a trits polynomial from a seed using MGF1
*
* @param alg MGF1 algorithm used(XOF_MGF1_SHA1 or XOF_MGF_SHA256)
* @param seed seed used by MGF1 to generate trits from
* @param N ring dimension, number of polynomial coefficients
* @param q large modulus
* @param c_bits number of bits for candidate index
* @param indices_len_p number of indices for +1 coefficients
* @param indices_len_m number of indices for -1 coefficients
* @param is_product_form generate multiple polynomials
*/
ntru_poly_t *ntru_poly_create_from_seed(ext_out_function_t alg, chunk_t seed,
uint8_t c_bits, uint16_t N, uint16_t q,
uint32_t indices_len_p,
uint32_t indices_len_m,
bool is_product_form);
/**
* Create a trits polynomial from an array of indices of non-zero coefficients
*
* @param data array of indices of non-zero coefficients
* @param N ring dimension, number of polynomial coefficients
* @param q large modulus
* @param indices_len_p number of indices for +1 coefficients
* @param indices_len_m number of indices for -1 coefficients
* @param is_product_form generate multiple polynomials
*/
ntru_poly_t *ntru_poly_create_from_data(uint16_t *data, uint16_t N, uint16_t q,
uint32_t indices_len_p,
uint32_t indices_len_m,
bool is_product_form);
#endif /** NTRU_POLY_H_ @}*/

View File

@ -1,883 +0,0 @@
/*
* Copyright (C) 2014-2016 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 "ntru_private_key.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_private_key_t private_ntru_private_key_t;
/**
* Private data of an ntru_private_key_t object.
*/
struct private_ntru_private_key_t {
/**
* Public ntru_private_key_t interface.
*/
ntru_private_key_t public;
/**
* NTRU Parameter Set
*/
const ntru_param_set_t *params;
/**
* Polynomial F which is the private key
*/
ntru_poly_t *privkey;
/**
* Polynomial h which is the public key
*/
uint16_t *pubkey;
/**
* Encoding of the private key
*/
chunk_t encoding;
/**
* Deterministic Random Bit Generator
*/
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->drbg, this->params, this->pubkey);
}
/**
* Generate NTRU encryption private key encoding
*/
static void generate_encoding(private_ntru_private_key_t *this)
{
size_t pubkey_len, privkey_len, privkey_trits_len, privkey_indices_len;
int privkey_pack_type;
uint16_t *indices;
uint8_t *trits;
u_char *enc;
/* compute public key length encoded as packed coefficients */
pubkey_len = (this->params->N * this->params->q_bits + 7) / 8;
/* compute private key length encoded as packed trits coefficients */
privkey_trits_len = (this->params->N + 4) / 5;
/* compute private key length encoded as packed indices */
privkey_indices_len = (this->privkey->get_size(this->privkey) *
this->params->N_bits + 7) / 8;
if (this->params->is_product_form ||
privkey_indices_len <= privkey_trits_len)
{
privkey_pack_type = NTRU_KEY_PACKED_INDICES;
privkey_len = privkey_indices_len;
}
else
{
privkey_pack_type = NTRU_KEY_PACKED_TRITS;
privkey_len = privkey_trits_len;
}
/* allocate memory for private key encoding */
this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len + privkey_len);
enc = this->encoding.ptr;
/* format header and packed public key */
*enc++ = NTRU_PRIVKEY_DEFAULT_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);
enc += pubkey_len;
/* add packed private key */
indices = this->privkey->get_indices(this->privkey);
if (privkey_pack_type == NTRU_KEY_PACKED_TRITS)
{
/* encode private key as packed trits */
trits = malloc(this->params->N);
ntru_indices_2_packed_trits(indices, this->params->dF_r,
this->params->dF_r, this->params->N, trits, enc);
memwipe(trits, this->params->N);
free(trits);
}
else
{
/* encode private key as packed indices */
ntru_elements_2_octets(this->privkey->get_size(this->privkey),
indices, this->params->N_bits, enc);
}
}
METHOD(ntru_private_key_t, get_encoding, chunk_t,
private_ntru_private_key_t *this)
{
return this->encoding;
}
/**
* Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
* a minimum weight.
*
* @param N degree of polynomial
* @param t array of trinary ring elements
* @param min_wt minimum weight
* @return TRUE if minimum weight met or exceeded
*/
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;
for (i = 0; i < N; i++)
{
++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 success;
}
METHOD(ntru_private_key_t, decrypt, bool,
private_ntru_private_key_t *this, chunk_t ciphertext, chunk_t *plaintext)
{
ext_out_function_t alg;
size_t t_len, seed1_len, seed2_len;
uint16_t *t1, *t2, *t = NULL;
uint16_t mod_q_mask, q_mod_p, cmprime_len, cm_len = 0, num_zeros;
uint8_t *Mtrin, *M, *cm, *mask_trits, *ptr;
int16_t m1 = 0;
chunk_t seed = chunk_empty;
ntru_trits_t *mask;
ntru_poly_t *r_poly;
bool msg_rep_good, success = TRUE;
int i;
*plaintext = chunk_empty;
if (ciphertext.len != (this->params->N * this->params->q_bits + 7) / 8)
{
DBG1(DBG_LIB, "wrong NTRU ciphertext length");
return FALSE;
}
/* allocate temporary array t */
t_len = 2 * this->params->N * sizeof(uint16_t);
t = malloc(t_len);
t1 = t;
t2 = t + this->params->N;
Mtrin = (uint8_t *)t1;
M = Mtrin + this->params->N;
/* set MGF1 algorithm type based on security strength */
alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
XOF_MGF1_SHA256;
/* set constants */
mod_q_mask = this->params->q - 1;
q_mod_p = this->params->q % 3;
/* unpack the ciphertext */
ntru_octets_2_elements(ciphertext.len, ciphertext.ptr,
this->params->q_bits, t2);
/* form cm':
* F * e
* A = e * (1 + pF) mod q = e + pFe mod q
* a = A in the range [-q/2, q/2)
* cm' = a mod p
*/
this->privkey->ring_mult(this->privkey, t2, t1);
cmprime_len = this->params->N;
if (this->params->is_product_form)
{
--cmprime_len;
for (i = 0; i < cmprime_len; i++)
{
t1[i] = (t2[i] + 3 * t1[i]) & mod_q_mask;
if (t1[i] >= (this->params->q / 2))
{
t1[i] -= q_mod_p;
}
Mtrin[i] = (uint8_t)(t1[i] % 3);
if (Mtrin[i] == 1)
{
++m1;
}
else if (Mtrin[i] == 2)
{
--m1;
}
}
}
else
{
for (i = 0; i < cmprime_len; i++)
{
t1[i] = (t2[i] + 3 * t1[i]) & mod_q_mask;
if (t1[i] >= (this->params->q / 2))
{
t1[i] -= q_mod_p;
}
Mtrin[i] = (uint8_t)(t1[i] % 3);
}
}
/**
* check that the candidate 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(cmprime_len, Mtrin,
this->params->min_msg_rep_wt);
}
if (!msg_rep_good)
{
DBG1(DBG_LIB, "decryption failed due to insufficient minimum weight");
success = FALSE;
}
/* form cR = e - cm' mod q */
for (i = 0; i < cmprime_len; i++)
{
if (Mtrin[i] == 1)
{
t2[i] = (t2[i] - 1) & mod_q_mask;
}
else if (Mtrin[i] == 2)
{
t2[i] = (t2[i] + 1) & mod_q_mask;
}
}
if (this->params->is_product_form)
{
t2[i] = (t2[i] + m1) & mod_q_mask;
}
/* 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 + this->params->m_len_max;
seed = chunk_alloc(max(seed1_len, seed2_len));
seed.len = seed1_len;
/* form cR mod 4 */
ntru_coeffs_mod4_2_octets(this->params->N, t2, seed.ptr);
/* form mask */
mask = ntru_trits_create(this->params->N, alg, seed);
if (!mask)
{
DBG1(DBG_LIB, "mask creation failed");
success = FALSE;
goto err;
}
mask_trits = mask->get_trits(mask);
/* form cMtrin by subtracting mask from cm', mod p */
for (i = 0; i < cmprime_len; i++)
{
Mtrin[i] -= mask_trits[i];
if (Mtrin[i] >= 3)
{
Mtrin[i] += 3;
}
}
mask->destroy(mask);
if (this->params->is_product_form)
{
/* set the last trit to zero since that's what it was, and
* because it can't be calculated from (cm' - mask) since
* we don't have the correct value for the last cm' trit
*/
Mtrin[i] = 0;
}
/* convert cMtrin to cM (Mtrin to Mbin) */
if (!ntru_trits_2_bits(Mtrin, this->params->N, M))
{
success = FALSE;
goto err;
}
/* skip the random padding */
ptr = M + this->params->sec_strength_len;
/* validate the padded message cM and copy cm to m_buf */
if (this->params->m_len_len == 2)
{
cm_len = (uint16_t)(*ptr++) << 16;
}
cm_len |= (uint16_t)(*ptr++);
if (cm_len > this->params->m_len_max)
{
cm_len = this->params->m_len_max;
DBG1(DBG_LIB, "NTRU message length is larger than maximum length");
success = FALSE;
}
cm = ptr;
ptr += cm_len;
/* check if the remaining padding consists of zeros */
num_zeros = this->params->m_len_max - cm_len + 1;
for (i = 0; i < num_zeros; i++)
{
if (ptr[i] != 0)
{
DBG1(DBG_LIB, "non-zero trailing padding detected");
success = FALSE;
break;
}
}
/* form sData (OID || m || b || hTrunc) */
ptr = seed.ptr;
memcpy(ptr, this->params->oid, 3);
ptr += 3;
memcpy(ptr, cm, cm_len);
ptr += cm_len;
memcpy(ptr, M, 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 = ptr - seed.ptr;
/* generate cr */
DBG2(DBG_LIB, "generate polynomial r");
r_poly = ntru_poly_create_from_seed(alg, 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)
{
success = FALSE;
goto err;
}
/* output plaintext in allocated chunk */
*plaintext = chunk_clone(chunk_create(cm, cm_len));
/* form cR' = h * cr */
r_poly->ring_mult(r_poly, this->pubkey, t1);
r_poly->destroy(r_poly);
/* compare cR' to cR */
for (i = 0; i < this->params->N; i++)
{
if (t[i] != t2[i])
{
DBG1(DBG_LIB, "cR' does not equal cR'");
chunk_clear(plaintext);
success = FALSE;
break;
}
}
memwipe(t, t_len);
err:
/* cleanup */
chunk_clear(&seed);
free(t);
return success;
}
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);
}
/**
* Multiplies ring element (polynomial) "a" by ring element (polynomial) "b"
* to produce ring element (polynomial) "c" in (Z/qZ)[X]/(X^N - 1).
* This is a convolution operation.
*
* Ring element "b" has coefficients in the range [0,N).
*
* This assumes q is 2^r where 8 < r < 16, so that overflow of the sum
* beyond 16 bits does not matter.
*
* @param a polynomial a
* @param b polynomial b
* @param N no. of coefficients in a, b, c
* @param q large modulus
* @param c polynomial c = a * b
*/
static void ring_mult_c(uint16_t *a, uint16_t *b, uint16_t N, uint16_t q,
uint16_t *c)
{
uint16_t *bptr = b;
uint16_t mod_q_mask = q - 1;
int i, k;
/* c[k] = sum(a[i] * b[k-i]) mod q */
memset(c, 0, N * sizeof(uint16_t));
for (k = 0; k < N; k++)
{
i = 0;
while (i <= k)
{
c[k] += a[i++] * *bptr--;
}
bptr += N;
while (i < N)
{
c[k] += a[i++] * *bptr--;
}
c[k] &= mod_q_mask;
++bptr;
}
}
/**
* Finds the inverse of a polynomial a in (Z/2^rZ)[X]/(X^N - 1).
*
* This assumes q is 2^r where 8 < r < 16, so that operations mod q can
* wait until the end, and only 16-bit arrays need to be used.
*
* @param a polynomial a
* @param N no. of coefficients in a
* @param q large modulus
* @param t temporary buffer of size 2N elements
* @param a_inv polynomial for inverse of a
*/
static bool ring_inv(uint16_t *a, uint16_t N, uint16_t q, uint16_t *t,
uint16_t *a_inv)
{
uint8_t *b = (uint8_t *)t;
uint8_t *c = b + N;
uint8_t *f = c + N;
uint8_t *g = (uint8_t *)a_inv;
uint16_t *t2 = t + N;
uint16_t deg_b, deg_c, deg_f, deg_g;
bool done = FALSE;
int i, j, k = 0;
/* form a^-1 in (Z/2Z)[X]/X^N - 1) */
memset(b, 0, 2 * N); /* clear to init b, c */
/* b(X) = 1 */
b[0] = 1;
deg_b = 0;
/* c(X) = 0 (cleared above) */
deg_c = 0;
/* f(X) = a(X) mod 2 */
for (i = 0; i < N; i++)
{
f[i] = (uint8_t)(a[i] & 1);
}
deg_f = N - 1;
/* g(X) = X^N - 1 */
g[0] = 1;
memset(g + 1, 0, N - 1);
g[N] = 1;
deg_g = N;
/* until f(X) = 1 */
while (!done)
{
/* while f[0] = 0, f(X) /= X, c(X) *= X, k++ */
for (i = 0; (i <= deg_f) && (f[i] == 0); ++i);
if (i > deg_f)
{
return FALSE;
}
if (i)
{
f = f + i;
deg_f = deg_f - i;
deg_c = deg_c + i;
for (j = deg_c; j >= i; j--)
{
c[j] = c[j-i];
}
for (j = 0; j < i; j++)
{
c[j] = 0;
}
k = k + i;
}
/* adjust degree of f(X) if the highest coefficients are zero
* Note: f[0] = 1 from above so the loop will terminate.
*/
while (f[deg_f] == 0)
{
--deg_f;
}
/* if f(X) = 1, done
* Note: f[0] = 1 from above, so only check the x term and up
*/
for (i = 1; (i <= deg_f) && (f[i] == 0); ++i);
if (i > deg_f)
{
done = TRUE;
break;
}
/* if deg_f < deg_g, f <-> g, b <-> c */
if (deg_f < deg_g)
{
uint8_t *x;
x = f;
f = g;
g = x;
deg_f ^= deg_g;
deg_g ^= deg_f;
deg_f ^= deg_g;
x = b;
b = c;
c = x;
deg_b ^= deg_c;
deg_c ^= deg_b;
deg_b ^= deg_c;
}
/* f(X) += g(X), b(X) += c(X) */
for (i = 0; i <= deg_g; i++)
{
f[i] ^= g[i];
}
if (deg_c > deg_b)
{
deg_b = deg_c;
}
for (i = 0; i <= deg_c; i++)
{
b[i] ^= c[i];
}
}
/* a^-1 in (Z/2Z)[X]/(X^N - 1) = b(X) shifted left k coefficients */
j = 0;
if (k >= N)
{
k = k - N;
}
for (i = k; i < N; i++)
{
a_inv[j++] = (uint16_t)(b[i]);
}
for (i = 0; i < k; i++)
{
a_inv[j++] = (uint16_t)(b[i]);
}
/* lift a^-1 in (Z/2Z)[X]/(X^N - 1) to a^-1 in (Z/qZ)[X]/(X^N -1) */
for (j = 0; j < 4; ++j) /* assumes 256 < q <= 65536 */
{
/* a^-1 = a^-1 * (2 - a * a^-1) mod q */
memcpy(t2, a_inv, N * sizeof(uint16_t));
ring_mult_c(a, t2, N, q, t);
for (i = 0; i < N; ++i)
{
t[i] = q - t[i];
}
t[0] = t[0] + 2;
ring_mult_c(t2, t, N, q, a_inv);
}
return TRUE;
}
/*
* Described in header.
*/
ntru_private_key_t *ntru_private_key_create(drbg_t *drbg,
const ntru_param_set_t *params)
{
private_ntru_private_key_t *this;
size_t t_len;
uint16_t *t1, *t2, *t = NULL;
uint16_t mod_q_mask;
ext_out_function_t alg;
ntru_poly_t *g_poly;
chunk_t seed;
int i;
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)),
.drbg = drbg->get_ref(drbg),
);
/* set hash algorithm and seed length based on security strength */
alg = (params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
XOF_MGF1_SHA256;
seed =chunk_alloc(params->sec_strength_len + 8);
/* get random seed for generating trinary F as a list of indices */
if (!drbg->generate(drbg, seed.len, seed.ptr))
{
goto err;
}
DBG2(DBG_LIB, "generate polynomial F");
this->privkey = ntru_poly_create_from_seed(alg, seed, params->c_bits,
params->N, params->q,
params->dF_r, params->dF_r,
params->is_product_form);
if (!this->privkey)
{
goto err;
}
/* allocate temporary array t */
t_len = 3 * params->N * sizeof(uint16_t);
t = malloc(t_len);
t1 = t + 2 * params->N;
/* extend sparse private key polynomial f to N array elements */
this->privkey->get_array(this->privkey, t1);
/* set mask for large modulus */
mod_q_mask = params->q - 1;
/* form f = 1 + pF */
for (i = 0; i < params->N; i++)
{
t1[i] = (t1[i] * 3) & mod_q_mask;
}
t1[0] = (t1[0] + 1) & mod_q_mask;
/* use the public key array as a temporary buffer */
t2 = this->pubkey;
/* find f^-1 in (Z/qZ)[X]/(X^N - 1) */
if (!ring_inv(t1, params->N, params->q, t, t2))
{
goto err;
}
/* get random seed for generating trinary g as a list of indices */
if (!drbg->generate(drbg, seed.len, seed.ptr))
{
goto err;
}
DBG2(DBG_LIB, "generate polynomial g");
g_poly = ntru_poly_create_from_seed(alg, seed, params->c_bits,
params->N, params->q, params->dg + 1,
params->dg, FALSE);
if (!g_poly)
{
goto err;
}
/* compute public key polynomial h = p * (f^-1 * g) mod q */
g_poly->ring_mult(g_poly, t2, t2);
g_poly->destroy(g_poly);
for (i = 0; i < params->N; i++)
{
this->pubkey[i] = (t2[i] * 3) & mod_q_mask;
}
/* cleanup temporary storage */
chunk_clear(&seed);
memwipe(t, t_len);
free(t);
/* generate private key encoding */
generate_encoding(this);
return &this->public;
err:
chunk_free(&seed);
free(t);
destroy(this);
return NULL;
}
/*
* Described in header.
*/
ntru_private_key_t *ntru_private_key_create_from_data(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;
const 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

@ -1,93 +0,0 @@
/*
* Copyright (C) 2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_private_key ntru_private_key
* @{ @ingroup ntru_p
*/
#ifndef NTRU_PRIVATE_KEY_H_
#define NTRU_PRIVATE_KEY_H_
typedef struct ntru_private_key_t ntru_private_key_t;
#include "ntru_param_set.h"
#include "ntru_public_key.h"
#include <library.h>
#include <crypto/drbgs/drbg.h>
/**
* Implements an NTRU encryption public/private key pair
*/
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
*
* @return NTRU encryption public key (must be freed after use)
*/
ntru_public_key_t* (*get_public_key)(ntru_private_key_t *this);
/**
* Returns the packed encoding of the NTRU encryption private key
*
* @return Packed encoding of NTRU encryption private key
*/
chunk_t (*get_encoding)(ntru_private_key_t *this);
/**
* Decrypts an NTRU ciphertext
*
* @param ciphertext NTRU Ciphertext
* @param plaintext Plaintext
* @return TRUE if decryption was successful
*/
bool (*decrypt)(ntru_private_key_t *this, chunk_t ciphertext,
chunk_t *plaintext);
/**
* Destroy ntru_private_key_t object
*/
void (*destroy)(ntru_private_key_t *this);
};
/**
* Creates an NTRU encryption public/private key pair using a NIST DRBG
*
* @param drbg Digital Random Bit Generator used for key generation
* @param params NTRU encryption parameter set to be used
*/
ntru_private_key_t *ntru_private_key_create(drbg_t *drbg,
const 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(drbg_t *drbg,
chunk_t data);
#endif /** NTRU_PRIVATE_KEY_H_ @}*/

View File

@ -1,406 +0,0 @@
/*
* Copyright (C) 2014-2016 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 "ntru_public_key.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;
/**
* Private data of an ntru_public_key_t object.
*/
struct private_ntru_public_key_t {
/**
* Public ntru_public_key_t interface.
*/
ntru_public_key_t public;
/**
* NTRU Parameter Set
*/
const ntru_param_set_t *params;
/**
* Polynomial h which is the public key
*/
uint16_t *pubkey;
/**
* Encoding of the public key
*/
chunk_t encoding;
/**
* Deterministic Random Bit Generator
*/
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)
{
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)
{
ext_out_function_t alg;
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 = 0;
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 */
alg = (this->params->sec_strength_len <= 20) ? XOF_MGF1_SHA1 :
XOF_MGF1_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, 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(alg, 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, alg, 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(drbg_t *drbg,
const ntru_param_set_t *params,
uint16_t *pubkey)
{
private_ntru_public_key_t *this;
int i;
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(drbg_t *drbg,
chunk_t data)
{
private_ntru_public_key_t *this;
size_t header_len, pubkey_packed_len;
const 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

@ -1,88 +0,0 @@
/*
* Copyright (C) 2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_public_key ntru_public_key
* @{ @ingroup ntru_p
*/
#ifndef NTRU_PUBLIC_KEY_H_
#define NTRU_PUBLIC_KEY_H_
typedef struct ntru_public_key_t ntru_public_key_t;
#include "ntru_param_set.h"
#include <library.h>
#include <crypto/drbgs/drbg.h>
/**
* Implements an NTRU encryption public key
*/
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
*
* @return Packed encoding of 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
*/
void (*destroy)(ntru_public_key_t *this);
};
/**
* 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(drbg_t *drbg,
const 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(drbg_t *drbg,
chunk_t data);
#endif /** NTRU_PUBLIC_KEY_H_ @}*/

View File

@ -1,122 +0,0 @@
/*
* Copyright (C) 2013-2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "ntru_trits.h"
#include "ntru_convert.h"
#include <crypto/xofs/xof_bitspender.h>
#include <utils/debug.h>
#include <utils/test.h>
typedef struct private_ntru_trits_t private_ntru_trits_t;
/**
* Private data of an ntru_trits_t object.
*/
struct private_ntru_trits_t {
/**
* Public ntru_trits_t interface.
*/
ntru_trits_t public;
/**
* Size of the trits array
*/
size_t trits_len;
/**
* Array containing a trit per octet
*/
uint8_t *trits;
};
METHOD(ntru_trits_t, get_size, size_t,
private_ntru_trits_t *this)
{
return this->trits_len;
}
METHOD(ntru_trits_t, get_trits, uint8_t*,
private_ntru_trits_t *this)
{
return this->trits;
}
METHOD(ntru_trits_t, destroy, void,
private_ntru_trits_t *this)
{
memwipe(this->trits, this->trits_len);
free(this->trits);
free(this);
}
/*
* Described in header.
*/
ntru_trits_t *ntru_trits_create(size_t len, ext_out_function_t alg,
chunk_t seed)
{
private_ntru_trits_t *this;
uint8_t octet, buf[5], *trits;
size_t trits_needed;
xof_bitspender_t *bitspender;
bitspender = xof_bitspender_create(alg, seed, TRUE);
if (!bitspender)
{
return NULL;
}
INIT(this,
.public = {
.get_size = _get_size,
.get_trits = _get_trits,
.destroy = _destroy,
},
.trits_len = len,
.trits = malloc(len),
);
trits = this->trits;
trits_needed = this->trits_len;
while (trits_needed > 0)
{
if (!bitspender->get_byte(bitspender, &octet))
{
bitspender->destroy(bitspender);
destroy(this);
return NULL;
}
if (octet < 243) /* 243 = 3^5 */
{
ntru_octet_2_trits(octet, (trits_needed < 5) ? buf : trits);
if (trits_needed < 5)
{
memcpy(trits, buf, trits_needed);
break;
}
trits += 5;
trits_needed -= 5;
}
}
bitspender->destroy(bitspender);
return &this->public;
}
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create);

View File

@ -1,63 +0,0 @@
/*
* Copyright (C) 2013-2016 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup ntru_trits ntru_trits
* @{ @ingroup ntru_p
*/
#ifndef NTRU_TRITS_H_
#define NTRU_TRITS_H_
typedef struct ntru_trits_t ntru_trits_t;
#include <library.h>
#include <crypto/xofs/xof.h>
/**
* Implements an array of trinary elements (trits)
*/
struct ntru_trits_t {
/**
* Get the size of the trits array
*
* @return number of trinary elements
*/
size_t (*get_size)(ntru_trits_t *this);
/**
* @return octet array containing a trit per octet
*/
uint8_t* (*get_trits)(ntru_trits_t *this);
/**
* Destroy ntru_trits_t object
*/
void (*destroy)(ntru_trits_t *this);
};
/**
* Create a trits array from a seed using MGF1 with a base hash function
*
* @param size size of the trits array
* @param alg MGF1 algorithm used (XOF_MGF1_SHA1 or XOF_MGF_SHA256)
* @param seed seed used by MGF1 to generate trits from
*/
ntru_trits_t *ntru_trits_create(size_t size, ext_out_function_t alg,
chunk_t seed);
#endif /** NTRU_TRITS_H_ @}*/

View File

@ -56,7 +56,6 @@ libstrongswan_tests_SOURCES = tests.h tests.c \
suites/test_rng_tester.c \
suites/test_mgf1.c \
suites/test_prf_plus.c \
suites/test_ntru.c \
suites/test_ed25519.c \
suites/test_ed448.c \
suites/test_signature_params.c

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,6 @@ TEST_SUITE(rng_tester_suite_create)
TEST_SUITE_DEPEND(mgf1_sha1_suite_create, XOF, XOF_MGF1_SHA1)
TEST_SUITE_DEPEND(mgf1_sha256_suite_create, XOF, XOF_MGF1_SHA256)
TEST_SUITE_DEPEND(prf_plus_suite_create, PRF, PRF_HMAC_SHA2_256)
TEST_SUITE_DEPEND(ntru_suite_create, KE, NTRU_112_BIT)
TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://")
TEST_SUITE_DEPEND(ed25519_suite_create, PRIVKEY_GEN, KEY_ED25519)
TEST_SUITE_DEPEND(ed448_suite_create, PRIVKEY_GEN, KEY_ED448)

View File

@ -99,7 +99,6 @@ CONFIG_OPTS = \
--enable-libipsec \
--enable-kernel-libipsec \
--enable-tkm \
--enable-ntru \
--enable-lookip \
--enable-sha3 \
--enable-frodo \

View File

@ -1,5 +1,5 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
}

View File

@ -1,5 +1,5 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
}

View File

@ -1,7 +1,7 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm stroke kernel-netlink socket-default updown
integrity_test = yes

View File

@ -5,5 +5,5 @@ swanctl {
}
charon-systemd {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
}

View File

@ -5,5 +5,5 @@ swanctl {
}
charon-systemd {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
}

View File

@ -5,7 +5,7 @@ swanctl {
}
charon-systemd {
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
integrity_test = yes

View File

@ -1,5 +1,5 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 ntru pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
}

View File

@ -1,5 +1,5 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 ntru pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
}

View File

@ -1,7 +1,7 @@
# /etc/strongswan.conf - strongSwan configuration file
charon {
load = random drbg nonce test-vectors aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 ntru pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
load = random drbg nonce test-vectors aes des sha1 sha2 sha3 md5 chapoly mgf1 curve25519 pem pkcs1 pkcs8 gmp x509 curl revocation hmac xcbc cmac ctr ccm gcm stroke kernel-netlink socket-default updown
integrity_test = yes
crypto_test {

View File

@ -1,9 +0,0 @@
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.
The authentication is based on <b>X.509 certificates</b>.
<p/>
Upon the successful establishment of the IPsec tunnel, the updown script 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

@ -1,5 +0,0 @@
moon::swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.1 local-port=500 local-id=moon.strongswan.org remote-host=192.168.0.2 remote-port=500 remote-id=sun.strongswan.org initiator=yes.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=NTRU_128.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.1.0.0/16] remote-ts=\[10.2.0.0/16]::YES
sun:: swanctl --list-sas --raw 2> /dev/null::gw-gw.*version=2 state=ESTABLISHED local-host=192.168.0.2 local-port=500 local-id=sun.strongswan.org remote-host=192.168.0.1 remote-port=500 remote-id=moon.strongswan.org.*encr-alg=AES_CBC encr-keysize=128 integ-alg=HMAC_SHA2_256_128 prf-alg=PRF_HMAC_SHA2_256 dh-group=NTRU_128.*child-sas.*net-net.*state=INSTALLED mode=TUNNEL.*ESP.*encr-alg=AES_GCM_16 encr-keysize=128.*local-ts=\[10.2.0.0/16] remote-ts=\[10.1.0.0/16]::YES
alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_.eq=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

@ -1,24 +0,0 @@
# /etc/strongswan.conf - strongSwan configuration file
swanctl {
load = pem pkcs1 x509 revocation constraints pubkey openssl random
}
charon-systemd {
load = random drbg nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl mgf1 ntru revocation hmac vici kernel-netlink socket-default updown
multiple_authentication = no
send_vendor_id = yes
syslog {
daemon {
ike = 4
lib = 4
}
}
plugins {
ntru {
parameter_set = x9_98_bandwidth
}
}
}

View File

@ -1,29 +0,0 @@
connections {
gw-gw {
local_addrs = 192.168.0.1
remote_addrs = 192.168.0.2
local {
auth = pubkey
certs = moonCert.pem
id = moon.strongswan.org
}
remote {
auth = pubkey
id = sun.strongswan.org
}
children {
net-net {
local_ts = 10.1.0.0/16
remote_ts = 10.2.0.0/16
updown = /usr/local/libexec/ipsec/_updown iptables
esp_proposals = aes128gcm128-ntru128
}
}
version = 2
mobike = no
proposals = aes128-sha256-ntru128
}
}

View File

@ -1,24 +0,0 @@
# /etc/strongswan.conf - strongSwan configuration file
swanctl {
load = pem pkcs1 x509 revocation constraints pubkey openssl random
}
charon-systemd {
load = random drbg nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl mgf1 ntru revocation hmac vici kernel-netlink socket-default updown
multiple_authentication = no
send_vendor_id = yes
syslog {
daemon {
ike = 4
lib = 4
}
}
plugins {
ntru {
parameter_set = x9_98_bandwidth
}
}
}

View File

@ -1,29 +0,0 @@
connections {
gw-gw {
local_addrs = 192.168.0.2
remote_addrs = 192.168.0.1
local {
auth = pubkey
certs = sunCert.pem
id = sun.strongswan.org
}
remote {
auth = pubkey
id = moon.strongswan.org
}
children {
net-net {
local_ts = 10.2.0.0/16
remote_ts = 10.1.0.0/16
updown = /usr/local/libexec/ipsec/_updown iptables
esp_proposals = aes128gcm128-ntru128
}
}
version = 2
mobike = no
proposals = aes128-sha256-ntru128
}
}

View File

@ -1,4 +0,0 @@
moon::systemctl stop strongswan
sun::systemctl stop strongswan
moon::iptables-restore < /etc/iptables.flush
sun::iptables-restore < /etc/iptables.flush

View File

@ -1,7 +0,0 @@
moon::iptables-restore < /etc/iptables.rules
sun::iptables-restore < /etc/iptables.rules
moon::systemctl start strongswan
sun::systemctl start strongswan
moon::expect-connection gw-gw
sun::expect-connection gw-gw
moon::swanctl --initiate --child net-net 2> /dev/null

View File

@ -1,25 +0,0 @@
#!/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"
# charon controlled by swanctl
#
SWANCTL=1

View File

@ -5,5 +5,5 @@ swanctl {
}
charon-systemd {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
}

View File

@ -5,5 +5,5 @@ swanctl {
}
charon-systemd {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
}

View File

@ -5,7 +5,7 @@ swanctl {
}
charon-systemd {
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce test-vectors aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
integrity_test = yes

View File

@ -5,5 +5,5 @@ swanctl {
}
charon-systemd {
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 ntru x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
load = random drbg nonce aes des md5 sha1 sha2 sha3 chapoly pem pkcs1 pkcs8 curve25519 gmp mgf1 x509 curl revocation hmac xcbc ctr ccm gcm vici kernel-netlink socket-default updown
}

View File

@ -19,4 +19,4 @@ conn home
right=PH_IP_MOON
rightsubnet=10.1.0.0/16
rightid=@moon.strongswan.org
auto=add
auto=add