mirror of
https://github.com/strongswan/strongswan.git
synced 2025-12-07 00:00:13 -05:00
Completed integration of ntru_crypto library into ntru plugin
This commit is contained in:
parent
b517912848
commit
22e1aa51f9
@ -12,6 +12,7 @@ endif
|
|||||||
|
|
||||||
libstrongswan_ntru_la_SOURCES = \
|
libstrongswan_ntru_la_SOURCES = \
|
||||||
ntru_plugin.h ntru_plugin.c \
|
ntru_plugin.h ntru_plugin.c \
|
||||||
|
ntru_convert.h ntru_convert.c \
|
||||||
ntru_drbg.h ntru_drbg.c \
|
ntru_drbg.h ntru_drbg.c \
|
||||||
ntru_ke.h ntru_ke.c \
|
ntru_ke.h ntru_ke.c \
|
||||||
ntru_mgf1.h ntru_mgf1.c \
|
ntru_mgf1.h ntru_mgf1.c \
|
||||||
@ -19,15 +20,7 @@ libstrongswan_ntru_la_SOURCES = \
|
|||||||
ntru_poly.h ntru_poly.c \
|
ntru_poly.h ntru_poly.c \
|
||||||
ntru_public_key.h ntru_public_key.c \
|
ntru_public_key.h ntru_public_key.c \
|
||||||
ntru_private_key.h ntru_private_key.c \
|
ntru_private_key.h ntru_private_key.c \
|
||||||
ntru_trits.h ntru_trits.c \
|
ntru_trits.h ntru_trits.c
|
||||||
ntru_crypto/ntru_crypto.h \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_convert.h \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_convert.c \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_encrypt.c \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_encrypt_key.h \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_encrypt_key.c \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_poly.h \
|
|
||||||
ntru_crypto/ntru_crypto_ntru_poly.c
|
|
||||||
|
|
||||||
libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
|
libstrongswan_ntru_la_LDFLAGS = -module -avoid-version
|
||||||
|
|
||||||
|
|||||||
452
src/libstrongswan/plugins/ntru/ntru_convert.c
Normal file
452
src/libstrongswan/plugins/ntru/ntru_convert.c
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Andreas Steffen
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2013 Security Innovation
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ntru_convert.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3-bit to 2-trit conversion tables: 2 represents -1
|
||||||
|
*/
|
||||||
|
static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2};
|
||||||
|
static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits, uint8_t *trits)
|
||||||
|
{
|
||||||
|
uint32_t bits24, bits3, shift;
|
||||||
|
|
||||||
|
while (num_trits >= 16)
|
||||||
|
{
|
||||||
|
/* get next three octets */
|
||||||
|
bits24 = ((uint32_t)(*octets++)) << 16;
|
||||||
|
bits24 |= ((uint32_t)(*octets++)) << 8;
|
||||||
|
bits24 |= (uint32_t)(*octets++);
|
||||||
|
|
||||||
|
/* for each 3 bits in the three octets, output 2 trits */
|
||||||
|
bits3 = (bits24 >> 21) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 18) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 15) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 12) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 9) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 6) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = (bits24 >> 3) & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
bits3 = bits24 & 0x7;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
|
||||||
|
num_trits -= 16;
|
||||||
|
}
|
||||||
|
if (num_trits == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get three octets */
|
||||||
|
bits24 = ((uint32_t)(*octets++)) << 16;
|
||||||
|
bits24 |= ((uint32_t)(*octets++)) << 8;
|
||||||
|
bits24 |= (uint32_t)(*octets++);
|
||||||
|
|
||||||
|
shift = 21;
|
||||||
|
while (num_trits)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* for each 3 bits in the three octets, output up to 2 trits
|
||||||
|
* until all trits needed are produced
|
||||||
|
*/
|
||||||
|
bits3 = (bits24 >> shift) & 0x7;
|
||||||
|
shift -= 3;
|
||||||
|
*trits++ = bits_2_trit1[bits3];
|
||||||
|
if (--num_trits)
|
||||||
|
{
|
||||||
|
*trits++ = bits_2_trit2[bits3];
|
||||||
|
--num_trits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits, uint8_t *octets)
|
||||||
|
{
|
||||||
|
bool all_trits_valid = TRUE;
|
||||||
|
uint32_t bits24, bits3, shift;
|
||||||
|
|
||||||
|
while (num_trits >= 16)
|
||||||
|
{
|
||||||
|
/* convert each 2 trits to 3 bits and pack */
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 = (bits3 << 21);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 18);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 15);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 12);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 9);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 6);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << 3);
|
||||||
|
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
bits3 += *trits++;
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= bits3;
|
||||||
|
|
||||||
|
num_trits -= 16;
|
||||||
|
|
||||||
|
/* output three octets */
|
||||||
|
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
||||||
|
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
||||||
|
*octets++ = (uint8_t)(bits24 & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
bits24 = 0;
|
||||||
|
shift = 21;
|
||||||
|
while (num_trits)
|
||||||
|
{
|
||||||
|
/* convert each 2 trits to 3 bits and pack */
|
||||||
|
bits3 = *trits++ * 3;
|
||||||
|
if (--num_trits)
|
||||||
|
{
|
||||||
|
bits3 += *trits++;
|
||||||
|
--num_trits;
|
||||||
|
}
|
||||||
|
if (bits3 > 7)
|
||||||
|
{
|
||||||
|
bits3 = 7;
|
||||||
|
all_trits_valid = FALSE;
|
||||||
|
}
|
||||||
|
bits24 |= (bits3 << shift);
|
||||||
|
shift -= 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* output three octets */
|
||||||
|
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
||||||
|
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
||||||
|
*octets++ = (uint8_t)(bits24 & 0xff);
|
||||||
|
|
||||||
|
return all_trits_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs, uint8_t *octets)
|
||||||
|
{
|
||||||
|
uint8_t bits2;
|
||||||
|
int shift, i;
|
||||||
|
|
||||||
|
*octets = 0;
|
||||||
|
shift = 6;
|
||||||
|
for (i = 0; i < num_coeffs; i++)
|
||||||
|
{
|
||||||
|
bits2 = (uint8_t)(coeffs[i] & 0x3);
|
||||||
|
*octets |= bits2 << shift;
|
||||||
|
shift -= 2;
|
||||||
|
if (shift < 0)
|
||||||
|
{
|
||||||
|
++octets;
|
||||||
|
*octets = 0;
|
||||||
|
shift = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*octet = 0;
|
||||||
|
for (i = 4; i >= 0; i--)
|
||||||
|
{
|
||||||
|
*octet = (*octet * 3) + trits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_octet_2_trits(uint8_t octet, uint8_t *trits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
trits[i] = octet % 3;
|
||||||
|
octet = (octet - trits[i]) / 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
uint8_t trit = plus1 ? 1 : 2;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < in_len; i++)
|
||||||
|
{
|
||||||
|
out[in[i]] = trit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits,
|
||||||
|
uint16_t *indices_plus1,
|
||||||
|
uint16_t *indices_minus1)
|
||||||
|
{
|
||||||
|
uint8_t trits[5];
|
||||||
|
uint16_t i = 0;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
while (num_trits >= 5)
|
||||||
|
{
|
||||||
|
ntru_octet_2_trits(*in++, trits);
|
||||||
|
num_trits -= 5;
|
||||||
|
for (j = 0; j < 5; j++, i++)
|
||||||
|
{
|
||||||
|
if (trits[j] == 1)
|
||||||
|
{
|
||||||
|
*indices_plus1 = i;
|
||||||
|
++indices_plus1;
|
||||||
|
}
|
||||||
|
else if (trits[j] == 2)
|
||||||
|
{
|
||||||
|
*indices_minus1 = i;
|
||||||
|
++indices_minus1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num_trits)
|
||||||
|
{
|
||||||
|
ntru_octet_2_trits(*in, trits);
|
||||||
|
for (j = 0; num_trits && (j < 5); j++, i++)
|
||||||
|
{
|
||||||
|
if (trits[j] == 1)
|
||||||
|
{
|
||||||
|
*indices_plus1 = i;
|
||||||
|
++indices_plus1;
|
||||||
|
}
|
||||||
|
else if (trits[j] == 2)
|
||||||
|
{
|
||||||
|
*indices_minus1 = i;
|
||||||
|
++indices_minus1;
|
||||||
|
}
|
||||||
|
--num_trits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1,
|
||||||
|
uint16_t num_minus1, uint16_t num_trits,
|
||||||
|
uint8_t *buf, uint8_t *out)
|
||||||
|
{
|
||||||
|
/* convert indices to an array of trits */
|
||||||
|
memset(buf, 0, num_trits);
|
||||||
|
ntru_indices_2_trits(num_plus1, indices, TRUE, buf);
|
||||||
|
ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf);
|
||||||
|
|
||||||
|
/* pack the array of trits */
|
||||||
|
while (num_trits >= 5)
|
||||||
|
{
|
||||||
|
ntru_trits_2_octet(buf, out);
|
||||||
|
num_trits -= 5;
|
||||||
|
buf += 5;
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
if (num_trits)
|
||||||
|
{
|
||||||
|
uint8_t trits[5];
|
||||||
|
|
||||||
|
memcpy(trits, buf, num_trits);
|
||||||
|
memset(trits + num_trits, 0, sizeof(trits) - num_trits);
|
||||||
|
ntru_trits_2_octet(trits, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits,
|
||||||
|
uint8_t *out)
|
||||||
|
{
|
||||||
|
uint16_t temp;
|
||||||
|
int shift, i;
|
||||||
|
|
||||||
|
/* pack */
|
||||||
|
temp = 0;
|
||||||
|
shift = n_bits - 8;
|
||||||
|
i = 0;
|
||||||
|
while (i < in_len)
|
||||||
|
{
|
||||||
|
/* add bits to temp to fill an octet and output the octet */
|
||||||
|
temp |= in[i] >> shift;
|
||||||
|
*out++ = (uint8_t)(temp & 0xff);
|
||||||
|
shift = 8 - shift;
|
||||||
|
if (shift < 1)
|
||||||
|
{
|
||||||
|
/* next full octet is in current input word */
|
||||||
|
shift += n_bits;
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* put remaining bits of input word in temp as partial octet,
|
||||||
|
* and increment index to next input word
|
||||||
|
*/
|
||||||
|
temp = in[i] << (uint16_t)shift;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
shift = n_bits - shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* output any bits remaining in last input word */
|
||||||
|
if (shift != n_bits - 8)
|
||||||
|
{
|
||||||
|
*out++ = (uint8_t)(temp & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits,
|
||||||
|
uint16_t *out)
|
||||||
|
{
|
||||||
|
uint16_t temp;
|
||||||
|
uint16_t mask = (1 << n_bits) - 1;
|
||||||
|
int shift, i;
|
||||||
|
|
||||||
|
/* unpack */
|
||||||
|
temp = 0;
|
||||||
|
shift = n_bits;
|
||||||
|
i = 0;
|
||||||
|
while (i < in_len)
|
||||||
|
{
|
||||||
|
shift = 8 - shift;
|
||||||
|
if (shift < 0)
|
||||||
|
{
|
||||||
|
/* the current octet will not fill the current element */
|
||||||
|
shift += n_bits;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* add bits from the current octet to fill the current element and
|
||||||
|
* output the element
|
||||||
|
*/
|
||||||
|
temp |= ((uint16_t)in[i]) >> shift;
|
||||||
|
*out++ = temp & mask;
|
||||||
|
temp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the remaining bits of the current octet to start an element */
|
||||||
|
shift = n_bits - shift;
|
||||||
|
temp |= ((uint16_t)in[i]) << shift;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
147
src/libstrongswan/plugins/ntru/ntru_convert.h
Normal file
147
src/libstrongswan/plugins/ntru/ntru_convert.h
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Andreas Steffen
|
||||||
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2013 Security Innovation
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup ntru_convert ntru_convert
|
||||||
|
* @{ @ingroup ntru_p
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NTRU_CONVERT_H_
|
||||||
|
#define NTRU_CONVERT_H_
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each 3 bits in an array of octets is converted to 2 trits in an array
|
||||||
|
* of trits.
|
||||||
|
*
|
||||||
|
* @param octets pointer to array of octets
|
||||||
|
* @param num_trits number of trits to produce
|
||||||
|
* @param trits address for array of trits
|
||||||
|
*/
|
||||||
|
void ntru_bits_2_trits(uint8_t const *octets, uint16_t num_trits,
|
||||||
|
uint8_t *trits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Each 2 trits in an array of trits is converted to 3 bits, and the bits
|
||||||
|
* are packed in an array of octets. A multiple of 3 octets is output.
|
||||||
|
* Any bits in the final octets not derived from trits are zero.
|
||||||
|
*
|
||||||
|
* @param trits pointer to array of trits
|
||||||
|
* @param num_trits number of trits to convert
|
||||||
|
* @param octets address for array of octets
|
||||||
|
* @return TRUE if all trits were valid
|
||||||
|
* FALSE if invalid trits were found
|
||||||
|
*/
|
||||||
|
bool ntru_trits_2_bits(uint8_t const *trits, uint32_t num_trits,
|
||||||
|
uint8_t *octets);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes an array of coefficients mod 4 and packs the results into an
|
||||||
|
* octet string.
|
||||||
|
*
|
||||||
|
* @param num_coeffs number of coefficients
|
||||||
|
* @param coeffs pointer to coefficients
|
||||||
|
* @param octets address for octets
|
||||||
|
*/
|
||||||
|
void ntru_coeffs_mod4_2_octets(uint16_t num_coeffs, uint16_t const *coeffs,
|
||||||
|
uint8_t *octets);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
|
||||||
|
*
|
||||||
|
* @param trits pointer to trits
|
||||||
|
* @param octet address for octet
|
||||||
|
*/
|
||||||
|
void ntru_trits_2_octet(uint8_t const *trits, uint8_t *octet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
|
||||||
|
*
|
||||||
|
* @param octet octet to be unpacked
|
||||||
|
* @param trits address for trits
|
||||||
|
*/
|
||||||
|
void ntru_octet_2_trits(uint8_t octet, uint8_t *trits);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Converts a list of the nonzero indices of a polynomial into an array of
|
||||||
|
* trits.
|
||||||
|
*
|
||||||
|
* @param in_len no. of indices
|
||||||
|
* @param in pointer to list of indices
|
||||||
|
* @param plus1 if list is +1 coefficients
|
||||||
|
* @param out address of output polynomial
|
||||||
|
*/
|
||||||
|
void ntru_indices_2_trits(uint16_t in_len, uint16_t const *in, bool plus1,
|
||||||
|
uint8_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpacks an array of N trits and creates a list of array indices
|
||||||
|
* corresponding to trits = +1, and list of array indices corresponding to
|
||||||
|
* trits = -1.
|
||||||
|
*
|
||||||
|
* @param in pointer to packed-trit octets
|
||||||
|
* @param num_trits no. of packed trits
|
||||||
|
* @param indices_plus1 address for indices of +1 trits
|
||||||
|
* @param indices_minus1 address for indices of -1 trits
|
||||||
|
*/
|
||||||
|
void ntru_packed_trits_2_indices(uint8_t const *in, uint16_t num_trits,
|
||||||
|
uint16_t *indices_plus1,
|
||||||
|
uint16_t *indices_minus1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a list of array indices corresponding to elements whose values
|
||||||
|
* are +1 or -1, and packs the N-element array of trits described by these
|
||||||
|
* lists into octets, 5 trits per octet.
|
||||||
|
*
|
||||||
|
* @param indices pointer to indices
|
||||||
|
* @param num_plus1 no. of indices for +1 trits
|
||||||
|
* @param num_minus1 no. of indices for -1 trits
|
||||||
|
* @param num_trits N, no. of trits in array
|
||||||
|
* @param buf temp buf, N octets
|
||||||
|
* @param out address for packed octet
|
||||||
|
*/
|
||||||
|
void ntru_indices_2_packed_trits(uint16_t const *indices, uint16_t num_plus1,
|
||||||
|
uint16_t num_minus1, uint16_t num_trits,
|
||||||
|
uint8_t *buf, uint8_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packs an array of n-bit elements into an array of
|
||||||
|
* ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
|
||||||
|
*
|
||||||
|
* @param in_len no. of elements to be packed
|
||||||
|
* @param in ptr to elements to be packed
|
||||||
|
* @param n_bits no. of bits in input element
|
||||||
|
* @param out addr for output octets
|
||||||
|
*/
|
||||||
|
void ntru_elements_2_octets(uint16_t in_len, uint16_t const *in, uint8_t n_bits,
|
||||||
|
uint8_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
||||||
|
* n-bit elements, 8 < n < 16. Any extra bits are discarded.
|
||||||
|
*
|
||||||
|
* @param in_len no. of octets to be unpacked
|
||||||
|
* @param in ptr to octets to be unpacked
|
||||||
|
* @param n_bits no. of bits in output element
|
||||||
|
* @param out addr for output elements
|
||||||
|
*/
|
||||||
|
void ntru_octets_2_elements(uint16_t in_len, uint8_t const *in, uint8_t n_bits,
|
||||||
|
uint16_t *out);
|
||||||
|
|
||||||
|
#endif /** NTRU_CONVERT_H_ @}*/
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto.h is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto.h
|
|
||||||
*
|
|
||||||
* Contents: Public header file for NTRUEncrypt.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef NTRU_CRYPTO_H
|
|
||||||
#define NTRU_CRYPTO_H
|
|
||||||
|
|
||||||
#include <library.h>
|
|
||||||
|
|
||||||
#include "ntru_param_set.h"
|
|
||||||
#include "ntru_drbg.h"
|
|
||||||
|
|
||||||
#if !defined( NTRUCALL )
|
|
||||||
#if !defined(WIN32) || defined (NTRUCRYPTO_STATIC)
|
|
||||||
// Linux, or a Win32 static library
|
|
||||||
#define NTRUCALL extern uint32_t
|
|
||||||
#elif defined (NTRUCRYPTO_EXPORTS)
|
|
||||||
// Win32 DLL build
|
|
||||||
#define NTRUCALL extern __declspec(dllexport) uint32_t
|
|
||||||
#else
|
|
||||||
// Win32 DLL import
|
|
||||||
#define NTRUCALL extern __declspec(dllimport) uint32_t
|
|
||||||
#endif
|
|
||||||
#endif /* NTRUCALL */
|
|
||||||
|
|
||||||
/* error codes */
|
|
||||||
|
|
||||||
#define NTRU_OK 0
|
|
||||||
#define NTRU_FAIL 1
|
|
||||||
#define NTRU_BAD_PARAMETER 2
|
|
||||||
#define NTRU_BAD_LENGTH 3
|
|
||||||
#define NTRU_BUFFER_TOO_SMALL 4
|
|
||||||
#define NTRU_INVALID_PARAMETER_SET 5
|
|
||||||
#define NTRU_BAD_PUBLIC_KEY 6
|
|
||||||
#define NTRU_BAD_PRIVATE_KEY 7
|
|
||||||
#define NTRU_OUT_OF_MEMORY 8
|
|
||||||
#define NTRU_BAD_ENCODING 9
|
|
||||||
#define NTRU_OID_NOT_RECOGNIZED 10
|
|
||||||
#define NTRU_DRBG_FAIL 11
|
|
||||||
#define NTRU_MGF1_FAIL 12
|
|
||||||
|
|
||||||
/* function declarations */
|
|
||||||
|
|
||||||
/* ntru_crypto_ntru_encrypt
|
|
||||||
*
|
|
||||||
* Implements NTRU encryption (SVES) for the parameter set specified in
|
|
||||||
* the public key blob.
|
|
||||||
*
|
|
||||||
* Before invoking this function, a DRBG must be instantiated using
|
|
||||||
* ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
|
|
||||||
* instantiation the requested security strength must be at least as large
|
|
||||||
* as the security strength of the NTRU parameter set being used.
|
|
||||||
* Failure to instantiate the DRBG with the proper security strength will
|
|
||||||
* result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
|
|
||||||
*
|
|
||||||
* The required minimum size of the output ciphertext buffer (ct) may be
|
|
||||||
* queried by invoking this function with ct = NULL. In this case, no
|
|
||||||
* encryption is performed, NTRU_OK is returned, and the required minimum
|
|
||||||
* size for ct is returned in ct_len.
|
|
||||||
*
|
|
||||||
* When ct != NULL, at invocation *ct_len must be the size of the ct buffer.
|
|
||||||
* Upon return it is the actual size of the ciphertext.
|
|
||||||
*
|
|
||||||
* Returns NTRU_OK if successful.
|
|
||||||
* Returns NTRU_DRBG_FAIL if the DRBG handle is invalid.
|
|
||||||
* Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
|
|
||||||
* Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is
|
|
||||||
* zero, or if pt_len exceeds the maximum plaintext length for the parameter set.
|
|
||||||
* Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid
|
|
||||||
* (unknown format, corrupt, bad length).
|
|
||||||
* Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
|
|
||||||
* Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
NTRUCALL
|
|
||||||
ntru_crypto_ntru_encrypt(
|
|
||||||
ntru_drbg_t *drbg , /* in - handle for DRBG */
|
|
||||||
uint16_t pubkey_blob_len, /* in - no. of octets in public key
|
|
||||||
blob */
|
|
||||||
uint8_t const *pubkey_blob, /* in - pointer to public key */
|
|
||||||
uint16_t pt_len, /* in - no. of octets in plaintext */
|
|
||||||
uint8_t const *pt, /* in - pointer to plaintext */
|
|
||||||
uint16_t *ct_len, /* in/out - no. of octets in ct, addr for
|
|
||||||
no. of octets in ciphertext */
|
|
||||||
uint8_t *ct); /* out - address for ciphertext */
|
|
||||||
|
|
||||||
#endif /* NTRU_CRYPTO_H */
|
|
||||||
@ -1,581 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_convert.c is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto_ntru_convert.c
|
|
||||||
*
|
|
||||||
* Contents: Conversion routines for NTRUEncrypt, including packing, unpacking,
|
|
||||||
* and others.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "ntru_crypto_ntru_convert.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* 3-bit to 2-trit conversion tables: 2 represents -1 */
|
|
||||||
|
|
||||||
static uint8_t const bits_2_trit1[] = {0, 0, 0, 1, 1, 1, 2, 2};
|
|
||||||
static uint8_t const bits_2_trit2[] = {0, 1, 2, 0, 1, 2, 0, 1};
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_bits_2_trits
|
|
||||||
*
|
|
||||||
* Each 3 bits in an array of octets is converted to 2 trits in an array
|
|
||||||
* of trits.
|
|
||||||
*
|
|
||||||
* The octet array may overlap the end of the trit array.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_bits_2_trits(
|
|
||||||
uint8_t const *octets, /* in - pointer to array of octets */
|
|
||||||
uint16_t num_trits, /* in - number of trits to produce */
|
|
||||||
uint8_t *trits) /* out - address for array of trits */
|
|
||||||
{
|
|
||||||
uint32_t bits24;
|
|
||||||
uint32_t bits3;
|
|
||||||
uint32_t shift;
|
|
||||||
|
|
||||||
assert(octets);
|
|
||||||
assert(trits);
|
|
||||||
|
|
||||||
while (num_trits >= 16) {
|
|
||||||
|
|
||||||
/* get next three octets */
|
|
||||||
|
|
||||||
bits24 = ((uint32_t)(*octets++)) << 16;
|
|
||||||
bits24 |= ((uint32_t)(*octets++)) << 8;
|
|
||||||
bits24 |= (uint32_t)(*octets++);
|
|
||||||
|
|
||||||
/* for each 3 bits in the three octets, output 2 trits */
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 21) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 18) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 15) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 12) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 9) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 6) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = (bits24 >> 3) & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
bits3 = bits24 & 0x7;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
|
|
||||||
num_trits -= 16;
|
|
||||||
}
|
|
||||||
if (num_trits == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* get three octets */
|
|
||||||
|
|
||||||
bits24 = ((uint32_t)(*octets++)) << 16;
|
|
||||||
bits24 |= ((uint32_t)(*octets++)) << 8;
|
|
||||||
bits24 |= (uint32_t)(*octets++);
|
|
||||||
|
|
||||||
shift = 21;
|
|
||||||
while (num_trits) {
|
|
||||||
|
|
||||||
/* for each 3 bits in the three octets, output up to 2 trits
|
|
||||||
* until all trits needed are produced
|
|
||||||
*/
|
|
||||||
|
|
||||||
bits3 = (bits24 >> shift) & 0x7;
|
|
||||||
shift -= 3;
|
|
||||||
*trits++ = bits_2_trit1[bits3];
|
|
||||||
if (--num_trits) {
|
|
||||||
*trits++ = bits_2_trit2[bits3];
|
|
||||||
--num_trits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_trits_2_bits
|
|
||||||
*
|
|
||||||
* Each 2 trits in an array of trits is converted to 3 bits, and the bits
|
|
||||||
* are packed in an array of octets. A multiple of 3 octets is output.
|
|
||||||
* Any bits in the final octets not derived from trits are zero.
|
|
||||||
*
|
|
||||||
* Returns TRUE if all trits were valid.
|
|
||||||
* Returns FALSE if invalid trits were found.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
ntru_trits_2_bits(
|
|
||||||
uint8_t const *trits, /* in - pointer to array of trits */
|
|
||||||
uint32_t num_trits, /* in - number of trits to convert */
|
|
||||||
uint8_t *octets) /* out - address for array of octets */
|
|
||||||
{
|
|
||||||
bool all_trits_valid = TRUE;
|
|
||||||
uint32_t bits24;
|
|
||||||
uint32_t bits3;
|
|
||||||
uint32_t shift;
|
|
||||||
|
|
||||||
assert(octets);
|
|
||||||
assert(trits);
|
|
||||||
|
|
||||||
while (num_trits >= 16) {
|
|
||||||
|
|
||||||
/* convert each 2 trits to 3 bits and pack */
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 = (bits3 << 21);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 18);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 15);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 12);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 9);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 6);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << 3);
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
bits3 += *trits++;
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= bits3;
|
|
||||||
|
|
||||||
num_trits -= 16;
|
|
||||||
|
|
||||||
/* output three octets */
|
|
||||||
|
|
||||||
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
|
||||||
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
|
||||||
*octets++ = (uint8_t)(bits24 & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
bits24 = 0;
|
|
||||||
shift = 21;
|
|
||||||
while (num_trits) {
|
|
||||||
|
|
||||||
/* convert each 2 trits to 3 bits and pack */
|
|
||||||
|
|
||||||
bits3 = *trits++ * 3;
|
|
||||||
if (--num_trits) {
|
|
||||||
bits3 += *trits++;
|
|
||||||
--num_trits;
|
|
||||||
}
|
|
||||||
if (bits3 > 7) {
|
|
||||||
bits3 = 7;
|
|
||||||
all_trits_valid = FALSE;
|
|
||||||
}
|
|
||||||
bits24 |= (bits3 << shift);
|
|
||||||
shift -= 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* output three octets */
|
|
||||||
|
|
||||||
*octets++ = (uint8_t)((bits24 >> 16) & 0xff);
|
|
||||||
*octets++ = (uint8_t)((bits24 >> 8) & 0xff);
|
|
||||||
*octets++ = (uint8_t)(bits24 & 0xff);
|
|
||||||
|
|
||||||
return all_trits_valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_coeffs_mod4_2_octets
|
|
||||||
*
|
|
||||||
* Takes an array of ring element coefficients mod 4 and packs the
|
|
||||||
* results into an octet string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_coeffs_mod4_2_octets(
|
|
||||||
uint16_t num_coeffs, /* in - number of coefficients */
|
|
||||||
uint16_t const *coeffs, /* in - pointer to coefficients */
|
|
||||||
uint8_t *octets) /* out - address for octets */
|
|
||||||
{
|
|
||||||
uint8_t bits2;
|
|
||||||
int shift;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
assert(coeffs);
|
|
||||||
assert(octets);
|
|
||||||
|
|
||||||
*octets = 0;
|
|
||||||
shift = 6;
|
|
||||||
for (i = 0; i < num_coeffs; i++) {
|
|
||||||
bits2 = (uint8_t)(coeffs[i] & 0x3);
|
|
||||||
*octets |= bits2 << shift;
|
|
||||||
shift -= 2;
|
|
||||||
if (shift < 0) {
|
|
||||||
++octets;
|
|
||||||
*octets = 0;
|
|
||||||
shift = 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_trits_2_octet
|
|
||||||
*
|
|
||||||
* Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_trits_2_octet(
|
|
||||||
uint8_t const *trits, /* in - pointer to trits */
|
|
||||||
uint8_t *octet) /* out - address for octet */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(trits);
|
|
||||||
assert(octet);
|
|
||||||
|
|
||||||
*octet = 0;
|
|
||||||
for (i = 4; i >= 0; i--) {
|
|
||||||
*octet = (*octet * 3) + trits[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_octet_2_trits
|
|
||||||
*
|
|
||||||
* Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_octet_2_trits(
|
|
||||||
uint8_t octet, /* in - octet to be unpacked */
|
|
||||||
uint8_t *trits) /* out - address for trits */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert(trits);
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++) {
|
|
||||||
trits[i] = octet % 3;
|
|
||||||
octet = (octet - trits[i]) / 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_indices_2_trits
|
|
||||||
*
|
|
||||||
* Converts a list of the nonzero indices of a polynomial into an array of
|
|
||||||
* trits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_indices_2_trits(
|
|
||||||
uint16_t in_len, /* in - no. of indices */
|
|
||||||
uint16_t const *in, /* in - pointer to list of indices */
|
|
||||||
bool plus1, /* in - if list is +1 cofficients */
|
|
||||||
uint8_t *out) /* out - address of output polynomial */
|
|
||||||
{
|
|
||||||
uint8_t trit = plus1 ? 1 : 2;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
assert(in);
|
|
||||||
assert(out);
|
|
||||||
|
|
||||||
for (i = 0; i < in_len; i++) {
|
|
||||||
out[in[i]] = trit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_packed_trits_2_indices
|
|
||||||
*
|
|
||||||
* Unpacks an array of N trits and creates a list of array indices
|
|
||||||
* corresponding to trits = +1, and list of array indices corresponding to
|
|
||||||
* trits = -1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_packed_trits_2_indices(
|
|
||||||
uint8_t const *in, /* in - pointer to packed-trit octets */
|
|
||||||
uint16_t num_trits, /* in - no. of packed trits */
|
|
||||||
uint16_t *indices_plus1, /* out - address for indices of +1 trits */
|
|
||||||
uint16_t *indices_minus1) /* out - address for indices of -1 trits */
|
|
||||||
{
|
|
||||||
uint8_t trits[5];
|
|
||||||
uint16_t i = 0;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
assert(in);
|
|
||||||
assert(indices_plus1);
|
|
||||||
assert(indices_minus1);
|
|
||||||
|
|
||||||
while (num_trits >= 5) {
|
|
||||||
ntru_octet_2_trits(*in++, trits);
|
|
||||||
num_trits -= 5;
|
|
||||||
for (j = 0; j < 5; j++, i++) {
|
|
||||||
if (trits[j] == 1) {
|
|
||||||
*indices_plus1 = i;
|
|
||||||
++indices_plus1;
|
|
||||||
} else if (trits[j] == 2) {
|
|
||||||
*indices_minus1 = i;
|
|
||||||
++indices_minus1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num_trits) {
|
|
||||||
ntru_octet_2_trits(*in, trits);
|
|
||||||
for (j = 0; num_trits && (j < 5); j++, i++) {
|
|
||||||
if (trits[j] == 1) {
|
|
||||||
*indices_plus1 = i;
|
|
||||||
++indices_plus1;
|
|
||||||
} else if (trits[j] == 2) {
|
|
||||||
*indices_minus1 = i;
|
|
||||||
++indices_minus1;
|
|
||||||
}
|
|
||||||
--num_trits;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_indices_2_packed_trits
|
|
||||||
*
|
|
||||||
* Takes a list of array indices corresponding to elements whose values
|
|
||||||
* are +1 or -1, and packs the N-element array of trits described by these
|
|
||||||
* lists into octets, 5 trits per octet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_indices_2_packed_trits(
|
|
||||||
uint16_t const *indices, /* in - pointer to indices */
|
|
||||||
uint16_t num_plus1, /* in - no. of indices for +1 trits */
|
|
||||||
uint16_t num_minus1, /* in - no. of indices for -1 trits */
|
|
||||||
uint16_t num_trits, /* in - N, no. of trits in array */
|
|
||||||
uint8_t *buf, /* in - temp buf, N octets */
|
|
||||||
uint8_t *out) /* out - address for packed octets */
|
|
||||||
{
|
|
||||||
assert(indices);
|
|
||||||
assert(buf);
|
|
||||||
assert(out);
|
|
||||||
|
|
||||||
/* convert indices to an array of trits */
|
|
||||||
|
|
||||||
memset(buf, 0, num_trits);
|
|
||||||
ntru_indices_2_trits(num_plus1, indices, TRUE, buf);
|
|
||||||
ntru_indices_2_trits(num_minus1, indices + num_plus1, FALSE, buf);
|
|
||||||
|
|
||||||
/* pack the array of trits */
|
|
||||||
|
|
||||||
while (num_trits >= 5) {
|
|
||||||
ntru_trits_2_octet(buf, out);
|
|
||||||
num_trits -= 5;
|
|
||||||
buf += 5;
|
|
||||||
++out;
|
|
||||||
}
|
|
||||||
if (num_trits) {
|
|
||||||
uint8_t trits[5];
|
|
||||||
|
|
||||||
memcpy(trits, buf, num_trits);
|
|
||||||
memset(trits + num_trits, 0, sizeof(trits) - num_trits);
|
|
||||||
ntru_trits_2_octet(trits, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_elements_2_octets
|
|
||||||
*
|
|
||||||
* Packs an array of n-bit elements into an array of
|
|
||||||
* ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_elements_2_octets(
|
|
||||||
uint16_t in_len, /* in - no. of elements to be packed */
|
|
||||||
uint16_t const *in, /* in - ptr to elements to be packed */
|
|
||||||
uint8_t n_bits, /* in - no. of bits in input element */
|
|
||||||
uint8_t *out) /* out - addr for output octets */
|
|
||||||
{
|
|
||||||
uint16_t temp;
|
|
||||||
int shift;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
assert(in_len);
|
|
||||||
assert(in);
|
|
||||||
assert((n_bits > 8) && (n_bits < 16));
|
|
||||||
assert(out);
|
|
||||||
|
|
||||||
/* pack */
|
|
||||||
|
|
||||||
temp = 0;
|
|
||||||
shift = n_bits - 8;
|
|
||||||
i = 0;
|
|
||||||
while (i < in_len) {
|
|
||||||
|
|
||||||
/* add bits to temp to fill an octet and output the octet */
|
|
||||||
|
|
||||||
temp |= in[i] >> shift;
|
|
||||||
*out++ = (uint8_t)(temp & 0xff);
|
|
||||||
shift = 8 - shift;
|
|
||||||
if (shift < 1) {
|
|
||||||
|
|
||||||
/* next full octet is in current input word */
|
|
||||||
|
|
||||||
shift += n_bits;
|
|
||||||
temp = 0;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* put remaining bits of input word in temp as partial octet,
|
|
||||||
* and increment index to next input word
|
|
||||||
*/
|
|
||||||
temp = in[i] << (uint16_t)shift;
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
shift = n_bits - shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* output any bits remaining in last input word */
|
|
||||||
|
|
||||||
if (shift != n_bits - 8) {
|
|
||||||
*out++ = (uint8_t)(temp & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_octets_2_elements
|
|
||||||
*
|
|
||||||
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
|
||||||
* n-bit elements, 8 < n_bits < 16. Any extra bits are discarded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
ntru_octets_2_elements(
|
|
||||||
uint16_t in_len, /* in - no. of octets to be unpacked */
|
|
||||||
uint8_t const *in, /* in - ptr to octets to be unpacked */
|
|
||||||
uint8_t n_bits, /* in - no. of bits in output element */
|
|
||||||
uint16_t *out) /* out - addr for output elements */
|
|
||||||
{
|
|
||||||
uint16_t temp;
|
|
||||||
uint16_t mask = (1 << n_bits) - 1;
|
|
||||||
int shift;
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
assert(in_len > 1);
|
|
||||||
assert(in);
|
|
||||||
assert((n_bits > 8) && (n_bits < 16));
|
|
||||||
assert(out);
|
|
||||||
|
|
||||||
/* unpack */
|
|
||||||
|
|
||||||
temp = 0;
|
|
||||||
shift = n_bits;
|
|
||||||
i = 0;
|
|
||||||
while (i < in_len) {
|
|
||||||
shift = 8 - shift;
|
|
||||||
if (shift < 0) {
|
|
||||||
|
|
||||||
/* the current octet will not fill the current element */
|
|
||||||
|
|
||||||
shift += n_bits;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* add bits from the current octet to fill the current element and
|
|
||||||
* output the element
|
|
||||||
*/
|
|
||||||
|
|
||||||
temp |= ((uint16_t)in[i]) >> shift;
|
|
||||||
*out++ = temp & mask;
|
|
||||||
temp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the remaining bits of the current octet to start an element */
|
|
||||||
|
|
||||||
shift = n_bits - shift;
|
|
||||||
temp |= ((uint16_t)in[i]) << shift;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,183 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_convert.h is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto_ntru_convert.h
|
|
||||||
*
|
|
||||||
* Contents: Definitions and declarations for conversion routines
|
|
||||||
* for NTRUEncrypt, including packing, unpacking and others.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#ifndef NTRU_CRYPTO_NTRU_CONVERT_H
|
|
||||||
#define NTRU_CRYPTO_NTRU_CONVERT_H
|
|
||||||
|
|
||||||
#include "ntru_crypto.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* function declarations */
|
|
||||||
|
|
||||||
/* ntru_bits_2_trits
|
|
||||||
*
|
|
||||||
* Each 3 bits in an array of octets is converted to 2 trits in an array
|
|
||||||
* of trits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_bits_2_trits(
|
|
||||||
uint8_t const *octets, /* in - pointer to array of octets */
|
|
||||||
uint16_t num_trits, /* in - number of trits to produce */
|
|
||||||
uint8_t *trits); /* out - address for array of trits */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_trits_2_bits
|
|
||||||
*
|
|
||||||
* Each 2 trits in an array of trits is converted to 3 bits, and the bits
|
|
||||||
* are packed in an array of octets. A multiple of 3 octets is output.
|
|
||||||
* Any bits in the final octets not derived from trits are zero.
|
|
||||||
*
|
|
||||||
* Returns TRUE if all trits were valid.
|
|
||||||
* Returns FALSE if invalid trits were found.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern bool
|
|
||||||
ntru_trits_2_bits(
|
|
||||||
uint8_t const *trits, /* in - pointer to array of trits */
|
|
||||||
uint32_t num_trits, /* in - number of trits to convert */
|
|
||||||
uint8_t *octets); /* out - address for array of octets */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_coeffs_mod4_2_octets
|
|
||||||
*
|
|
||||||
* Takes an array of coefficients mod 4 and packs the results into an
|
|
||||||
* octet string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_coeffs_mod4_2_octets(
|
|
||||||
uint16_t num_coeffs, /* in - number of coefficients */
|
|
||||||
uint16_t const *coeffs, /* in - pointer to coefficients */
|
|
||||||
uint8_t *octets); /* out - address for octets */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_trits_2_octet
|
|
||||||
*
|
|
||||||
* Packs 5 trits in an octet, where a trit is 0, 1, or 2 (-1).
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_trits_2_octet(
|
|
||||||
uint8_t const *trits, /* in - pointer to trits */
|
|
||||||
uint8_t *octet); /* out - address for octet */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_octet_2_trits
|
|
||||||
*
|
|
||||||
* Unpacks an octet to 5 trits, where a trit is 0, 1, or 2 (-1).
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_octet_2_trits(
|
|
||||||
uint8_t octet, /* in - octet to be unpacked */
|
|
||||||
uint8_t *trits); /* out - address for trits */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_indices_2_trits
|
|
||||||
*
|
|
||||||
* Converts a list of the nonzero indices of a polynomial into an array of
|
|
||||||
* trits.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_indices_2_trits(
|
|
||||||
uint16_t in_len, /* in - no. of indices */
|
|
||||||
uint16_t const *in, /* in - pointer to list of indices */
|
|
||||||
bool plus1, /* in - if list is +1 coefficients */
|
|
||||||
uint8_t *out); /* out - address of output polynomial */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_packed_trits_2_indices
|
|
||||||
*
|
|
||||||
* Unpacks an array of N trits and creates a list of array indices
|
|
||||||
* corresponding to trits = +1, and list of array indices corresponding to
|
|
||||||
* trits = -1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_packed_trits_2_indices(
|
|
||||||
uint8_t const *in, /* in - pointer to packed-trit octets */
|
|
||||||
uint16_t num_trits, /* in - no. of packed trits */
|
|
||||||
uint16_t *indices_plus1, /* out - address for indices of +1 trits */
|
|
||||||
uint16_t *indices_minus1); /* out - address for indices of -1 trits */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_indices_2_packed_trits
|
|
||||||
*
|
|
||||||
* Takes a list of array indices corresponding to elements whose values
|
|
||||||
* are +1 or -1, and packs the N-element array of trits described by these
|
|
||||||
* lists into octets, 5 trits per octet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_indices_2_packed_trits(
|
|
||||||
uint16_t const *indices, /* in - pointer to indices */
|
|
||||||
uint16_t num_plus1, /* in - no. of indices for +1 trits */
|
|
||||||
uint16_t num_minus1, /* in - no. of indices for -1 trits */
|
|
||||||
uint16_t num_trits, /* in - N, no. of trits in array */
|
|
||||||
uint8_t *buf, /* in - temp buf, N octets */
|
|
||||||
uint8_t *out); /* out - address for packed octets */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_elements_2_octets
|
|
||||||
*
|
|
||||||
* Packs an array of n-bit elements into an array of
|
|
||||||
* ((in_len * n_bits) + 7) / 8 octets, 8 < n_bits < 16.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_elements_2_octets(
|
|
||||||
uint16_t in_len, /* in - no. of elements to be packed */
|
|
||||||
uint16_t const *in, /* in - ptr to elements to be packed */
|
|
||||||
uint8_t n_bits, /* in - no. of bits in input element */
|
|
||||||
uint8_t *out); /* out - addr for output octets */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_octets_2_elements
|
|
||||||
*
|
|
||||||
* Unpacks an octet string into an array of ((in_len * 8) / n_bits)
|
|
||||||
* n-bit elements, 8 < n < 16. Any extra bits are discarded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern void
|
|
||||||
ntru_octets_2_elements(
|
|
||||||
uint16_t in_len, /* in - no. of octets to be unpacked */
|
|
||||||
uint8_t const *in, /* in - ptr to octets to be unpacked */
|
|
||||||
uint8_t n_bits, /* in - no. of bits in output element */
|
|
||||||
uint16_t *out); /* out - addr for output elements */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* NTRU_CRYPTO_NTRU_CONVERT_H */
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,374 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_encrypt.c is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto_ntru_encrypt.c
|
|
||||||
*
|
|
||||||
* Contents: Routines implementing NTRUEncrypt encryption and decryption and
|
|
||||||
* key generation.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "ntru_crypto.h"
|
|
||||||
#include "ntru_crypto_ntru_encrypt_key.h"
|
|
||||||
#include "ntru_crypto_ntru_convert.h"
|
|
||||||
#include "ntru_crypto_ntru_poly.h"
|
|
||||||
|
|
||||||
#include "ntru_param_set.h"
|
|
||||||
#include "ntru_trits.h"
|
|
||||||
#include "ntru_poly.h"
|
|
||||||
|
|
||||||
/* ntru_crypto_ntru_encrypt
|
|
||||||
*
|
|
||||||
* Implements NTRU encryption (SVES) for the parameter set specified in
|
|
||||||
* the public key blob.
|
|
||||||
*
|
|
||||||
* Before invoking this function, a DRBG must be instantiated using
|
|
||||||
* ntru_crypto_drbg_instantiate() to obtain a DRBG handle, and in that
|
|
||||||
* instantiation the requested security strength must be at least as large
|
|
||||||
* as the security strength of the NTRU parameter set being used.
|
|
||||||
* Failure to instantiate the DRBG with the proper security strength will
|
|
||||||
* result in this function returning DRBG_ERROR_BASE + DRBG_BAD_LENGTH.
|
|
||||||
*
|
|
||||||
* The required minimum size of the output ciphertext buffer (ct) may be
|
|
||||||
* queried by invoking this function with ct = NULL. In this case, no
|
|
||||||
* encryption is performed, NTRU_OK is returned, and the required minimum
|
|
||||||
* size for ct is returned in ct_len.
|
|
||||||
*
|
|
||||||
* When ct != NULL, at invocation *ct_len must be the size of the ct buffer.
|
|
||||||
* Upon return it is the actual size of the ciphertext.
|
|
||||||
*
|
|
||||||
* Returns NTRU_OK if successful.
|
|
||||||
* Returns NTRU_DRBG_FAIL if the DRBG handle is invalid.
|
|
||||||
* Returns NTRU_BAD_PARAMETER if an argument pointer (other than ct) is NULL.
|
|
||||||
* Returns NTRU_BAD_LENGTH if a length argument (pubkey_blob_len or pt_len) is
|
|
||||||
* zero, or if pt_len exceeds the maximum plaintext length for the parameter set.
|
|
||||||
* Returns NTRU_BAD_PUBLIC_KEY if the public-key blob is invalid
|
|
||||||
* (unknown format, corrupt, bad length).
|
|
||||||
* Returns NTRU_BUFFER_TOO_SMALL if the ciphertext buffer is too small.
|
|
||||||
* Returns NTRU_NO_MEMORY if memory needed cannot be allocated from the heap.
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
ntru_crypto_ntru_encrypt(
|
|
||||||
ntru_drbg_t *drbg, /* in - handle of DRBG */
|
|
||||||
uint16_t pubkey_blob_len, /* in - no. of octets in public key
|
|
||||||
blob */
|
|
||||||
uint8_t const *pubkey_blob, /* in - pointer to public key */
|
|
||||||
uint16_t pt_len, /* in - no. of octets in plaintext */
|
|
||||||
uint8_t const *pt, /* in - pointer to plaintext */
|
|
||||||
uint16_t *ct_len, /* in/out - no. of octets in ct, addr for
|
|
||||||
no. of octets in ciphertext */
|
|
||||||
uint8_t *ct) /* out - address for ciphertext */
|
|
||||||
{
|
|
||||||
ntru_param_set_t *params = NULL;
|
|
||||||
uint8_t const *pubkey_packed = NULL;
|
|
||||||
uint8_t pubkey_pack_type = 0x00;
|
|
||||||
uint16_t packed_ct_len;
|
|
||||||
size_t scratch_buf_len;
|
|
||||||
uint32_t dr;
|
|
||||||
uint32_t dr1 = 0;
|
|
||||||
uint32_t dr2 = 0;
|
|
||||||
uint32_t dr3 = 0;
|
|
||||||
uint16_t ring_mult_tmp_len;
|
|
||||||
int16_t m1;
|
|
||||||
uint16_t *scratch_buf = NULL;
|
|
||||||
uint16_t *ringel_buf = NULL;
|
|
||||||
uint8_t *b_buf = NULL;
|
|
||||||
uint8_t *tmp_buf = NULL;
|
|
||||||
bool msg_rep_good = FALSE;
|
|
||||||
hash_algorithm_t hash_algid;
|
|
||||||
uint16_t mprime_len = 0;
|
|
||||||
uint16_t mod_q_mask;
|
|
||||||
uint32_t result = NTRU_OK;
|
|
||||||
ntru_trits_t *mask;
|
|
||||||
uint8_t *mask_trits;
|
|
||||||
chunk_t seed;
|
|
||||||
ntru_poly_t *r_poly;
|
|
||||||
|
|
||||||
/* check for bad parameters */
|
|
||||||
|
|
||||||
if (!pubkey_blob || !pt || !ct_len)
|
|
||||||
{
|
|
||||||
return NTRU_BAD_PARAMETER;
|
|
||||||
}
|
|
||||||
if ((pubkey_blob_len == 0) || (pt_len == 0))
|
|
||||||
{
|
|
||||||
return NTRU_BAD_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get a pointer to the parameter-set parameters, the packing type for
|
|
||||||
* the public key, and a pointer to the packed public key
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!ntru_crypto_ntru_encrypt_key_parse(TRUE /* pubkey */, pubkey_blob_len,
|
|
||||||
pubkey_blob, &pubkey_pack_type,
|
|
||||||
NULL, ¶ms, &pubkey_packed,
|
|
||||||
NULL))
|
|
||||||
{
|
|
||||||
return NTRU_BAD_PUBLIC_KEY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the ciphertext size if requested */
|
|
||||||
|
|
||||||
packed_ct_len = (params->N * params->q_bits + 7) >> 3;
|
|
||||||
if (!ct)
|
|
||||||
{
|
|
||||||
*ct_len = packed_ct_len;
|
|
||||||
return NTRU_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check the ciphertext buffer size */
|
|
||||||
|
|
||||||
if (*ct_len < packed_ct_len)
|
|
||||||
{
|
|
||||||
return NTRU_BUFFER_TOO_SMALL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check the plaintext length */
|
|
||||||
|
|
||||||
if (pt_len > params->m_len_max)
|
|
||||||
{
|
|
||||||
return NTRU_BAD_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate memory for all operations */
|
|
||||||
|
|
||||||
if (params->is_product_form)
|
|
||||||
{
|
|
||||||
ring_mult_tmp_len = params->N << 1; /* 2N 16-bit word buffer */
|
|
||||||
dr1 = params->dF_r & 0xff;
|
|
||||||
dr2 = (params->dF_r >> 8) & 0xff;
|
|
||||||
dr3 = (params->dF_r >> 16) & 0xff;
|
|
||||||
dr = dr1 + dr2 + dr3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ring_mult_tmp_len = params->N; /* N 16-bit word buffer */
|
|
||||||
dr = params->dF_r;
|
|
||||||
}
|
|
||||||
scratch_buf_len = (ring_mult_tmp_len << 1) +
|
|
||||||
/* X-byte temp buf for ring mult and
|
|
||||||
other intermediate results */
|
|
||||||
(params->N << 1) + /* 2N-byte buffer for ring elements
|
|
||||||
and overflow from temp buffer */
|
|
||||||
(dr << 2) + /* buffer for r indices */
|
|
||||||
params->sec_strength_len;
|
|
||||||
/* buffer for b */
|
|
||||||
scratch_buf = malloc(scratch_buf_len);
|
|
||||||
if (!scratch_buf)
|
|
||||||
{
|
|
||||||
return NTRU_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
ringel_buf = scratch_buf + ring_mult_tmp_len;
|
|
||||||
b_buf = (uint8_t *)(ringel_buf + params->N);
|
|
||||||
tmp_buf = (uint8_t *)scratch_buf;
|
|
||||||
|
|
||||||
/* set hash algorithm based on security strength */
|
|
||||||
hash_algid = (params->sec_strength_len <= 20) ? HASH_SHA1 : HASH_SHA256;
|
|
||||||
|
|
||||||
/* set constants */
|
|
||||||
mod_q_mask = params->q - 1;
|
|
||||||
|
|
||||||
/* loop until a message representative with proper weight is achieved */
|
|
||||||
|
|
||||||
do {
|
|
||||||
uint8_t *ptr = tmp_buf;
|
|
||||||
|
|
||||||
/* get b */
|
|
||||||
if (drbg->generate(drbg, params->sec_strength_len * BITS_PER_BYTE,
|
|
||||||
params->sec_strength_len, b_buf))
|
|
||||||
{
|
|
||||||
result = NTRU_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = NTRU_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == NTRU_OK)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* form sData (OID || m || b || hTrunc) */
|
|
||||||
memcpy(ptr, params->oid, 3);
|
|
||||||
ptr += 3;
|
|
||||||
memcpy(ptr, pt, pt_len);
|
|
||||||
ptr += pt_len;
|
|
||||||
memcpy(ptr, b_buf, params->sec_strength_len);
|
|
||||||
ptr += params->sec_strength_len;
|
|
||||||
memcpy(ptr, pubkey_packed, params->sec_strength_len);
|
|
||||||
ptr += params->sec_strength_len;
|
|
||||||
|
|
||||||
DBG2(DBG_LIB, "generate polynomial r");
|
|
||||||
|
|
||||||
seed = chunk_create(tmp_buf, ptr - tmp_buf);
|
|
||||||
r_poly = ntru_poly_create_from_seed(hash_algid, seed, params->c_bits,
|
|
||||||
params->N, params->q,
|
|
||||||
params->dF_r, params->dF_r,
|
|
||||||
params->is_product_form);
|
|
||||||
if (!r_poly)
|
|
||||||
{
|
|
||||||
result = NTRU_MGF1_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == NTRU_OK)
|
|
||||||
{
|
|
||||||
uint16_t pubkey_packed_len;
|
|
||||||
|
|
||||||
/* unpack the public key */
|
|
||||||
assert(pubkey_pack_type == NTRU_KEY_PACKED_COEFFICIENTS);
|
|
||||||
pubkey_packed_len = (params->N * params->q_bits + 7) >> 3;
|
|
||||||
ntru_octets_2_elements(pubkey_packed_len, pubkey_packed,
|
|
||||||
params->q_bits, ringel_buf);
|
|
||||||
|
|
||||||
/* form R = h * r */
|
|
||||||
r_poly->ring_mult(r_poly, ringel_buf, ringel_buf);
|
|
||||||
r_poly->destroy(r_poly);
|
|
||||||
|
|
||||||
/* form R mod 4 */
|
|
||||||
ntru_coeffs_mod4_2_octets(params->N, ringel_buf, tmp_buf);
|
|
||||||
|
|
||||||
/* form mask */
|
|
||||||
seed = chunk_create(tmp_buf, (params->N + 3)/4);
|
|
||||||
mask = ntru_trits_create(params->N, hash_algid, seed);
|
|
||||||
if (!mask)
|
|
||||||
{
|
|
||||||
result = NTRU_MGF1_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == NTRU_OK)
|
|
||||||
{
|
|
||||||
uint8_t *Mtrin_buf = tmp_buf + params->N;
|
|
||||||
uint8_t *M_buf = Mtrin_buf + params->N -
|
|
||||||
(params->sec_strength_len + params->m_len_len +
|
|
||||||
params->m_len_max + 2);
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
/* form the padded message M */
|
|
||||||
ptr = M_buf;
|
|
||||||
memcpy(ptr, b_buf, params->sec_strength_len);
|
|
||||||
ptr += params->sec_strength_len;
|
|
||||||
if (params->m_len_len == 2)
|
|
||||||
*ptr++ = (uint8_t)((pt_len >> 8) & 0xff);
|
|
||||||
*ptr++ = (uint8_t)(pt_len & 0xff);
|
|
||||||
memcpy(ptr, pt, pt_len);
|
|
||||||
ptr += pt_len;
|
|
||||||
|
|
||||||
/* add an extra zero byte in case without it the bit string
|
|
||||||
* is not a multiple of 3 bits and therefore might not be
|
|
||||||
* able to produce enough trits
|
|
||||||
*/
|
|
||||||
|
|
||||||
memset(ptr, 0, params->m_len_max - pt_len + 2);
|
|
||||||
|
|
||||||
/* convert M to trits (Mbin to Mtrin) */
|
|
||||||
mprime_len = params->N;
|
|
||||||
if (params->is_product_form)
|
|
||||||
{
|
|
||||||
--mprime_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
ntru_bits_2_trits(M_buf, mprime_len, Mtrin_buf);
|
|
||||||
mask_trits = mask->get_trits(mask);
|
|
||||||
|
|
||||||
/* form the msg representative m' by adding Mtrin to mask, mod p */
|
|
||||||
if (params->is_product_form)
|
|
||||||
{
|
|
||||||
m1 = 0;
|
|
||||||
for (i = 0; i < mprime_len; i++)
|
|
||||||
{
|
|
||||||
tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
|
|
||||||
if (tmp_buf[i] >= 3)
|
|
||||||
{
|
|
||||||
tmp_buf[i] -= 3;
|
|
||||||
}
|
|
||||||
if (tmp_buf[i] == 1)
|
|
||||||
{
|
|
||||||
++m1;
|
|
||||||
}
|
|
||||||
else if (tmp_buf[i] == 2)
|
|
||||||
{
|
|
||||||
--m1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < mprime_len; i++)
|
|
||||||
{
|
|
||||||
tmp_buf[i] = mask_trits[i] + Mtrin_buf[i];
|
|
||||||
if (tmp_buf[i] >= 3)
|
|
||||||
{
|
|
||||||
tmp_buf[i] -= 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mask->destroy(mask);
|
|
||||||
|
|
||||||
/* check that message representative meets minimum weight
|
|
||||||
* requirements
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (params->is_product_form)
|
|
||||||
msg_rep_good = m1 < 0 ? (bool)(-m1 <= params->min_msg_rep_wt) :
|
|
||||||
(bool)( m1 <= params->min_msg_rep_wt);
|
|
||||||
else
|
|
||||||
msg_rep_good = ntru_poly_check_min_weight(mprime_len, tmp_buf,
|
|
||||||
params->min_msg_rep_wt);
|
|
||||||
}
|
|
||||||
} while ((result == NTRU_OK) && !msg_rep_good);
|
|
||||||
|
|
||||||
if (result == NTRU_OK)
|
|
||||||
{
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
/* form ciphertext e by adding m' to R mod q */
|
|
||||||
|
|
||||||
for (i = 0; i < mprime_len; i++) {
|
|
||||||
if (tmp_buf[i] == 1)
|
|
||||||
ringel_buf[i] = (ringel_buf[i] + 1) & mod_q_mask;
|
|
||||||
else if (tmp_buf[i] == 2)
|
|
||||||
ringel_buf[i] = (ringel_buf[i] - 1) & mod_q_mask;
|
|
||||||
}
|
|
||||||
if (params->is_product_form)
|
|
||||||
ringel_buf[i] = (ringel_buf[i] - m1) & mod_q_mask;
|
|
||||||
|
|
||||||
/* pack ciphertext */
|
|
||||||
ntru_elements_2_octets(params->N, ringel_buf, params->q_bits, ct);
|
|
||||||
*ct_len = packed_ct_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cleanup */
|
|
||||||
memset(scratch_buf, 0, scratch_buf_len);
|
|
||||||
free(scratch_buf);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_encrypt_key.c is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto_ntru_encrypt_key.c
|
|
||||||
*
|
|
||||||
* Contents: Routines for exporting and importing public and private keys
|
|
||||||
* for NTRUEncrypt.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include "ntru_crypto_ntru_encrypt_key.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_crypto_ntru_encrypt_key_parse
|
|
||||||
*
|
|
||||||
* Parses an NTRUEncrypt key blob.
|
|
||||||
* If the blob is not corrupt, returns packing types for public and private
|
|
||||||
* keys, a pointer to the parameter set, a pointer to the public key, and
|
|
||||||
* a pointer to the private key if it exists.
|
|
||||||
*
|
|
||||||
* Returns TRUE if successful.
|
|
||||||
* Returns FALSE if the blob is invalid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
ntru_crypto_ntru_encrypt_key_parse(
|
|
||||||
bool pubkey_parse, /* in - if parsing pubkey
|
|
||||||
blob */
|
|
||||||
uint16_t key_blob_len, /* in - no. octets in key
|
|
||||||
blob */
|
|
||||||
uint8_t const *key_blob, /* in - pointer to key blob */
|
|
||||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
|
||||||
packing type */
|
|
||||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
|
||||||
packing type */
|
|
||||||
ntru_param_set_t **params, /* out - addr for ptr to
|
|
||||||
parameter set */
|
|
||||||
uint8_t const **pubkey, /* out - addr for ptr to
|
|
||||||
packed pubkey */
|
|
||||||
uint8_t const **privkey) /* out - addr for ptr to
|
|
||||||
packed privkey */
|
|
||||||
{
|
|
||||||
uint8_t tag;
|
|
||||||
|
|
||||||
/* parse key blob based on tag */
|
|
||||||
tag = key_blob[0];
|
|
||||||
switch (tag) {
|
|
||||||
case NTRU_PUBKEY_TAG:
|
|
||||||
if (!pubkey_parse)
|
|
||||||
return FALSE;
|
|
||||||
break;
|
|
||||||
case NTRU_PRIVKEY_DEFAULT_TAG:
|
|
||||||
case NTRU_PRIVKEY_TRITS_TAG:
|
|
||||||
case NTRU_PRIVKEY_INDICES_TAG:
|
|
||||||
assert(privkey_pack_type);
|
|
||||||
assert(privkey);
|
|
||||||
if (pubkey_parse)
|
|
||||||
return FALSE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (tag) {
|
|
||||||
case NTRU_PUBKEY_TAG:
|
|
||||||
case NTRU_PRIVKEY_DEFAULT_TAG:
|
|
||||||
case NTRU_PRIVKEY_TRITS_TAG:
|
|
||||||
case NTRU_PRIVKEY_INDICES_TAG:
|
|
||||||
|
|
||||||
/* Version 0:
|
|
||||||
* byte 0: tag
|
|
||||||
* byte 1: no. of octets in OID
|
|
||||||
* bytes 2-4: OID
|
|
||||||
* bytes 5- : packed pubkey
|
|
||||||
* [packed privkey]
|
|
||||||
*/
|
|
||||||
|
|
||||||
{
|
|
||||||
ntru_param_set_t *p = NULL;
|
|
||||||
uint16_t pubkey_packed_len;
|
|
||||||
|
|
||||||
/* check OID length and minimum blob length for tag and OID */
|
|
||||||
|
|
||||||
if ((key_blob_len < 5) || (key_blob[1] != 3))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* get a pointer to the parameter set corresponding to the OID */
|
|
||||||
p = ntru_param_set_get_by_oid(key_blob + 2);
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check blob length and assign pointers to blob fields */
|
|
||||||
|
|
||||||
pubkey_packed_len = (p->N * p->q_bits + 7) / 8;
|
|
||||||
if (pubkey_parse) { /* public-key parsing */
|
|
||||||
if (key_blob_len != 5 + pubkey_packed_len)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
*pubkey = key_blob + 5;
|
|
||||||
|
|
||||||
} else { /* private-key parsing */
|
|
||||||
uint16_t privkey_packed_len;
|
|
||||||
uint16_t privkey_packed_trits_len = (p->N + 4) / 5;
|
|
||||||
uint16_t privkey_packed_indices_len;
|
|
||||||
uint16_t dF;
|
|
||||||
|
|
||||||
/* check packing type for product-form private keys */
|
|
||||||
|
|
||||||
if (p->is_product_form &&
|
|
||||||
(tag == NTRU_PRIVKEY_TRITS_TAG))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* set packed-key length for packed indices */
|
|
||||||
|
|
||||||
if (p->is_product_form)
|
|
||||||
dF = (uint16_t)( (p->dF_r & 0xff) + /* df1 */
|
|
||||||
((p->dF_r >> 8) & 0xff) + /* df2 */
|
|
||||||
((p->dF_r >> 16) & 0xff)); /* df3 */
|
|
||||||
else
|
|
||||||
dF = (uint16_t)p->dF_r;
|
|
||||||
privkey_packed_indices_len = ((dF << 1) * p->N_bits + 7) >> 3;
|
|
||||||
|
|
||||||
/* set private-key packing type if defaulted */
|
|
||||||
|
|
||||||
if (tag == NTRU_PRIVKEY_DEFAULT_TAG) {
|
|
||||||
if (p->is_product_form ||
|
|
||||||
(privkey_packed_indices_len <=
|
|
||||||
privkey_packed_trits_len))
|
|
||||||
tag = NTRU_PRIVKEY_INDICES_TAG;
|
|
||||||
else
|
|
||||||
tag = NTRU_PRIVKEY_TRITS_TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag == NTRU_PRIVKEY_TRITS_TAG)
|
|
||||||
privkey_packed_len = privkey_packed_trits_len;
|
|
||||||
else
|
|
||||||
privkey_packed_len = privkey_packed_indices_len;
|
|
||||||
|
|
||||||
if (key_blob_len != 5 + pubkey_packed_len + privkey_packed_len)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
*pubkey = key_blob + 5;
|
|
||||||
*privkey = *pubkey + pubkey_packed_len;
|
|
||||||
*privkey_pack_type = (tag == NTRU_PRIVKEY_TRITS_TAG) ?
|
|
||||||
NTRU_KEY_PACKED_TRITS :
|
|
||||||
NTRU_KEY_PACKED_INDICES;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return parameter set pointer */
|
|
||||||
|
|
||||||
*pubkey_pack_type = NTRU_KEY_PACKED_COEFFICIENTS;
|
|
||||||
*params = p;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break; /* can't get here */
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
@ -1,65 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_cencrypt_key.h is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
|
|
||||||
#define NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H
|
|
||||||
|
|
||||||
#include "ntru_crypto_ntru_convert.h"
|
|
||||||
|
|
||||||
#include "ntru_param_set.h"
|
|
||||||
|
|
||||||
/* function declarations */
|
|
||||||
|
|
||||||
|
|
||||||
/* ntru_crypto_ntru_encrypt_key_parse
|
|
||||||
*
|
|
||||||
* Parses an NTRUEncrypt key blob.
|
|
||||||
* If the blob is not corrupt, returns packing types for public and private
|
|
||||||
* keys, a pointer to the parameter set, a pointer to the public key, and
|
|
||||||
* a pointer to the private key if it exists.
|
|
||||||
*
|
|
||||||
* Returns TRUE if successful.
|
|
||||||
* Returns FALSE if the blob is invalid.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern bool
|
|
||||||
ntru_crypto_ntru_encrypt_key_parse(
|
|
||||||
bool pubkey_parse, /* in - if parsing pubkey
|
|
||||||
blob */
|
|
||||||
uint16_t key_blob_len, /* in - no. octets in key
|
|
||||||
blob */
|
|
||||||
uint8_t const *key_blob, /* in - pointer to key blob */
|
|
||||||
uint8_t *pubkey_pack_type, /* out - addr for pubkey
|
|
||||||
packing type */
|
|
||||||
uint8_t *privkey_pack_type, /* out - addr for privkey
|
|
||||||
packing type */
|
|
||||||
ntru_param_set_t **params, /* out - addr for ptr to
|
|
||||||
parameter set */
|
|
||||||
uint8_t const **pubkey, /* out - addr for ptr to
|
|
||||||
packed pubkey */
|
|
||||||
uint8_t const **privkey); /* out - addr for ptr to
|
|
||||||
packed privkey */
|
|
||||||
|
|
||||||
#endif /* NTRU_CRYPTO_NTRU_ENCRYPT_KEY_H */
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_poly.c is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "ntru_crypto_ntru_poly.h"
|
|
||||||
|
|
||||||
/* ntru_poly_check_min_weight
|
|
||||||
*
|
|
||||||
* Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
|
|
||||||
* a minimum weight.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool
|
|
||||||
ntru_poly_check_min_weight(
|
|
||||||
uint16_t num_els, /* in - degree of polynomial */
|
|
||||||
uint8_t *ringels, /* in - pointer to trinary ring elements */
|
|
||||||
uint16_t min_wt) /* in - minimum weight */
|
|
||||||
{
|
|
||||||
uint16_t wt[3];
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
wt[0] = wt[1] = wt[2] = 0;
|
|
||||||
for (i = 0; i < num_els; i++) {
|
|
||||||
++wt[ringels[i]];
|
|
||||||
}
|
|
||||||
if ((wt[0] < min_wt) || (wt[1] < min_wt) || (wt[2] < min_wt)) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
/******************************************************************************
|
|
||||||
* NTRU Cryptography Reference Source Code
|
|
||||||
* Copyright (c) 2009-2013, by Security Innovation, Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* ntru_crypto_ntru_poly.h is a component of ntru-crypto.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2009-2013 Security Innovation
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* File: ntru_crypto_ntru_poly.h
|
|
||||||
*
|
|
||||||
* Contents: Public header file for generating and operating on polynomials
|
|
||||||
* in the NTRU algorithm.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef NTRU_CRYPTO_NTRU_POLY_H
|
|
||||||
#define NTRU_CRYPTO_NTRU_POLY_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "ntru_crypto.h"
|
|
||||||
|
|
||||||
#include <crypto/hashers/hasher.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* function declarations */
|
|
||||||
|
|
||||||
/* ntru_poly_check_min_weight
|
|
||||||
*
|
|
||||||
* Checks that the number of 0, +1, and -1 trinary ring elements meet or exceed
|
|
||||||
* a minimum weight.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern bool
|
|
||||||
ntru_poly_check_min_weight(
|
|
||||||
uint16_t num_els, /* in - degree of polynomial */
|
|
||||||
uint8_t *ringels, /* in - pointer to trinary ring elements */
|
|
||||||
uint16_t min_wt); /* in - minimum weight */
|
|
||||||
|
|
||||||
#endif /* NTRU_CRYPTO_NTRU_POLY_H */
|
|
||||||
@ -67,6 +67,10 @@ struct private_ntru_drbg_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t value;
|
chunk_t value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,13 +184,23 @@ METHOD(ntru_drbg_t, generate, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(ntru_drbg_t, get_ref, ntru_drbg_t*,
|
||||||
|
private_ntru_drbg_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ntru_drbg_t, destroy, void,
|
METHOD(ntru_drbg_t, destroy, void,
|
||||||
private_ntru_drbg_t *this)
|
private_ntru_drbg_t *this)
|
||||||
{
|
{
|
||||||
this->hmac->destroy(this->hmac);
|
if (ref_put(&this->ref))
|
||||||
chunk_clear(&this->key);
|
{
|
||||||
chunk_clear(&this->value);
|
this->hmac->destroy(this->hmac);
|
||||||
free(this);
|
chunk_clear(&this->key);
|
||||||
|
chunk_clear(&this->value);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -238,6 +252,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
|
|||||||
.get_strength = _get_strength,
|
.get_strength = _get_strength,
|
||||||
.reseed = _reseed,
|
.reseed = _reseed,
|
||||||
.generate = _generate,
|
.generate = _generate,
|
||||||
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.strength = strength,
|
.strength = strength,
|
||||||
@ -247,6 +262,7 @@ ntru_drbg_t *ntru_drbg_create(u_int32_t strength, chunk_t pers_str,
|
|||||||
.value = chunk_alloc(hmac->get_block_size(hmac)),
|
.value = chunk_alloc(hmac->get_block_size(hmac)),
|
||||||
.max_requests = max_requests,
|
.max_requests = max_requests,
|
||||||
.reseed_counter = 1,
|
.reseed_counter = 1,
|
||||||
|
.ref = 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
memset(this->key.ptr, 0x00, this->key.len);
|
memset(this->key.ptr, 0x00, this->key.len);
|
||||||
|
|||||||
@ -57,6 +57,13 @@ struct ntru_drbg_t {
|
|||||||
bool (*generate)(ntru_drbg_t *this, u_int32_t strength, u_int32_t len,
|
bool (*generate)(ntru_drbg_t *this, u_int32_t strength, u_int32_t len,
|
||||||
u_int8_t *out);
|
u_int8_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a reference on an ntru_drbg_t object increasing the count by one
|
||||||
|
*
|
||||||
|
* @return reference to the ntru_drbg_t object
|
||||||
|
*/
|
||||||
|
ntru_drbg_t* (*get_ref)(ntru_drbg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uninstantiate and destroy the DRBG object
|
* Uninstantiate and destroy the DRBG object
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -19,8 +19,6 @@
|
|||||||
#include "ntru_private_key.h"
|
#include "ntru_private_key.h"
|
||||||
#include "ntru_public_key.h"
|
#include "ntru_public_key.h"
|
||||||
|
|
||||||
#include "ntru_crypto/ntru_crypto.h"
|
|
||||||
|
|
||||||
#include <crypto/diffie_hellman.h>
|
#include <crypto/diffie_hellman.h>
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
@ -80,11 +78,6 @@ struct private_ntru_ke_t {
|
|||||||
*/
|
*/
|
||||||
ntru_private_key_t *privkey;
|
ntru_private_key_t *privkey;
|
||||||
|
|
||||||
/**
|
|
||||||
* NTRU Public Key Encoding
|
|
||||||
*/
|
|
||||||
chunk_t pubkey_enc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NTRU encrypted shared secret
|
* NTRU encrypted shared secret
|
||||||
*/
|
*/
|
||||||
@ -140,11 +133,9 @@ METHOD(diffie_hellman_t, get_my_public_value, void,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->pubkey = this->privkey->get_public_key(this->privkey);
|
this->pubkey = this->privkey->get_public_key(this->privkey);
|
||||||
this->pubkey_enc = this->pubkey->get_encoding(this->pubkey);
|
|
||||||
this->pubkey_enc = chunk_clone(this->pubkey_enc);
|
|
||||||
DBG3(DBG_LIB, "NTRU public key: %B", &this->pubkey_enc);
|
|
||||||
}
|
}
|
||||||
*value = chunk_clone(this->pubkey_enc);
|
*value = chunk_clone(this->pubkey->get_encoding(this->pubkey));
|
||||||
|
DBG3(DBG_LIB, "NTRU public key: %B", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +156,6 @@ METHOD(diffie_hellman_t, get_shared_secret, status_t,
|
|||||||
METHOD(diffie_hellman_t, set_other_public_value, void,
|
METHOD(diffie_hellman_t, set_other_public_value, void,
|
||||||
private_ntru_ke_t *this, chunk_t value)
|
private_ntru_ke_t *this, chunk_t value)
|
||||||
{
|
{
|
||||||
u_int16_t ciphertext_len;
|
|
||||||
|
|
||||||
if (this->privkey)
|
if (this->privkey)
|
||||||
{
|
{
|
||||||
/* initiator decrypting shared secret */
|
/* initiator decrypting shared secret */
|
||||||
@ -187,23 +176,24 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ntru_public_key_t *pubkey;
|
||||||
|
|
||||||
/* responder generating and encrypting the shared secret */
|
/* responder generating and encrypting the shared secret */
|
||||||
this->responder = TRUE;
|
this->responder = TRUE;
|
||||||
|
|
||||||
/* check the NTRU public key format */
|
DBG3(DBG_LIB, "NTRU public key: %B", &value);
|
||||||
if (value.len < 5 ||
|
pubkey = ntru_public_key_create_from_data(this->drbg, value);
|
||||||
value.ptr[0] != NTRU_PUBKEY_TAG ||
|
if (!pubkey)
|
||||||
value.ptr[1] != NTRU_OID_LEN)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "received NTRU public key with invalid header");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!memeq(value.ptr + 2, this->param_set->oid, NTRU_OID_LEN))
|
if (pubkey->get_id(pubkey) != this->param_set->id)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "received NTRU public key with wrong OID");
|
DBG1(DBG_LIB, "received NTRU public key with wrong OUI");
|
||||||
|
pubkey->destroy(pubkey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this->pubkey_enc = chunk_clone(value);
|
this->pubkey = pubkey;
|
||||||
|
|
||||||
/* shared secret size is chosen as twice the cryptographical strength */
|
/* shared secret size is chosen as twice the cryptographical strength */
|
||||||
this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
|
this->shared_secret = chunk_alloc(2 * this->strength / BITS_PER_BYTE);
|
||||||
@ -218,25 +208,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
|
|||||||
}
|
}
|
||||||
this->computed = TRUE;
|
this->computed = TRUE;
|
||||||
|
|
||||||
/* determine the size of the ciphertext */
|
|
||||||
if (ntru_crypto_ntru_encrypt(this->drbg,
|
|
||||||
this->pubkey_enc.len, this->pubkey_enc.ptr,
|
|
||||||
this->shared_secret.len, this->shared_secret.ptr,
|
|
||||||
&ciphertext_len, NULL) != NTRU_OK)
|
|
||||||
{
|
|
||||||
DBG1(DBG_LIB, "error determining ciphertext size");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this->ciphertext = chunk_alloc(ciphertext_len);
|
|
||||||
|
|
||||||
/* encrypt the shared secret */
|
/* encrypt the shared secret */
|
||||||
if (ntru_crypto_ntru_encrypt(this->drbg,
|
if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext))
|
||||||
this->pubkey_enc.len, this->pubkey_enc.ptr,
|
|
||||||
this->shared_secret.len, this->shared_secret.ptr,
|
|
||||||
&ciphertext_len, this->ciphertext.ptr) != NTRU_OK)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
|
DBG1(DBG_LIB, "NTRU encryption of shared secret failed");
|
||||||
chunk_free(&this->ciphertext);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
|
DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext);
|
||||||
@ -256,7 +231,6 @@ METHOD(diffie_hellman_t, destroy, void,
|
|||||||
DESTROY_IF(this->pubkey);
|
DESTROY_IF(this->pubkey);
|
||||||
this->drbg->destroy(this->drbg);
|
this->drbg->destroy(this->drbg);
|
||||||
this->entropy->destroy(this->entropy);
|
this->entropy->destroy(this->entropy);
|
||||||
chunk_free(&this->pubkey_enc);
|
|
||||||
chunk_free(&this->ciphertext);
|
chunk_free(&this->ciphertext);
|
||||||
chunk_clear(&this->shared_secret);
|
chunk_clear(&this->shared_secret);
|
||||||
free(this);
|
free(this);
|
||||||
|
|||||||
@ -116,4 +116,3 @@ ntru_param_set_t* ntru_param_set_get_by_id(ntru_param_set_id_t id);
|
|||||||
ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid);
|
ntru_param_set_t* ntru_param_set_get_by_oid(uint8_t const *oid);
|
||||||
|
|
||||||
#endif /** NTRU_PARAM_SET_H_ @}*/
|
#endif /** NTRU_PARAM_SET_H_ @}*/
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,7 @@
|
|||||||
#include "ntru_private_key.h"
|
#include "ntru_private_key.h"
|
||||||
#include "ntru_trits.h"
|
#include "ntru_trits.h"
|
||||||
#include "ntru_poly.h"
|
#include "ntru_poly.h"
|
||||||
|
#include "ntru_convert.h"
|
||||||
#include "ntru_crypto/ntru_crypto_ntru_convert.h"
|
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <utils/test.h>
|
#include <utils/test.h>
|
||||||
@ -56,12 +55,23 @@ struct private_ntru_private_key_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t encoding;
|
chunk_t encoding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deterministic Random Bit Generator
|
||||||
|
*/
|
||||||
|
ntru_drbg_t *drbg;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
METHOD(ntru_private_key_t, get_id, ntru_param_set_id_t,
|
||||||
|
private_ntru_private_key_t *this)
|
||||||
|
{
|
||||||
|
return this->params->id;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ntru_private_key_t, get_public_key, ntru_public_key_t*,
|
METHOD(ntru_private_key_t, get_public_key, ntru_public_key_t*,
|
||||||
private_ntru_private_key_t *this)
|
private_ntru_private_key_t *this)
|
||||||
{
|
{
|
||||||
return ntru_public_key_create(this->params, this->pubkey);
|
return ntru_public_key_create(this->drbg, this->params, this->pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,9 +155,10 @@ METHOD(ntru_private_key_t, get_encoding, chunk_t,
|
|||||||
* @param min_wt minimum weight
|
* @param min_wt minimum weight
|
||||||
* @return TRUE if minimum weight met or exceeded
|
* @return TRUE if minimum weight met or exceeded
|
||||||
*/
|
*/
|
||||||
static bool check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
|
bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
|
||||||
{
|
{
|
||||||
uint16_t wt[3];
|
uint16_t wt[3];
|
||||||
|
bool success;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
wt[0] = wt[1] = wt[2] = 0;
|
wt[0] = wt[1] = wt[2] = 0;
|
||||||
@ -156,8 +167,12 @@ static bool check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt)
|
|||||||
{
|
{
|
||||||
++wt[t[i]];
|
++wt[t[i]];
|
||||||
}
|
}
|
||||||
|
success = (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt);
|
||||||
|
|
||||||
return (wt[0] >= min_wt) && (wt[1] >= min_wt) && (wt[2] >= min_wt);
|
DBG2(DBG_LIB, "minimum weight = %u, so -1: %u, 0: %u, +1: %u is %sok",
|
||||||
|
min_wt, wt[2], wt[0], wt[1], success ? "" : "not ");
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ntru_private_key_t, decrypt, bool,
|
METHOD(ntru_private_key_t, decrypt, bool,
|
||||||
@ -172,7 +187,7 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
|||||||
chunk_t seed = chunk_empty;
|
chunk_t seed = chunk_empty;
|
||||||
ntru_trits_t *mask;
|
ntru_trits_t *mask;
|
||||||
ntru_poly_t *r_poly;
|
ntru_poly_t *r_poly;
|
||||||
bool success = TRUE;
|
bool msg_rep_good, success = TRUE;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*plaintext = chunk_empty;
|
*plaintext = chunk_empty;
|
||||||
@ -252,16 +267,17 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
|||||||
*/
|
*/
|
||||||
if (this->params->is_product_form)
|
if (this->params->is_product_form)
|
||||||
{
|
{
|
||||||
success = (abs(m1) <= this->params->min_msg_rep_wt);
|
msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
success = check_min_weight(cmprime_len, Mtrin,
|
msg_rep_good = ntru_check_min_weight(cmprime_len, Mtrin,
|
||||||
this->params->min_msg_rep_wt);
|
this->params->min_msg_rep_wt);
|
||||||
}
|
}
|
||||||
if (!success)
|
if (!msg_rep_good)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "decryption failed due to unsufficient minimum weight");
|
DBG1(DBG_LIB, "decryption failed due to unsufficient minimum weight");
|
||||||
|
success = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* form cR = e - cm' mod q */
|
/* form cR = e - cm' mod q */
|
||||||
@ -397,7 +413,9 @@ METHOD(ntru_private_key_t, decrypt, bool,
|
|||||||
if (t[i] != t2[i])
|
if (t[i] != t2[i])
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "cR' does not equal cR'");
|
DBG1(DBG_LIB, "cR' does not equal cR'");
|
||||||
|
chunk_clear(plaintext);
|
||||||
success = FALSE;
|
success = FALSE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memwipe(t, t_len);
|
memwipe(t, t_len);
|
||||||
@ -414,6 +432,7 @@ METHOD(ntru_private_key_t, destroy, void,
|
|||||||
private_ntru_private_key_t *this)
|
private_ntru_private_key_t *this)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->privkey);
|
DESTROY_IF(this->privkey);
|
||||||
|
this->drbg->destroy(this->drbg);
|
||||||
chunk_clear(&this->encoding);
|
chunk_clear(&this->encoding);
|
||||||
free(this->pubkey);
|
free(this->pubkey);
|
||||||
free(this);
|
free(this);
|
||||||
@ -622,7 +641,8 @@ static bool ring_inv(uint16_t *a, uint16_t N, uint16_t q, uint16_t *t,
|
|||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params)
|
ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg,
|
||||||
|
ntru_param_set_t *params)
|
||||||
{
|
{
|
||||||
private_ntru_private_key_t *this;
|
private_ntru_private_key_t *this;
|
||||||
size_t t_len;
|
size_t t_len;
|
||||||
@ -635,6 +655,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t
|
|||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
|
.get_id = _get_id,
|
||||||
.get_public_key = _get_public_key,
|
.get_public_key = _get_public_key,
|
||||||
.get_encoding = _get_encoding,
|
.get_encoding = _get_encoding,
|
||||||
.decrypt = _decrypt,
|
.decrypt = _decrypt,
|
||||||
@ -642,6 +663,7 @@ ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t
|
|||||||
},
|
},
|
||||||
.params = params,
|
.params = params,
|
||||||
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
||||||
|
.drbg = drbg->get_ref(drbg),
|
||||||
);
|
);
|
||||||
|
|
||||||
/* set hash algorithm and seed length based on security strength */
|
/* set hash algorithm and seed length based on security strength */
|
||||||
@ -742,4 +764,129 @@ err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg,
|
||||||
|
chunk_t data)
|
||||||
|
{
|
||||||
|
private_ntru_private_key_t *this;
|
||||||
|
size_t header_len, pubkey_packed_len, privkey_packed_len;
|
||||||
|
size_t privkey_packed_trits_len, privkey_packed_indices_len;
|
||||||
|
uint8_t *privkey_packed, tag;
|
||||||
|
uint16_t *indices, dF;
|
||||||
|
ntru_param_set_t *params;
|
||||||
|
|
||||||
|
header_len = 2 + NTRU_OID_LEN;
|
||||||
|
|
||||||
|
/* check the NTRU public key header format */
|
||||||
|
if (data.len < header_len ||
|
||||||
|
!(data.ptr[0] == NTRU_PRIVKEY_DEFAULT_TAG ||
|
||||||
|
data.ptr[0] == NTRU_PRIVKEY_TRITS_TAG ||
|
||||||
|
data.ptr[0] == NTRU_PRIVKEY_INDICES_TAG) ||
|
||||||
|
data.ptr[1] != NTRU_OID_LEN)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "loaded NTRU private key with invalid header");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tag = data.ptr[0];
|
||||||
|
params = ntru_param_set_get_by_oid(data.ptr + 2);
|
||||||
|
|
||||||
|
if (!params)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "loaded NTRU private key with unknown OID");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pubkey_packed_len = (params->N * params->q_bits + 7) / 8;
|
||||||
|
privkey_packed_trits_len = (params->N + 4) / 5;
|
||||||
|
|
||||||
|
/* check packing type for product-form private keys */
|
||||||
|
if (params->is_product_form && tag == NTRU_PRIVKEY_TRITS_TAG)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "a product-form NTRU private key cannot be trits-encoded");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set packed-key length for packed indices */
|
||||||
|
if (params->is_product_form)
|
||||||
|
{
|
||||||
|
dF = (uint16_t)((params->dF_r & 0xff) + /* df1 */
|
||||||
|
((params->dF_r >> 8) & 0xff) + /* df2 */
|
||||||
|
((params->dF_r >> 16) & 0xff)); /* df3 */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dF = (uint16_t)params->dF_r;
|
||||||
|
}
|
||||||
|
privkey_packed_indices_len = (2 * dF * params->N_bits + 7) / 8;
|
||||||
|
|
||||||
|
/* set private-key packing type if defaulted */
|
||||||
|
if (tag == NTRU_PRIVKEY_DEFAULT_TAG)
|
||||||
|
{
|
||||||
|
if (params->is_product_form ||
|
||||||
|
privkey_packed_indices_len <= privkey_packed_trits_len)
|
||||||
|
{
|
||||||
|
tag = NTRU_PRIVKEY_INDICES_TAG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tag = NTRU_PRIVKEY_TRITS_TAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
privkey_packed_len = (tag == NTRU_PRIVKEY_TRITS_TAG) ?
|
||||||
|
privkey_packed_trits_len : privkey_packed_indices_len;
|
||||||
|
|
||||||
|
if (data.len < header_len + pubkey_packed_len + privkey_packed_len)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "loaded NTRU private key with wrong packed key size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.get_id = _get_id,
|
||||||
|
.get_public_key = _get_public_key,
|
||||||
|
.get_encoding = _get_encoding,
|
||||||
|
.decrypt = _decrypt,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.params = params,
|
||||||
|
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
||||||
|
.encoding = chunk_clone(data),
|
||||||
|
.drbg = drbg->get_ref(drbg),
|
||||||
|
);
|
||||||
|
|
||||||
|
/* unpack the encoded public key */
|
||||||
|
ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len,
|
||||||
|
params->q_bits, this->pubkey);
|
||||||
|
|
||||||
|
/* allocate temporary memory for indices */
|
||||||
|
indices = malloc(2 * dF * sizeof(uint16_t));
|
||||||
|
|
||||||
|
/* unpack the private key */
|
||||||
|
privkey_packed = data.ptr + header_len + pubkey_packed_len;
|
||||||
|
if (tag == NTRU_PRIVKEY_TRITS_TAG)
|
||||||
|
{
|
||||||
|
ntru_packed_trits_2_indices(privkey_packed, params->N,
|
||||||
|
indices, indices + dF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ntru_octets_2_elements(privkey_packed_indices_len, privkey_packed,
|
||||||
|
params->N_bits, indices);
|
||||||
|
}
|
||||||
|
this->privkey = ntru_poly_create_from_data(indices, params->N, params->q,
|
||||||
|
params->dF_r, params->dF_r,
|
||||||
|
params->is_product_form);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
memwipe(indices, 2 * dF * sizeof(uint16_t));
|
||||||
|
free(indices);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create);
|
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create);
|
||||||
|
|
||||||
|
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data);
|
||||||
|
|||||||
@ -34,6 +34,12 @@ typedef struct ntru_private_key_t ntru_private_key_t;
|
|||||||
*/
|
*/
|
||||||
struct ntru_private_key_t {
|
struct ntru_private_key_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns NTRU parameter set ID of the private key
|
||||||
|
*
|
||||||
|
* @return NTRU parameter set ID
|
||||||
|
*/
|
||||||
|
ntru_param_set_id_t (*get_id)(ntru_private_key_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the NTRU encryption public key as an encoded binary blob
|
* Returns the NTRU encryption public key as an encoded binary blob
|
||||||
@ -73,6 +79,14 @@ struct ntru_private_key_t {
|
|||||||
*/
|
*/
|
||||||
ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params);
|
ntru_private_key_t *ntru_private_key_create(ntru_drbg_t *drbg, ntru_param_set_t *params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an NTRU encryption private key from encoding
|
||||||
|
*
|
||||||
|
* @param drbg Deterministic random bit generator
|
||||||
|
* @param data Encoded NTRU private key
|
||||||
|
*/
|
||||||
|
ntru_private_key_t *ntru_private_key_create_from_data(ntru_drbg_t *drbg,
|
||||||
|
chunk_t data);
|
||||||
|
|
||||||
#endif /** NTRU_PRIVATE_KEY_H_ @}*/
|
#endif /** NTRU_PRIVATE_KEY_H_ @}*/
|
||||||
|
|
||||||
|
|||||||
@ -16,10 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ntru_public_key.h"
|
#include "ntru_public_key.h"
|
||||||
|
#include "ntru_trits.h"
|
||||||
#include "ntru_crypto/ntru_crypto_ntru_convert.h"
|
#include "ntru_poly.h"
|
||||||
|
#include "ntru_convert.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
#include <utils/test.h>
|
||||||
|
|
||||||
typedef struct private_ntru_public_key_t private_ntru_public_key_t;
|
typedef struct private_ntru_public_key_t private_ntru_public_key_t;
|
||||||
|
|
||||||
@ -47,37 +49,268 @@ struct private_ntru_public_key_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t encoding;
|
chunk_t encoding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deterministic Random Bit Generator
|
||||||
|
*/
|
||||||
|
ntru_drbg_t *drbg;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
METHOD(ntru_public_key_t, get_id, ntru_param_set_id_t,
|
||||||
|
private_ntru_public_key_t *this)
|
||||||
|
{
|
||||||
|
return this->params->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate NTRU encryption public key encoding
|
||||||
|
*/
|
||||||
|
static void generate_encoding(private_ntru_public_key_t *this)
|
||||||
|
{
|
||||||
|
size_t pubkey_len;
|
||||||
|
u_char *enc;
|
||||||
|
|
||||||
|
/* compute public key length encoded as packed coefficients */
|
||||||
|
pubkey_len = (this->params->N * this->params->q_bits + 7) / 8;
|
||||||
|
|
||||||
|
/* allocate memory for public key encoding */
|
||||||
|
this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len);
|
||||||
|
enc = this->encoding.ptr;
|
||||||
|
|
||||||
|
/* format header and packed public key */
|
||||||
|
*enc++ = NTRU_PUBKEY_TAG;
|
||||||
|
*enc++ = NTRU_OID_LEN;
|
||||||
|
memcpy(enc, this->params->oid, NTRU_OID_LEN);
|
||||||
|
enc += NTRU_OID_LEN;
|
||||||
|
ntru_elements_2_octets(this->params->N, this->pubkey,
|
||||||
|
this->params->q_bits, enc);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(ntru_public_key_t, get_encoding, chunk_t,
|
METHOD(ntru_public_key_t, get_encoding, chunk_t,
|
||||||
private_ntru_public_key_t *this)
|
private_ntru_public_key_t *this)
|
||||||
{
|
{
|
||||||
if (!this->encoding.len)
|
|
||||||
{
|
|
||||||
size_t pubkey_len;
|
|
||||||
u_char *enc;
|
|
||||||
|
|
||||||
/* compute public key length encoded as packed coefficients */
|
|
||||||
pubkey_len = (this->params->N * this->params->q_bits + 7) / 8;
|
|
||||||
|
|
||||||
/* allocate memory for public key encoding */
|
|
||||||
this->encoding = chunk_alloc(2 + NTRU_OID_LEN + pubkey_len);
|
|
||||||
enc = this->encoding.ptr;
|
|
||||||
|
|
||||||
/* format header and packed public key */
|
|
||||||
*enc++ = NTRU_PUBKEY_TAG;
|
|
||||||
*enc++ = NTRU_OID_LEN;
|
|
||||||
memcpy(enc, this->params->oid, NTRU_OID_LEN);
|
|
||||||
enc += NTRU_OID_LEN;
|
|
||||||
ntru_elements_2_octets(this->params->N, this->pubkey,
|
|
||||||
this->params->q_bits, enc);
|
|
||||||
}
|
|
||||||
return this->encoding;
|
return this->encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_SEC_STRENGTH_LEN 32 /* bytes */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared with ntru_private_key.c
|
||||||
|
*/
|
||||||
|
extern bool ntru_check_min_weight(uint16_t N, uint8_t *t, uint16_t min_wt);
|
||||||
|
|
||||||
|
METHOD(ntru_public_key_t, encrypt, bool,
|
||||||
|
private_ntru_public_key_t *this, chunk_t plaintext, chunk_t *ciphertext)
|
||||||
|
{
|
||||||
|
hash_algorithm_t hash_algid;
|
||||||
|
size_t t_len, seed1_len, seed2_len;
|
||||||
|
uint16_t *t1, *t = NULL;
|
||||||
|
uint8_t b[MAX_SEC_STRENGTH_LEN];
|
||||||
|
uint8_t *t2, *Mtrin, *M, *mask_trits, *ptr;
|
||||||
|
uint16_t mod_q_mask, mprime_len = 0;
|
||||||
|
int16_t m1;
|
||||||
|
chunk_t seed = chunk_empty;
|
||||||
|
ntru_trits_t *mask;
|
||||||
|
ntru_poly_t *r_poly;
|
||||||
|
bool msg_rep_good, success = FALSE;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
*ciphertext = chunk_empty;
|
||||||
|
|
||||||
|
if (plaintext.len > this->params->m_len_max)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "plaintext exceeds maximum size");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->params->sec_strength_len > MAX_SEC_STRENGTH_LEN)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "required security strength exceeds %d bits",
|
||||||
|
MAX_SEC_STRENGTH_LEN * BITS_PER_BYTE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate temporary array t */
|
||||||
|
t_len = (sizeof(uint16_t) + 3*sizeof(uint8_t)) * this->params->N;
|
||||||
|
t = malloc(t_len);
|
||||||
|
t1 = t;
|
||||||
|
t2 = (uint8_t *)(t1 + this->params->N);
|
||||||
|
Mtrin = t2 + this->params->N;
|
||||||
|
M = Mtrin + this->params->N;
|
||||||
|
|
||||||
|
/* set hash algorithm based on security strength */
|
||||||
|
hash_algid = (this->params->sec_strength_len <= 20) ? HASH_SHA1 :
|
||||||
|
HASH_SHA256;
|
||||||
|
/* set constants */
|
||||||
|
mod_q_mask = this->params->q - 1;
|
||||||
|
|
||||||
|
/* allocate memory for the larger of the two seeds */
|
||||||
|
seed1_len = (this->params->N + 3)/4;
|
||||||
|
seed2_len = 3 + 2*this->params->sec_strength_len + plaintext.len;
|
||||||
|
seed = chunk_alloc(max(seed1_len, seed2_len));
|
||||||
|
|
||||||
|
/* loop until a message representative with proper weight is achieved */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!this->drbg->generate(this->drbg,
|
||||||
|
this->params->sec_strength_len * BITS_PER_BYTE,
|
||||||
|
this->params->sec_strength_len, b))
|
||||||
|
{
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* form sData (OID || m || b || hTrunc) */
|
||||||
|
ptr = seed.ptr;
|
||||||
|
memcpy(ptr, this->params->oid, NTRU_OID_LEN);
|
||||||
|
ptr += NTRU_OID_LEN;
|
||||||
|
memcpy(ptr, plaintext.ptr, plaintext.len);
|
||||||
|
ptr += plaintext.len;
|
||||||
|
memcpy(ptr, b, this->params->sec_strength_len);
|
||||||
|
ptr += this->params->sec_strength_len;
|
||||||
|
memcpy(ptr, this->encoding.ptr + 2 + NTRU_OID_LEN,
|
||||||
|
this->params->sec_strength_len);
|
||||||
|
ptr += this->params->sec_strength_len;
|
||||||
|
seed.len = seed2_len;
|
||||||
|
|
||||||
|
DBG2(DBG_LIB, "generate polynomial r");
|
||||||
|
r_poly = ntru_poly_create_from_seed(hash_algid, seed, this->params->c_bits,
|
||||||
|
this->params->N, this->params->q,
|
||||||
|
this->params->dF_r, this->params->dF_r,
|
||||||
|
this->params->is_product_form);
|
||||||
|
if (!r_poly)
|
||||||
|
{
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* form R = h * r */
|
||||||
|
r_poly->ring_mult(r_poly, this->pubkey, t1);
|
||||||
|
r_poly->destroy(r_poly);
|
||||||
|
|
||||||
|
/* form R mod 4 */
|
||||||
|
ntru_coeffs_mod4_2_octets(this->params->N, t1, seed.ptr);
|
||||||
|
seed.len = seed1_len;
|
||||||
|
|
||||||
|
/* form mask */
|
||||||
|
mask = ntru_trits_create(this->params->N, hash_algid, seed);
|
||||||
|
if (!mask)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "mask creation failed");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* form the padded message M */
|
||||||
|
ptr = M;
|
||||||
|
memcpy(ptr, b, this->params->sec_strength_len);
|
||||||
|
ptr += this->params->sec_strength_len;
|
||||||
|
if (this->params->m_len_len == 2)
|
||||||
|
{
|
||||||
|
*ptr++ = (uint8_t)((plaintext.len >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
*ptr++ = (uint8_t)(plaintext.len & 0xff);
|
||||||
|
memcpy(ptr, plaintext.ptr, plaintext.len);
|
||||||
|
ptr += plaintext.len;
|
||||||
|
|
||||||
|
/* add an extra zero byte in case without it the bit string
|
||||||
|
* is not a multiple of 3 bits and therefore might not be
|
||||||
|
* able to produce enough trits
|
||||||
|
*/
|
||||||
|
memset(ptr, 0, this->params->m_len_max - plaintext.len + 2);
|
||||||
|
|
||||||
|
/* convert M to trits (Mbin to Mtrin) */
|
||||||
|
mprime_len = this->params->N;
|
||||||
|
if (this->params->is_product_form)
|
||||||
|
{
|
||||||
|
--mprime_len;
|
||||||
|
}
|
||||||
|
ntru_bits_2_trits(M, mprime_len, Mtrin);
|
||||||
|
mask_trits = mask->get_trits(mask);
|
||||||
|
|
||||||
|
|
||||||
|
/* form the msg representative m' by adding Mtrin to mask, mod p */
|
||||||
|
if (this->params->is_product_form)
|
||||||
|
{
|
||||||
|
m1 = 0;
|
||||||
|
for (i = 0; i < mprime_len; i++)
|
||||||
|
{
|
||||||
|
t2[i] = mask_trits[i] + Mtrin[i];
|
||||||
|
if (t2[i] >= 3)
|
||||||
|
{
|
||||||
|
t2[i] -= 3;
|
||||||
|
}
|
||||||
|
if (t2[i] == 1)
|
||||||
|
{
|
||||||
|
++m1;
|
||||||
|
}
|
||||||
|
else if (t2[i] == 2)
|
||||||
|
{
|
||||||
|
--m1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0; i < mprime_len; i++)
|
||||||
|
{
|
||||||
|
t2[i] = mask_trits[i] + Mtrin[i];
|
||||||
|
if (t2[i] >= 3)
|
||||||
|
{
|
||||||
|
t2[i] -= 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mask->destroy(mask);
|
||||||
|
|
||||||
|
/* check that message representative meets minimum weight
|
||||||
|
* requirements
|
||||||
|
*/
|
||||||
|
if (this->params->is_product_form)
|
||||||
|
{
|
||||||
|
msg_rep_good = (abs(m1) <= this->params->min_msg_rep_wt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg_rep_good = ntru_check_min_weight(mprime_len, t2,
|
||||||
|
this->params->min_msg_rep_wt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!msg_rep_good);
|
||||||
|
|
||||||
|
/* form ciphertext e by adding m' to R mod q */
|
||||||
|
for (i = 0; i < mprime_len; i++)
|
||||||
|
{
|
||||||
|
if (t2[i] == 1)
|
||||||
|
{
|
||||||
|
t1[i] = (t1[i] + 1) & mod_q_mask;
|
||||||
|
}
|
||||||
|
else if (t2[i] == 2)
|
||||||
|
{
|
||||||
|
t1[i] = (t1[i] - 1) & mod_q_mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this->params->is_product_form)
|
||||||
|
{
|
||||||
|
t1[i] = (t1[i] - m1) & mod_q_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pack ciphertext */
|
||||||
|
*ciphertext = chunk_alloc((this->params->N * this->params->q_bits + 7) / 8);
|
||||||
|
ntru_elements_2_octets(this->params->N, t1, this->params->q_bits,
|
||||||
|
ciphertext->ptr);
|
||||||
|
|
||||||
|
memwipe(t, t_len);
|
||||||
|
success = TRUE;
|
||||||
|
|
||||||
|
err:
|
||||||
|
/* cleanup */
|
||||||
|
chunk_clear(&seed);
|
||||||
|
free(t);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
METHOD(ntru_public_key_t, destroy, void,
|
METHOD(ntru_public_key_t, destroy, void,
|
||||||
private_ntru_public_key_t *this)
|
private_ntru_public_key_t *this)
|
||||||
{
|
{
|
||||||
|
this->drbg->destroy(this->drbg);
|
||||||
chunk_clear(&this->encoding);
|
chunk_clear(&this->encoding);
|
||||||
free(this->pubkey);
|
free(this->pubkey);
|
||||||
free(this);
|
free(this);
|
||||||
@ -86,7 +319,8 @@ METHOD(ntru_public_key_t, destroy, void,
|
|||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
|
ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg,
|
||||||
|
ntru_param_set_t *params,
|
||||||
uint16_t *pubkey)
|
uint16_t *pubkey)
|
||||||
{
|
{
|
||||||
private_ntru_public_key_t *this;
|
private_ntru_public_key_t *this;
|
||||||
@ -94,11 +328,14 @@ ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
|
|||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
|
.get_id = _get_id,
|
||||||
.get_encoding = _get_encoding,
|
.get_encoding = _get_encoding,
|
||||||
|
.encrypt = _encrypt,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.params = params,
|
.params = params,
|
||||||
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
||||||
|
.drbg = drbg->get_ref(drbg),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (i = 0; i < params->N; i++)
|
for (i = 0; i < params->N; i++)
|
||||||
@ -106,5 +343,66 @@ ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
|
|||||||
this->pubkey[i] = pubkey[i];
|
this->pubkey[i] = pubkey[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* generate public key encoding */
|
||||||
|
generate_encoding(this);
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg,
|
||||||
|
chunk_t data)
|
||||||
|
{
|
||||||
|
private_ntru_public_key_t *this;
|
||||||
|
size_t header_len, pubkey_packed_len;
|
||||||
|
ntru_param_set_t *params;
|
||||||
|
|
||||||
|
header_len = 2 + NTRU_OID_LEN;
|
||||||
|
|
||||||
|
/* check the NTRU public key header format */
|
||||||
|
if (data.len < header_len ||
|
||||||
|
data.ptr[0] != NTRU_PUBKEY_TAG ||
|
||||||
|
data.ptr[1] != NTRU_OID_LEN)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "received NTRU public key with invalid header");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
params = ntru_param_set_get_by_oid(data.ptr + 2);
|
||||||
|
|
||||||
|
if (!params)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "received NTRU public key with unknown OID");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pubkey_packed_len = (params->N * params->q_bits + 7) / 8;
|
||||||
|
|
||||||
|
if (data.len < header_len + pubkey_packed_len)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "received NTRU public key with wrong packed key size");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.get_id = _get_id,
|
||||||
|
.get_encoding = _get_encoding,
|
||||||
|
.encrypt = _encrypt,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.params = params,
|
||||||
|
.pubkey = malloc(params->N * sizeof(uint16_t)),
|
||||||
|
.encoding = chunk_clone(data),
|
||||||
|
.drbg = drbg->get_ref(drbg),
|
||||||
|
);
|
||||||
|
|
||||||
|
/* unpack the encoded public key */
|
||||||
|
ntru_octets_2_elements(pubkey_packed_len, data.ptr + header_len,
|
||||||
|
params->q_bits, this->pubkey);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data);
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
typedef struct ntru_public_key_t ntru_public_key_t;
|
typedef struct ntru_public_key_t ntru_public_key_t;
|
||||||
|
|
||||||
#include "ntru_param_set.h"
|
#include "ntru_param_set.h"
|
||||||
|
#include "ntru_drbg.h"
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
|
||||||
@ -32,6 +33,13 @@ typedef struct ntru_public_key_t ntru_public_key_t;
|
|||||||
*/
|
*/
|
||||||
struct ntru_public_key_t {
|
struct ntru_public_key_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns NTRU parameter set ID of the public key
|
||||||
|
*
|
||||||
|
* @return NTRU parameter set ID
|
||||||
|
*/
|
||||||
|
ntru_param_set_id_t (*get_id)(ntru_public_key_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the packed encoding of the NTRU encryption public key
|
* Returns the packed encoding of the NTRU encryption public key
|
||||||
*
|
*
|
||||||
@ -39,6 +47,16 @@ struct ntru_public_key_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t (*get_encoding)(ntru_public_key_t *this);
|
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
|
* Destroy ntru_public_key_t object
|
||||||
*/
|
*/
|
||||||
@ -46,14 +64,25 @@ struct ntru_public_key_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an NTRU encryption public key
|
* Creates an NTRU encryption public key from coefficients
|
||||||
*
|
*
|
||||||
|
* @param drbg Deterministic random bit generator
|
||||||
* @param params NTRU encryption parameter set to be used
|
* @param params NTRU encryption parameter set to be used
|
||||||
* @param pubkey Coefficients of public key polynomial h
|
* @param pubkey Coefficients of public key polynomial h
|
||||||
*/
|
*/
|
||||||
ntru_public_key_t *ntru_public_key_create(ntru_param_set_t *params,
|
ntru_public_key_t *ntru_public_key_create(ntru_drbg_t *drbg,
|
||||||
|
ntru_param_set_t *params,
|
||||||
uint16_t *pubkey);
|
uint16_t *pubkey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an NTRU encryption public key from encoding
|
||||||
|
*
|
||||||
|
* @param drbg Deterministic random bit generator
|
||||||
|
* @param data Encoded NTRU public key
|
||||||
|
*/
|
||||||
|
ntru_public_key_t *ntru_public_key_create_from_data(ntru_drbg_t *drbg,
|
||||||
|
chunk_t data);
|
||||||
|
|
||||||
|
|
||||||
#endif /** NTRU_PUBLIC_KEY_H_ @}*/
|
#endif /** NTRU_PUBLIC_KEY_H_ @}*/
|
||||||
|
|
||||||
|
|||||||
@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
#include "ntru_trits.h"
|
#include "ntru_trits.h"
|
||||||
#include "ntru_mgf1.h"
|
#include "ntru_mgf1.h"
|
||||||
|
#include "ntru_convert.h"
|
||||||
#include "ntru_crypto/ntru_crypto_ntru_convert.h"
|
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
#include <utils/test.h>
|
#include <utils/test.h>
|
||||||
|
|||||||
@ -49,6 +49,12 @@ IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_param_set_get_by_id, ntru_param_set_t* ,
|
|||||||
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create, ntru_private_key_t*,
|
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create, ntru_private_key_t*,
|
||||||
ntru_drbg_t *drbg, ntru_param_set_t *params)
|
ntru_drbg_t *drbg, ntru_param_set_t *params)
|
||||||
|
|
||||||
|
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_private_key_create_from_data, ntru_private_key_t*,
|
||||||
|
ntru_drbg_t *drbg, chunk_t data)
|
||||||
|
|
||||||
|
IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_public_key_create_from_data, ntru_public_key_t*,
|
||||||
|
ntru_drbg_t *drbg, chunk_t data)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NTRU parameter sets to test
|
* NTRU parameter sets to test
|
||||||
*/
|
*/
|
||||||
@ -1086,22 +1092,74 @@ START_TEST(test_ntru_privkey)
|
|||||||
|
|
||||||
privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params);
|
privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params);
|
||||||
ck_assert(privkey);
|
ck_assert(privkey);
|
||||||
|
ck_assert(privkey->get_id(privkey) == privkey_tests[_i].id);
|
||||||
|
|
||||||
privkey_encoding = privkey->get_encoding(privkey);
|
privkey_encoding = privkey->get_encoding(privkey);
|
||||||
encoding = privkey_tests[_i].encoding;
|
encoding = privkey_tests[_i].encoding;
|
||||||
ck_assert(chunk_equals(privkey_encoding, encoding));
|
ck_assert(chunk_equals(privkey_encoding, encoding));
|
||||||
|
|
||||||
|
/* load private key as a packed blob */
|
||||||
pubkey= privkey->get_public_key(privkey);
|
privkey->destroy(privkey);
|
||||||
pubkey_encoding = pubkey->get_encoding(pubkey);
|
privkey = ntru_private_key_create_from_data(drbg, chunk_empty);
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
|
||||||
encoding = chunk_clone(encoding);
|
encoding = chunk_clone(encoding);
|
||||||
|
encoding.ptr[0] = NTRU_PUBKEY_TAG;
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
|
||||||
|
encoding.ptr[0] = NTRU_PRIVKEY_TRITS_TAG;
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
if (params->is_product_form)
|
||||||
|
{
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert(privkey != NULL);
|
||||||
|
privkey->destroy(privkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoding.ptr[0] = NTRU_PRIVKEY_INDICES_TAG;
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
if (params->is_product_form)
|
||||||
|
{
|
||||||
|
ck_assert(privkey != NULL);
|
||||||
|
privkey->destroy(privkey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
encoding.ptr[0] = NTRU_PRIVKEY_DEFAULT_TAG;
|
||||||
|
encoding.ptr[1] = NTRU_OID_LEN - 1;
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
|
||||||
|
encoding.ptr[1] = NTRU_OID_LEN;
|
||||||
|
encoding.ptr[2] = 0xff;
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
ck_assert(privkey == NULL);
|
||||||
|
|
||||||
|
encoding.ptr[2] = params->oid[0];
|
||||||
|
privkey = ntru_private_key_create_from_data(drbg, encoding);
|
||||||
|
privkey_encoding = privkey->get_encoding(privkey);
|
||||||
|
ck_assert(chunk_equals(privkey_encoding, encoding));
|
||||||
|
|
||||||
|
pubkey = privkey->get_public_key(privkey);
|
||||||
|
pubkey_encoding = pubkey->get_encoding(pubkey);
|
||||||
|
|
||||||
encoding.ptr[0] = NTRU_PUBKEY_TAG;
|
encoding.ptr[0] = NTRU_PUBKEY_TAG;
|
||||||
encoding.len = pubkey_encoding.len;
|
encoding.len = pubkey_encoding.len;
|
||||||
ck_assert(chunk_equals(pubkey_encoding, encoding));
|
ck_assert(chunk_equals(pubkey_encoding, encoding));
|
||||||
|
|
||||||
/* get encoding a second time without generating it again internally */
|
/* load public key as a packed blob */
|
||||||
|
pubkey->destroy(pubkey);
|
||||||
|
pubkey = ntru_public_key_create_from_data(drbg, encoding);
|
||||||
pubkey_encoding = pubkey->get_encoding(pubkey);
|
pubkey_encoding = pubkey->get_encoding(pubkey);
|
||||||
|
ck_assert(chunk_equals(pubkey_encoding, encoding));
|
||||||
|
|
||||||
chunk_free(&encoding);
|
chunk_free(&encoding);
|
||||||
privkey->destroy(privkey);
|
privkey->destroy(privkey);
|
||||||
pubkey->destroy(pubkey);
|
pubkey->destroy(pubkey);
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
A connection between the subnets behind the gateways <b>moon</b> and <b>sun</b> is set up.
|
||||||
|
The key exchange is based on NTRU encryption with a security strength of 128 bits.
|
||||||
|
The ANSI X9.98 NTRU encryption parameter set used is optimized for bandwidth.
|
||||||
|
<p/>
|
||||||
|
The authentication is based on <b>X.509 certificates</b>. Upon the successful
|
||||||
|
establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically
|
||||||
|
inserts iptables-based firewall rules that let pass the tunneled traffic.
|
||||||
|
In order to test both tunnel and firewall, client <b>alice</b> behind gateway <b>moon</b>
|
||||||
|
pings client <b>bob</b> located behind gateway <b>sun</b>.
|
||||||
9
testing/tests/ikev2/net2net-ntru-bandwidth/evaltest.dat
Normal file
9
testing/tests/ikev2/net2net-ntru-bandwidth/evaltest.dat
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
moon::ipsec status 2> /dev/null::net-net.*ESTABLISHED.*moon.strongswan.org.*sun.strongswan.org::YES
|
||||||
|
sun:: ipsec status 2> /dev/null::net-net.*ESTABLISHED.*sun.strongswan.org.*moon.strongswan.org::YES
|
||||||
|
moon::ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
|
||||||
|
sun:: ipsec status 2> /dev/null::net-net.*INSTALLED, TUNNEL::YES
|
||||||
|
moon::ipsec statusall 2> /dev/null::net-net.*IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
|
||||||
|
sun::ipsec statusall 2> /dev/null::net-net.*IKE proposal: AES_CBC_128/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/NTRU_128::YES
|
||||||
|
alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_req=1::YES
|
||||||
|
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
|
||||||
|
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
charondebug="ike 4, lib 4"
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
ikelifetime=60m
|
||||||
|
keylife=20m
|
||||||
|
rekeymargin=3m
|
||||||
|
keyingtries=1
|
||||||
|
keyexchange=ikev2
|
||||||
|
ike=aes128-sha256-ntru128!
|
||||||
|
esp=aes128-sha256!
|
||||||
|
mobike=no
|
||||||
|
|
||||||
|
conn net-net
|
||||||
|
left=PH_IP_MOON
|
||||||
|
leftcert=moonCert.pem
|
||||||
|
leftid=@moon.strongswan.org
|
||||||
|
leftsubnet=10.1.0.0/16
|
||||||
|
leftfirewall=yes
|
||||||
|
right=PH_IP_SUN
|
||||||
|
rightid=@sun.strongswan.org
|
||||||
|
rightsubnet=10.2.0.0/16
|
||||||
|
auto=add
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 ntru revocation hmac stroke kernel-netlink socket-default updown
|
||||||
|
|
||||||
|
multiple_authentication = no
|
||||||
|
send_vendor_id = yes
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
ntru {
|
||||||
|
parameter_set = x9_98_bandwidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
# /etc/ipsec.conf - strongSwan IPsec configuration file
|
||||||
|
|
||||||
|
config setup
|
||||||
|
charondebug="ike 4, lib 4"
|
||||||
|
|
||||||
|
conn %default
|
||||||
|
ikelifetime=60m
|
||||||
|
keylife=20m
|
||||||
|
rekeymargin=3m
|
||||||
|
keyingtries=1
|
||||||
|
keyexchange=ikev2
|
||||||
|
ike=aes128-sha256-ntru128!
|
||||||
|
esp=aes128-sha256!
|
||||||
|
mobike=no
|
||||||
|
|
||||||
|
conn net-net
|
||||||
|
left=PH_IP_SUN
|
||||||
|
leftcert=sunCert.pem
|
||||||
|
leftid=@sun.strongswan.org
|
||||||
|
leftsubnet=10.2.0.0/16
|
||||||
|
leftfirewall=yes
|
||||||
|
right=PH_IP_MOON
|
||||||
|
rightid=@moon.strongswan.org
|
||||||
|
rightsubnet=10.1.0.0/16
|
||||||
|
auto=add
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
# /etc/strongswan.conf - strongSwan configuration file
|
||||||
|
|
||||||
|
charon {
|
||||||
|
load = curl aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 ntru revocation hmac stroke kernel-netlink socket-default updown
|
||||||
|
|
||||||
|
multiple_authentication = no
|
||||||
|
send_vendor_id = yes
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
ntru {
|
||||||
|
parameter_set = x9_98_bandwidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
testing/tests/ikev2/net2net-ntru-bandwidth/posttest.dat
Normal file
5
testing/tests/ikev2/net2net-ntru-bandwidth/posttest.dat
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
moon::ipsec stop
|
||||||
|
sun::ipsec stop
|
||||||
|
moon::iptables-restore < /etc/iptables.flush
|
||||||
|
sun::iptables-restore < /etc/iptables.flush
|
||||||
|
|
||||||
6
testing/tests/ikev2/net2net-ntru-bandwidth/pretest.dat
Normal file
6
testing/tests/ikev2/net2net-ntru-bandwidth/pretest.dat
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
moon::iptables-restore < /etc/iptables.rules
|
||||||
|
sun::iptables-restore < /etc/iptables.rules
|
||||||
|
moon::ipsec start
|
||||||
|
sun::ipsec start
|
||||||
|
moon::sleep 1
|
||||||
|
moon::ipsec up net-net
|
||||||
21
testing/tests/ikev2/net2net-ntru-bandwidth/test.conf
Normal file
21
testing/tests/ikev2/net2net-ntru-bandwidth/test.conf
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This configuration file provides information on the
|
||||||
|
# guest instances used for this test
|
||||||
|
|
||||||
|
# All guest instances that are required for this test
|
||||||
|
#
|
||||||
|
VIRTHOSTS="alice moon winnetou sun bob"
|
||||||
|
|
||||||
|
# Corresponding block diagram
|
||||||
|
#
|
||||||
|
DIAGRAM="a-m-w-s-b.png"
|
||||||
|
|
||||||
|
# Guest instances on which tcpdump is to be started
|
||||||
|
#
|
||||||
|
TCPDUMPHOSTS="sun"
|
||||||
|
|
||||||
|
# Guest instances on which IPsec is started
|
||||||
|
# Used for IPsec logging purposes
|
||||||
|
#
|
||||||
|
IPSECHOSTS="moon sun"
|
||||||
Loading…
x
Reference in New Issue
Block a user