[PATCH] Add NTRUEncrypt public key encryption algorithm
Zhenfei Zhang
zzhang at securityinnovation.com
Tue Sep 8 20:45:33 CEST 2015
Hi list,
I wish to contribute this patch to the libgcrypt.
Can I please ask what is the right approach to get this patch included in a
release?
Thanks.
Signed-off-by: Zhenfei Zhang <zzhang at securityinnovation.com>.
Commit attached. Can also be found at
https://github.com/wwhyte-si/libgcrypt-ntru/commit/1cec836ec7fded3284c769b05daf4eb285527b38
On Wed, Aug 5, 2015 at 10:35 AM, Zhenfei Zhang <
zzhang at securityinnovation.com> wrote:
> Hi all,
>
> This is a patch to enable NTRUEncrypt public key encryption algorithm for
> libgcrypt.
> Here is the link to the commit:
>
> https://github.com/wwhyte-si/libgcrypt-ntru/commit/1cec836ec7fded3284c769b05daf4eb285527b38
>
> PS: I am new to big projects like this. So please let me know if this is
> not the correct way to do it.
>
> Cheers,
> Zhenfei
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/attachments/20150908/c12dbf7e/attachment-0001.html>
-------------- next part --------------
diff --git a/.gitignore b/.gitignore
index 3929e4d..db863dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,3 +84,6 @@ tests/rsacvt
tests/t-mpi-bit
tests/tsexp
tests/version
+*~
+sample/a.out
+.*
diff --git a/README b/README
index 938c6c6..0dc0509 100644
--- a/README
+++ b/README
@@ -36,6 +36,10 @@
You should get the latest versions of course.
+ To build libgcrypt with NTRU public key crypto:
+ https://github.com/NTRUOpenSourceProject/ntru-crypto
+
+
After building and installing the libgpg-error package, you may
continue with Libgcrypt installation as with allmost all GNU
packages, you just have to do
@@ -185,8 +189,11 @@
the feature under the assumption that either good
CFLAGS are given or the compiler can grok the code.
-
-
+ --enable-ntru
+ This let libgcrypt to link against libntruencrypt.
+ To check if it is linked propoerly, run the sample
+ code from sample/test_ntru_gcrypt.cpp.
+
Build Problems
--------------
diff --git a/README_NTRU b/README_NTRU
new file mode 100644
index 0000000..e8b1aa4
--- /dev/null
+++ b/README_NTRU
@@ -0,0 +1,18 @@
+ libgcrypt : enabling NTRUEncrypt for libgcrypt
+ -------------------------------------------------------
+
+Dependency:
+ libntruencrypt 1.0.0
+ https://github.com/NTRUOpenSourceProject/ntru-crypto
+
+Installation:
+
+ ./autogen.sh
+ ./configure --enable-maintainer-mode --enable-ntru
+ make
+ sudo make install
+
+Example code:
+ cd sample
+ g++ test_ntru_gcrypt.cpp -lgcrypt -o test.o
+ ./test.o
diff --git a/autogen.rc b/autogen.rc
index 09a9b9c..1e800f6 100644
--- a/autogen.rc
+++ b/autogen.rc
@@ -14,4 +14,4 @@ case "$myhost" in
;;
esac
-final_info="./configure --enable-maintainer-mode && make"
+final_info="./configure --enable-maintainer-mode --enable-ntru && make"
diff --git a/autogen.sh b/autogen.sh
index 471193c..d8da839 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -277,7 +277,7 @@ if [ "$myhost" = "amd64" ]; then
fi
fi
- $tsdir/configure --enable-maintainer-mode ${SILENT} \
+ $tsdir/configure --enable-maintainer-mode --enable-ntru ${SILENT} \
--prefix=${amd64root} \
--host=${host} --build=${build} \
${configure_opts} ${extraoptions} "$@"
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 33a68ff..c82f8d5 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -57,9 +57,13 @@ bufhelp.h \
primegen.c \
hash-common.c hash-common.h \
dsa-common.c rsa-common.c \
+base64.c \
+base64.h \
rmd.h
EXTRA_libcipher_la_SOURCES = \
+ntru-gcrypt-wrapper.c \
+ntru-gcrypt-wrapper.h \
arcfour.c arcfour-amd64.S \
blowfish.c blowfish-amd64.S blowfish-arm.S \
cast5.c cast5-amd64.S cast5-arm.S \
diff --git a/cipher/base64.c b/cipher/base64.c
new file mode 100644
index 0000000..cfedfb9
--- /dev/null
+++ b/cipher/base64.c
@@ -0,0 +1,295 @@
+/*
+ * RFC 1521 base64 encoding/decoding
+ *
+ * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ * 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.
+ */
+
+/*#if !defined(POLARSSL_CONFIG_FILE)
+#include "polarssl/config.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_BASE64_C)
+
+#include "polarssl/base64.h"
+
+#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
+#include <basetsd.h>
+typedef UINT32 uint32_t;
+#else
+#include <inttypes.h>
+#endif
+
+#if defined(POLARSSL_SELF_TEST)
+#include <string.h>
+#if defined(POLARSSL_PLATFORM_C)
+#include "polarssl/platform.h"
+#else
+#include <stdio.h>
+#define polarssl_printf printf
+#endif /* POLARSSL_PLATFORM_C */
+//#endif /* POLARSSL_SELF_TEST */
+
+
+#include "base64.h"
+#include <unistd.h>
+
+
+static const unsigned char base64_enc_map[64] =
+{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+};
+
+static const unsigned char base64_dec_map[128] =
+{
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
+ 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 127, 127, 127, 127, 127
+};
+
+/*
+ * Encode a buffer into base64 format
+ */
+int base64_encode( unsigned char *dst, size_t *dlen,
+ const unsigned char *src, size_t slen )
+{
+ size_t i, n;
+ int C1, C2, C3;
+ unsigned char *p;
+
+ if( slen == 0 )
+ {
+ *dlen = 0;
+ return( 0 );
+ }
+ n = ( slen << 3 ) / 6;
+
+ switch( ( slen << 3 ) - ( n * 6 ) )
+ {
+ case 2: n += 3; break;
+ case 4: n += 2; break;
+ default: break;
+ }
+
+ if( *dlen < n + 1 )
+ {
+ *dlen = n + 1;
+ return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
+ }
+
+ n = ( slen / 3 ) * 3;
+
+ for( i = 0, p = dst; i < n; i += 3 )
+ {
+ C1 = *src++;
+ C2 = *src++;
+ C3 = *src++;
+
+ *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+ *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+ *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
+ *p++ = base64_enc_map[C3 & 0x3F];
+ }
+
+ if( i < slen )
+ {
+ C1 = *src++;
+ C2 = ( ( i + 1 ) < slen ) ? *src++ : 0;
+
+ *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+ *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+
+ if( ( i + 1 ) < slen )
+ *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+ else *p++ = '=';
+
+ *p++ = '=';
+ }
+
+ *dlen = p - dst;
+ *p = 0;
+
+ return( 0 );
+}
+
+/*
+ * Decode a base64-formatted buffer
+ */
+int base64_decode( unsigned char *dst, size_t *dlen,
+ const unsigned char *src, size_t slen )
+{
+ size_t i, n;
+ uint32_t j, x;
+ unsigned char *p;
+
+ /* First pass: check for validity and get output length */
+ for( i = n = j = 0; i < slen; i++ )
+ {
+ /* Skip spaces before checking for EOL */
+ x = 0;
+ while( i < slen && src[i] == ' ' )
+ {
+ ++i;
+ ++x;
+ }
+
+ /* Spaces at end of buffer are OK */
+ if( i == slen )
+ break;
+
+ if( ( slen - i ) >= 2 &&
+ src[i] == '\r' && src[i + 1] == '\n' )
+ continue;
+
+ if( src[i] == '\n' )
+ continue;
+
+ /* Space inside a line is an error */
+ if( x != 0 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ if( src[i] == '=' && ++j > 2 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ if( base64_dec_map[src[i]] < 64 && j != 0 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ n++;
+ }
+
+ if( n == 0 )
+ return( 0 );
+
+ n = ( ( n * 6 ) + 7 ) >> 3;
+ n -= j;
+
+ if( dst == NULL || *dlen < n )
+ {
+ *dlen = n;
+ return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
+ }
+
+ for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
+ {
+ if( *src == '\r' || *src == '\n' || *src == ' ' )
+ continue;
+
+ j -= ( base64_dec_map[*src] == 64 );
+ x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F );
+
+ if( ++n == 4 )
+ {
+ n = 0;
+ if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
+ if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
+ if( j > 2 ) *p++ = (unsigned char)( x );
+ }
+ }
+
+ *dlen = p - dst;
+
+ return( 0 );
+}
+
+#if defined(POLARSSL_SELF_TEST)
+
+static const unsigned char base64_test_dec[64] =
+{
+ 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
+ 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
+ 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
+ 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
+ 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
+ 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
+ 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
+ 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
+};
+
+static const unsigned char base64_test_enc[] =
+ "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
+ "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
+
+/*
+ * Checkup routine
+ */
+int base64_self_test( int verbose )
+{
+ size_t len;
+ const unsigned char *src;
+ unsigned char buffer[128];
+
+ if( verbose != 0 )
+ polarssl_printf( " Base64 encoding test: " );
+
+ len = sizeof( buffer );
+ src = base64_test_dec;
+
+ if( base64_encode( buffer, &len, src, 64 ) != 0 ||
+ memcmp( base64_test_enc, buffer, 88 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n Base64 decoding test: " );
+
+ len = sizeof( buffer );
+ src = base64_test_enc;
+
+ if( base64_decode( buffer, &len, src, 88 ) != 0 ||
+ memcmp( base64_test_dec, buffer, 64 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n\n" );
+
+ return( 0 );
+}
+
+#endif /* POLARSSL_SELF_TEST */
+
+//#endif /* POLARSSL_BASE64_C */
diff --git a/cipher/base64.h b/cipher/base64.h
new file mode 100644
index 0000000..2fd1ac6
--- /dev/null
+++ b/cipher/base64.h
@@ -0,0 +1,86 @@
+/**
+ * \file base64.h
+ *
+ * \brief RFC 1521 base64 encoding/decoding
+ *
+ * Copyright (C) 2006-2013, ARM Limited, All Rights Reserved
+ *
+ * This file is part of mbed TLS (https://tls.mbed.org)
+ *
+ * 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 POLARSSL_BASE64_H
+#define POLARSSL_BASE64_H
+
+#include <stddef.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Encode a buffer into base64 format
+ *
+ * \param dst destination buffer
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be encoded
+ *
+ * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
+ * *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dlen = 0 to obtain the
+ * required buffer size in *dlen
+ */
+int base64_encode( unsigned char *dst, size_t *dlen,
+ const unsigned char *src, size_t slen );
+
+/**
+ * \brief Decode a base64-formatted buffer
+ *
+ * \param dst destination buffer (can be NULL for checking size)
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be decoded
+ *
+ * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
+ * POLARSSL_ERR_BASE64_INVALID_CHARACTER if the input data is
+ * not correct. *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dst = NULL or *dlen = 0 to obtain
+ * the required buffer size in *dlen
+ */
+int base64_decode( unsigned char *dst, size_t *dlen,
+ const unsigned char *src, size_t slen );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int base64_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* base64.h */
diff --git a/cipher/ntru-gcrypt-wrapper.c b/cipher/ntru-gcrypt-wrapper.c
new file mode 100644
index 0000000..28d35e2
--- /dev/null
+++ b/cipher/ntru-gcrypt-wrapper.c
@@ -0,0 +1,459 @@
+/* ntru-grcrypt-wrapper.h
+ * Copyright (C) 2015, Security Innovation.
+ * Author Zhenfei Zhang <zzhang at securityinnovation.com>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code is a wrapper for libgcrypt to be linked with libntruencrypt
+ * NTRUEncrypt is a lattice-based public key encryption algorithm.
+ * For the latest version of the NTRUEncrypt specs, visit
+ * https://github.com/NTRUOpenSourceProject/NTRUEncrypt
+ */
+
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "gcrypt.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "gcrypt-int.h"
+#include "base64.h"
+#include <libntruencrypt/ntru_crypto.h>
+#include "ntru-gcrypt-wrapper.h"
+
+static const char *ntru_names[] =
+{
+ "ntru",
+ NULL,
+};
+
+gcry_pk_spec_t _gcry_pubkey_spec_ntru = {
+ GCRY_PK_NTRU, // algo;
+ {0,0}, // struct {
+ // unsigned int disabled:1;
+ // unsigned int fips:1;
+ // } flags;
+ GCRY_PK_USAGE_ENCR, // int use;
+ "ntru", // const char *name;
+ ntru_names, // const char **aliases;
+ NULL, // const char *elements_pkey;
+ NULL, // const char *elements_skey;
+ NULL, // const char *elements_enc;
+ NULL, // const char *elements_sig;
+ NULL, // const char *elements_grip;
+ gcry_ntru_keygen, // gcry_pk_generate_t generate;
+ gcry_ntru_check_secret_key, // gcry_pk_check_secret_key_t check_secret_key;
+ gcry_ntru_encrypt, // gcry_pk_encrypt_t encrypt;
+ gcry_ntru_decrypt, // gcry_pk_decrypt_t decrypt;
+ NULL, // gcry_pk_sign_t sign;
+ NULL, // gcry_pk_verify_t verify;
+ gcry_ntru_get_nbits, // gcry_pk_get_nbits_t get_nbits;
+ NULL, // selftest_func_t selftest;
+ gcry_ntru_comp_keygrip, // pk_comp_keygrip_t comp_keygrip;
+ NULL, // pk_get_curve_t get_curve;
+ NULL // pk_get_curve_param_t get_curve_param;
+};
+
+static gpg_err_code_t gcry_ntru_comp_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
+{
+ fprintf (stderr,"NTRU compute keygrip function not required/implemented\n");
+ return 0;
+}
+
+static unsigned int gcry_ntru_get_nbits (gcry_sexp_t parms)
+{
+ fprintf (stderr,"NTRU get nbits function not required/implemented\n");
+ return 0;
+}
+static gcry_err_code_t gcry_ntru_check_secret_key (gcry_sexp_t keyparms)
+{
+ fprintf (stderr,"NTRU check secret key function not required/implemented\n");
+ return 0;
+}
+
+
+NTRU_ENCRYPT_PARAM_SET_ID gcry_ntru_get_param_id (gcry_sexp_t genparms)
+{
+ if ((_gcry_sexp_find_token(genparms, "n439", 4)!= NULL) ||
+ (_gcry_sexp_find_token(genparms, "b128", 4)!= NULL))
+ return NTRU_EES439EP1;
+
+ if ((_gcry_sexp_find_token(genparms, "n593", 4)!= NULL) ||
+ (_gcry_sexp_find_token(genparms, "b192", 4)!= NULL))
+ return NTRU_EES593EP1;
+
+ if ((_gcry_sexp_find_token(genparms, "n743", 4)!= NULL) ||
+ (_gcry_sexp_find_token(genparms, "b256", 4)!= NULL))
+ return NTRU_EES743EP1;
+
+ return -1;
+}
+
+
+/* Type for the pk_generate function. */
+// typedef gcry_err_code_t (*gcry_pk_generate_t) (gcry_sexp_t genparms,
+// gcry_sexp_t *r_skey);
+gcry_err_code_t gcry_ntru_keygen (gcry_sexp_t genparms, gcry_sexp_t *r_skey)
+{
+
+ NTRU_ENCRYPT_PARAM_SET_ID paramid;
+ int rc; /* return code */
+ uint8_t *public_key; /* sized for EES401EP2 */
+ uint16_t public_key_len; /* no. of octets in public key */
+ uint8_t *private_key; /* sized for EES401EP2 */
+ uint16_t private_key_len; /* no. of octets in private key */
+ DRBG_HANDLE drbg; /* handle for instantiated DRBG */
+ uint8_t *pers_str;
+ gcry_sexp_t temp_pk, temp_sk;
+
+ /* start key generation */
+ paramid = gcry_ntru_get_param_id (genparms);
+
+ if (paramid <0)
+ {
+ fprintf (stderr, "gcry_ntru: unrecognized parameter id\n");
+ return -1;
+ }
+/*
+ if (paramid == NTRU_EES439EP1)
+ printf("using NTRU_EES439EP1\n");
+ if (paramid == NTRU_EES593EP1)
+ printf("using NTRU_EES593EP1\n");
+ if (paramid == NTRU_EES743EP1)
+ printf("using NTRU_EES743EP1\n");
+*/
+ /* optional personal string for DRBG */
+ /* use this prg for best security */
+// pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_STRONG_RANDOM);
+ /* use this one to improve performance */
+ pers_str = (uint8_t*)_gcry_random_bytes (32, GCRY_WEAK_RANDOM);
+
+
+ public_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ private_key = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+
+ memset(public_key, 0, _MAX_NTRU_BUF_SIZE_);
+ memset(private_key, 0, _MAX_NTRU_BUF_SIZE_);
+
+ /* generating NTRU keys */
+
+ rc = ntru_crypto_drbg_instantiate(256, pers_str, sizeof(pers_str), (ENTROPY_FN) &get_entropy, &drbg);
+ if (rc!=0)
+ {
+ fprintf (stderr, "drbg error, ntru code: %d\n", rc);
+ return rc;
+ }
+ rc = ntru_crypto_ntru_encrypt_keygen(drbg, paramid , &public_key_len, NULL, &private_key_len, NULL);
+ if (rc!=0)
+ {
+ fprintf (stderr, "key gen error, ntru code: %d\n", rc);
+ return rc;
+ }
+ rc = ntru_crypto_ntru_encrypt_keygen(drbg, paramid , &public_key_len, public_key, &private_key_len, private_key);
+ if (rc!=0)
+ {
+ fprintf (stderr, "key gen error, ntru code: %d\n", rc);
+ return rc;
+ }
+
+ /* extract the key pair */
+ temp_pk = convert_ntru_data_to_sexp (public_key, public_key_len);
+ temp_sk = convert_ntru_data_to_sexp (private_key, private_key_len);
+ rc = _gcry_sexp_build (r_skey, NULL,
+ "(key-data(public-key(ntru%S))(private-key(ntru%S)))", temp_pk, temp_sk);
+ if (rc!=0)
+ {
+ fprintf (stderr, "gcry_sexp_build error: %s\n", _gcry_strerror (rc));
+ return rc;
+ }
+
+// _gcry_sexp_dump(*r_skey);
+
+ /* cleaning up */
+ rc = ntru_crypto_drbg_uninstantiate(drbg);
+ if (rc!=0)
+ {
+ fprintf (stderr, "drbg error, ntru code: %d\n", rc);
+ return rc;
+ }
+ free(public_key);
+ free(private_key);
+ free(pers_str);
+ xfree(temp_sk);
+ xfree(temp_pk);
+ return rc;
+}
+
+/* Type for the pk_encrypt function. */
+// typedef gcry_err_code_t (*gcry_pk_encrypt_t) (gcry_sexp_t *r_ciph,
+// gcry_sexp_t s_data,
+// gcry_sexp_t keyparms);
+gcry_err_code_t gcry_ntru_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ uint8_t rc;
+ uint8_t *msg_buf;
+ uint8_t *key_buf;
+ uint8_t *working_buf;
+ size_t msg_len;
+ size_t key_len;
+ size_t working_buf_len;
+ DRBG_HANDLE drbg;
+
+ working_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ msg_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ key_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ memset(msg_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ memset(key_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ memset(working_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ msg_len = _MAX_NTRU_BUF_SIZE_;
+ key_len = _MAX_NTRU_BUF_SIZE_;
+ working_buf_len = _MAX_NTRU_BUF_SIZE_;
+
+ /* extracting the message */
+ msg_buf = _gcry_sexp_nth_data (_gcry_sexp_find_token(s_data, "value", 0), 1, &msg_len);
+ /* extracting the public key; removing ntru header */
+ working_buf = _gcry_sexp_nth_data (_gcry_sexp_cadr (keyparms), 0, &working_buf_len);
+ base64_decode(key_buf, &key_len, working_buf+4, working_buf_len-4);
+
+ /* performing ntru encryption */
+ rc = ntru_crypto_drbg_instantiate(256, NULL, 0, (ENTROPY_FN) &get_entropy, &drbg);
+ if (rc!=0)
+ {
+ fprintf (stderr, "drbg error, ntru code: %d\n", rc);
+ return rc;
+ }
+ rc = ntru_crypto_ntru_encrypt(drbg, key_len, key_buf, msg_len, msg_buf, &working_buf_len, NULL);
+ if (rc!=0)
+ {
+ fprintf (stderr, "encryption error, ntru code: %d\n", rc);
+ return rc;
+ }
+ rc = ntru_crypto_ntru_encrypt(drbg, key_len, key_buf, msg_len, msg_buf, &working_buf_len, working_buf);
+ if (rc!=0)
+ {
+ fprintf (stderr, "encryption error, ntru code: %d\n", rc);
+ return rc;
+ }
+
+ *r_ciph = convert_ntru_data_to_sexp (working_buf, working_buf_len);
+// _gcry_sexp_dump(*r_ciph);
+
+ /* cleaning up */
+ rc = ntru_crypto_drbg_uninstantiate(drbg);
+ if (rc!=0)
+ {
+ fprintf (stderr, "drbg error, ntru code: %d\n", rc);
+ return rc;
+ }
+ free(key_buf);
+// free(working_buf);
+// free(msg_buf);
+ return rc;
+}
+
+
+
+/* Type for the pk_decrypt function. */
+// typedef gcry_err_code_t (*gcry_pk_decrypt_t) (gcry_sexp_t *r_plain,
+// gcry_sexp_t s_data,
+// gcry_sexp_t keyparms);
+gcry_err_code_t gcry_ntru_decrypt (gcry_sexp_t *r_msg, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+{
+ int rc;
+ uint8_t *cipher_buf;
+ uint8_t *key_buf;
+ uint8_t *working_buf;
+ size_t cipher_len;
+ size_t key_len;
+ size_t working_buf_len;
+ gcry_sexp_t key;
+
+ working_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ cipher_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ key_buf = (uint8_t *) malloc (_MAX_NTRU_BUF_SIZE_);
+ memset(cipher_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ memset(key_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ memset(working_buf, 0, _MAX_NTRU_BUF_SIZE_);
+ cipher_len = _MAX_NTRU_BUF_SIZE_;
+ key_len = _MAX_NTRU_BUF_SIZE_;
+ working_buf_len = _MAX_NTRU_BUF_SIZE_;
+
+ /* extracting the cipher; removing ntru header */
+ working_buf = _gcry_sexp_nth_data (s_data, 0, &working_buf_len);
+ base64_decode(cipher_buf, &cipher_len, working_buf+4, working_buf_len-4);
+
+ /* extracting the private key; removing ntru header */
+ key = _gcry_sexp_cadr (keyparms);
+ working_buf = _gcry_sexp_nth_data (key, 0, &working_buf_len);
+ base64_decode(key_buf, &key_len, working_buf+4, working_buf_len-4);
+
+ /* performing ntru decryption */
+ rc = ntru_crypto_ntru_decrypt(key_len, key_buf, cipher_len, cipher_buf, &working_buf_len, NULL);
+ if (rc!=0)
+ {
+ fprintf (stderr, "decryption error, ntru code: %d\n", rc);
+ return rc;
+ }
+ rc = ntru_crypto_ntru_decrypt(key_len, key_buf, cipher_len, cipher_buf, &working_buf_len, working_buf);
+ if (rc!=0)
+ {
+ fprintf (stderr, "decryption error, ntru code: %d\n", rc);
+ return rc;
+ }
+ working_buf[working_buf_len] = '\0';
+ rc = _gcry_sexp_build (r_msg, NULL, "%s", working_buf);
+ if (rc!=0)
+ {
+ fprintf (stderr, "gcry_sexp_build error: %s\n", _gcry_strerror (rc));
+ return rc;
+ }
+ /* cleaning up */
+ free(cipher_buf);
+ free(key_buf);
+ xfree(key);
+ return rc;
+}
+
+/*
+ * convert an ntru blob in ntru_data to a s-expression:
+ * 1. convert ASCII coded ntru blob into base64 encoding string
+ * 2. add guard string "NTRU" to the start of the string
+ * (if the base64 encoded string starts with a non-alphabetic
+ * char, sexp builder will bug)
+ * 3. form the sexp
+ */
+gcry_sexp_t convert_ntru_data_to_sexp (const uint8_t* ntru_data, const size_t ntru_data_len)
+{
+ gcry_sexp_t sexp_data;
+ uint8_t *base64_data;
+ size_t base64_data_len = _MAX_NTRU_BUF_SIZE_;
+ uint8_t *tmp_str;
+ int rc;
+ base64_data = (uint8_t*) malloc (ntru_data_len*2*sizeof(uint8_t));
+ tmp_str = (uint8_t*) malloc ((base64_data_len+2)*sizeof(uint8_t));
+
+ rc = base64_encode(base64_data, &base64_data_len, ntru_data, ntru_data_len);
+
+ tmp_str[0] = '(';
+ tmp_str[1] = 'N';
+ tmp_str[2] = 'T';
+ tmp_str[3] = 'R';
+ tmp_str[4] = 'U';
+ memcpy(tmp_str+5, base64_data, base64_data_len*sizeof(uint8_t));
+ tmp_str[base64_data_len+5] = ')';
+ tmp_str[base64_data_len+6] = '\0';
+
+ rc = _gcry_sexp_sscan (&sexp_data, NULL, tmp_str, strlen(tmp_str));
+ if (rc!=0)
+ {
+ fprintf (stderr, "gcry_sexp_new: %s\n", _gcry_strerror (rc));
+ return rc;
+ }
+// _gcry_sexp_dump(sexp_data);
+
+ free(tmp_str);
+ free(base64_data);
+ return sexp_data;
+}
+/*
+ * turns out those two functions are no longer required
+ *
+void convert_sexp_data_to_ntru (const gcry_sexp_t sexp_data, uint8_t* ntru_data, size_t* ntru_data_len)
+{
+ uint8_t *buffer = (uint8_t*) malloc(_MAX_NTRU_BUF_SIZE_);
+ uint8_t *ntru_data_buf = (uint8_t*) malloc(_MAX_NTRU_BUF_SIZE_);
+ uint8_t *buffer_pt = buffer;
+ size_t length;
+ *ntru_data_len = _MAX_NTRU_BUF_SIZE_;
+ _gcry_sexp_sprint (sexp_data, 3, buffer, ntru_data_len);
+ int i=0;
+ printf("buffer: ");
+ while(buffer[i]!='\0'){
+ printf("%c ",buffer[i]);i++;}
+ printf("\n");
+ length = my_strlen(buffer) - 7 ; // one for '(', four for "NTRU", one for ')', one for '\0'
+ buffer_pt = buffer+5; // removing the first five chars '(NTRU'
+ buffer_pt [length] = '\0'; // removing the last char ')'
+
+ base64_decode( (uint8_t*)ntru_data_buf, ntru_data_len, buffer_pt, length);
+
+ free (buffer);
+ free (ntru_data_buf);
+}
+
+size_t my_strlen(const uint8_t *str)
+{
+ size_t i;
+ for (i = 0; str[i]; i++);
+ return i;
+}
+*/
+
+static uint8_t
+get_entropy(
+ ENTROPY_CMD cmd,
+ uint8_t *out)
+{
+
+ int num_bytes = 48;
+ /*
+ * dimension number of bytes
+ * 439 24
+ * 593 36
+ * 743 48
+ */
+ /* use this prg for best security */
+// uint8_t *seed = (uint8_t*)_gcry_random_bytes (num_bytes, GCRY_STRONG_RANDOM);
+ /* use this prg to improve performance */
+ uint8_t *seed = (uint8_t*)_gcry_random_bytes (num_bytes, GCRY_WEAK_RANDOM);
+
+
+
+ static size_t index;
+
+ if (cmd == INIT) {
+ /* Any initialization for a real entropy source goes here. */
+ index = 0;
+ return 1;
+ }
+
+ if (out == NULL)
+ return 0;
+
+ if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) {
+ /* Here we return the number of bytes needed from the entropy
+ * source to obtain 8 bits of entropy. Maximum is 8.
+ */
+ *out = 1; /* this is a perfectly random source */
+ return 1;
+ }
+
+ if (cmd == GET_BYTE_OF_ENTROPY) {
+ if (index == 128)
+ return 0; /* used up all our entropy */
+
+ *out = seed[index++]; /* deliver an entropy byte */
+ return 1;
+ }
+ return 0;
+}
diff --git a/cipher/ntru-gcrypt-wrapper.h b/cipher/ntru-gcrypt-wrapper.h
new file mode 100644
index 0000000..0b5c3ab
--- /dev/null
+++ b/cipher/ntru-gcrypt-wrapper.h
@@ -0,0 +1,81 @@
+/* ntru-grcrypt-wrapper.h
+ * Copyright (C) 2015, Security Innovation.
+ * Author Zhenfei Zhang <zzhang at securityinnovation.com>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code is a wrapper for libgcrypt to be linked with libntruencrypt
+ * NTRUEncrypt is a lattice-based public key encryption algorithm.
+ * For the latest version of the NTRUEncrypt specs, visit
+ * https://github.com/NTRUOpenSourceProject/NTRUEncrypt
+ */
+
+
+#ifndef NTRU_GCRYPT_WRAPPER_H
+#define NTRU_GCRYPT_WRAPPER_H
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "gcrypt.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "gcrypt-int.h"
+#include "base64.h"
+#include <libntruencrypt/ntru_crypto.h>
+
+
+#ifndef _MAX_NTRU_BUF_SIZE_
+#define _MAX_NTRU_BUF_SIZE_ 2000
+#endif
+
+/* NTRUEncrypt keygen function, input genparms, output a keypair in r_skey
+ * sample genparms:
+ * (genkey(ntru(b256))), (genkey(ntru(n743))) = 256 bits security with dimension 743
+ * (genkey(ntru(b192))), (genkey(ntru(n593))) = 192 bits security with dimension 593
+ * (genkey(ntru(b128))), (genkey(ntru(n439))) = 128 bits security with dimension 439
+ */
+gcry_err_code_t gcry_ntru_keygen (gcry_sexp_t genparms, gcry_sexp_t *r_skey);
+
+gcry_err_code_t gcry_ntru_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms);
+gcry_err_code_t gcry_ntru_decrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms);
+
+// data conversion: S expression <---> ntru data
+gcry_sexp_t convert_ntru_data_to_sexp (const uint8_t* ntru_data, const size_t ntru_data_len);
+// void convert_sexp_data_to_ntru (const gcry_sexp_t sexp_data, uint8_t* ntru_data, size_t* ntru_data_len);
+
+/*
+ * dump functions
+ */
+static gpg_err_code_t gcry_ntru_comp_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms);
+static unsigned int gcry_ntru_get_nbits (gcry_sexp_t parms);
+static gcry_err_code_t gcry_ntru_check_secret_key (gcry_sexp_t keyparms);
+//static gcry_err_code_t gcry_ntru_self_tests (int algo, int extended, selftest_report_func_t report);
+//static gcry_err_code_t ntru_self_tests (selftest_report_func_t report);
+
+/*
+ * misc functions
+ */
+static uint8_t get_entropy(ENTROPY_CMD cmd, uint8_t *out);
+//size_t my_strlen(const unsigned char *str);
+
+#endif //NTRU_GCRYPT_WRAPPER_H
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index e3842c0..39c7f14 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -48,6 +48,9 @@ static gcry_pk_spec_t *pubkey_list[] =
#if USE_ELGAMAL
&_gcry_pubkey_spec_elg,
#endif
+#if USE_NTRU
+ &_gcry_pubkey_spec_ntru,
+#endif
NULL
};
@@ -62,6 +65,7 @@ map_algo (int algo)
case GCRY_PK_ELG_E: return GCRY_PK_ELG;
case GCRY_PK_ECDSA: return GCRY_PK_ECC;
case GCRY_PK_ECDH: return GCRY_PK_ECC;
+ case GCRY_PK_NTRU: return GCRY_PK_NTRU;
default: return algo;
}
}
diff --git a/configure.ac b/configure.ac
index 0f16175..c9bdb6d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -329,6 +329,18 @@ case "${host}" in
;;
esac
+# check if configured with libntruencrypt
+AC_ARG_ENABLE(ntru,
+ AS_HELP_STRING(--enable-ntru, Build libgcrypt with support for NTRUEncrypt algorithm), [], [enable_ntru=no])
+
+if test $enable_ntru != no; then
+ AC_CHECK_HEADERS([libntruencrypt/ntru_crypto.h])
+ LIBS="$LIBS -lntruencrypt"
+ NTRUENCRYPT_LIBS=-lntruencrypt
+ available_pubkey_ciphers="$available_pubkey_ciphers ntru"
+
+ AC_SUBST(NTRUENCRYPT_LIBS)
+fi
AC_ARG_ENABLE(endian-check,
AC_HELP_STRING([--disable-endian-check],
@@ -2019,6 +2031,12 @@ if test "$found" = "1" ; then
AC_DEFINE(USE_ECC, 1, [Defined if this module should be included])
fi
+LIST_MEMBER(ntru, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ntru-gcrypt-wrapper.lo"
+ AC_DEFINE(USE_NTRU, 1, [Defined if this module should be included])
+fi
+
LIST_MEMBER(crc, $enabled_digests)
if test "$found" = "1" ; then
GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
diff --git a/sample/test_ntru_gcrypt.cpp b/sample/test_ntru_gcrypt.cpp
new file mode 100644
index 0000000..68eda77
--- /dev/null
+++ b/sample/test_ntru_gcrypt.cpp
@@ -0,0 +1,151 @@
+/* test_ntru_gcrypt.cpp
+ * Copyright (C) 2015, Security Innovation.
+ * Author Zhenfei Zhang <zzhang at securityinnovation.com>
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code is an example of using libgcrypt instantiated with NTRUEncrypt
+ * For the latest version of the NTRUEncrypt specs, visit
+ * https://github.com/NTRUOpenSourceProject/NTRUEncrypt
+ */
+
+#include <iostream>
+#include <gcrypt.h>
+
+using namespace std;
+
+#ifndef _MAX_NTRU_BUF_SIZE_
+#define _MAX_NTRU_BUF_SIZE_ 4000
+#endif
+
+#define DEBUG
+
+/* Dumps a buffer in hex to the screen for debugging */
+
+void gcrypt_init();
+
+int main() {
+
+ gcrypt_init();
+ gcry_error_t err = 0;
+ gcry_sexp_t ntru_parms;
+ gcry_sexp_t ntru_keypair;
+ gcry_sexp_t data;
+ gcry_sexp_t cipher;
+
+ /*
+ * Check if NTRU is avaliable
+ */
+ err = gcry_pk_test_algo (GCRY_PK_NTRU);
+ if (err)
+ cerr<<"NTRUEncrypt is not supported: "<<err<<endl;
+
+ /*
+ * initialization
+ * (genkey(ntru(b256))), (genkey(ntru(n743))) = 256 bits security with dimension 743
+ * (genkey(ntru(b192))), (genkey(ntru(n593))) = 192 bits security with dimension 593
+ * (genkey(ntru(b128))), (genkey(ntru(n439))) = 128 bits security with dimension 439
+ *
+ */
+ err = gcry_sexp_build(&ntru_parms, NULL, "(genkey(ntru(b128)))");
+
+ /*
+ * start key generation
+ */
+ err = gcry_pk_genkey(&ntru_keypair, ntru_parms);
+
+ /*
+ * parse key pair into pubk and privk
+ */
+ gcry_sexp_t pubk = gcry_sexp_find_token(ntru_keypair, "public-key", 0);
+ gcry_sexp_t privk = gcry_sexp_find_token(ntru_keypair, "private-key", 0);
+
+#ifdef DEBUG
+ /*
+ * dump public key and private key
+ */
+ cerr<<"error in key gen ?: "<<err<<endl;
+ gcry_sexp_dump (pubk);
+ gcry_sexp_dump (privk);
+#endif
+
+ const unsigned char* msg = (const unsigned char*) "Hello SI. Let's encrypt";
+ err = gcry_sexp_build(&data, NULL, "(data (flags raw) (value %s))", msg);
+ err += gcry_pk_encrypt(&cipher, data, pubk);
+
+#ifdef DEBUG
+ /*
+ * dump message and cipher
+ */
+ cerr<<"error in encryption? : "<<err<<endl;
+ gcry_sexp_dump (data);
+ gcry_sexp_dump (cipher);
+#endif
+
+ err = gcry_pk_decrypt(&data, cipher, privk);
+
+#ifdef DEBUG
+ /*
+ * dump recovered message
+ */
+ cerr<<"error in decryption? : "<<err<<endl;
+ gcry_sexp_dump (data);
+#endif
+
+ cout << "Hello SI" << endl; // prints Hello SI
+
+ return 0;
+}
+
+void gcrypt_init()
+{
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are intialized. */
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ cout<<GCRYPT_VERSION<<endl;
+ printf("gcrypt: library version mismatch\n");
+ }
+
+ gcry_error_t err = 0;
+
+ /* We don't want to see any warnings, e.g. because we have not yet
+ parsed program options which might be used to suppress such
+ warnings. */
+ err = gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. Note that the
+ process might still be running with increased privileges and that
+ the secure memory has not been intialized. */
+
+ /* Allocate a pool of 16k secure memory. This make the secure memory
+ available and also drops privileges where needed. */
+ err |= gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* It is now okay to let Libgcrypt complain when there was/is
+ a problem with the secure memory. */
+ err |= gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ err |= gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ if (err) {
+ printf("gcrypt: failed initialization");
+ }
+}
diff --git a/src/cipher.h b/src/cipher.h
index ef183fd..d551316 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -286,6 +286,6 @@ extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
extern gcry_pk_spec_t _gcry_pubkey_spec_elg_e;
extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
extern gcry_pk_spec_t _gcry_pubkey_spec_ecc;
-
+extern gcry_pk_spec_t _gcry_pubkey_spec_ntru;
#endif /*G10_CIPHER_H*/
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index 0984d11..a08cbaf 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -1054,7 +1054,8 @@ enum gcry_pk_algos
GCRY_PK_ECC = 18, /* Generic ECC. */
GCRY_PK_ELG = 20, /* Elgamal */
GCRY_PK_ECDSA = 301, /* (deprecated: use 18). */
- GCRY_PK_ECDH = 302 /* (deprecated: use 18). */
+ GCRY_PK_ECDH = 302, /* (deprecated: use 18). */
+ GCRY_PK_NTRU = 303 /* NTRU with dim = 439 */
};
/* Flags describing usage capabilities of a PK algorithm. */
diff --git a/tests/benchmark.c b/tests/benchmark.c
index b6cd7a8..efd7141 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -392,6 +392,143 @@ static const char sample_private_elg_key_3072[] =
" ))";
+
+/* A sample dimension 439 NTRU private key used for the selftests. */
+static const char sample_secret_ntru_key439[] =
+"(private-key"
+"(ntru"
+"(NTRU"
+"AgMAAxD4/bZON4SkzqINu9cm4lgMLflx1zNmoGrkSSBfl4LPpCB2beJ1yyX2U7bEhr7e"
+"qZwBdYYDopvgyWFVr4H60z0XR6lh5Q01yRgs5tIzKQyUpym+Ce3fkZ/3+r2QBlGtAY4+6"
+"2irL7nZ4XYajYf0xE/9SLZfkFPXEzlJaByBgQPp/SdoC4mEDmei368+MeRz5ZfXkWaEQ3"
+"2byk7VuzuuoaVcMp3mpqxwImJmTozbUaPEo90iKZonzT9wt7n01sNUYm4ICzrYKSeLSMK"
+"cgRgOKdvJPEnGL4nRPzrLi9McNB1rITezC+3tg0f6uRvFz7ilLKjGxtI3lp7tQM2jx7wP"
+"Gw5+kaC/adaVTryEZprUZV7bRx1aALN6AS7MJsctFJXcx5ZzXHL9qc/BjBAM5bBCjnYMH"
+"SgK6f5xlS//+1Vi8A6Tzpluc37HGUJb7KEdIsXhnqrSY2ailTwjhIDVRxviAUiLn53oGn"
+"vdy+NU/gxtIxIonJ+GGm0k95/5qxyfSnyRepbU5ZQxDYPHFTiDtxs5nVpM5QoJQc6+ogx"
+"JSp8xEck52EgGSOH+GanJybIV6dWo0ykW1v8GQux2Bh3lePkI9csC7tHSZviGt+ILZdxA"
+"k/1lGofOhD7RhqFoYi8jYgdH/jPlAWIig4TilEfnEt4ynzPkcCRzk31DZYaXB1Qr86l1N"
+"wfOQWnSZjQsfVbMXVHbV5qP/f16o6SOTSy7JuzQ27giTGrdGGysRJoiRM0p2WQ5lnXPFz"
+"EU8KIFC3/ZUhUz/NPFZJL2RCdcKs0YNc44UHWJ3WRZlyGFH4n6cHlIF7mUptrykxejbhF"
+"PGimbCzGoFz5rFmagBvT7kIAZWYXqseQjextG91s8Wv0knasDCMA=)))";
+/* A sample dimension 439 NTRU public key used for the selftests. */
+static const char sample_public_ntru_key439[] =
+"(public-key"
+"(ntru"
+"(NTRU"
+"AQMAAxD4/bZON4SkzqINu9cm4lgMLflx1zNmoGrkSSBfl4LPpCB2beJ1yyX2U7bEhr7e"
+"qZwBdYYDopvgyWFVr4H60z0XR6lh5Q01yRgs5tIzKQyUpym+Ce3fkZ/3+r2QBlGtAY4+6"
+"2irL7nZ4XYajYf0xE/9SLZfkFPXEzlJaByBgQPp/SdoC4mEDmei368+MeRz5ZfXkWaEQ3"
+"2byk7VuzuuoaVcMp3mpqxwImJmTozbUaPEo90iKZonzT9wt7n01sNUYm4ICzrYKSeLSMK"
+"cgRgOKdvJPEnGL4nRPzrLi9McNB1rITezC+3tg0f6uRvFz7ilLKjGxtI3lp7tQM2jx7wP"
+"Gw5+kaC/adaVTryEZprUZV7bRx1aALN6AS7MJsctFJXcx5ZzXHL9qc/BjBAM5bBCjnYMH"
+"SgK6f5xlS//+1Vi8A6Tzpluc37HGUJb7KEdIsXhnqrSY2ailTwjhIDVRxviAUiLn53oGn"
+"vdy+NU/gxtIxIonJ+GGm0k95/5qxyfSnyRepbU5ZQxDYPHFTiDtxs5nVpM5QoJQc6+ogx"
+"JSp8xEck52EgGSOH+GanJybIV6dWo0ykW1v8GQux2Bh3lePkI9csC7tHSZviGt+ILZdxA"
+"k/1lGofOhD7RhqFoYi8jYgdH/jPlAWIig4TilEfnEt4ynzPkcCRzk31DZYaXB1Qr86l1N"
+"wfOQWnSZjQsfVbMXVHbV5qP/f16o6SOTSy7JuzQ27giTGrdGGysRJoiRM0p2WQ5lnXPFz"
+"EU8KIFC3/ZUhUz/NPFZJL2RCdcKs0YNc44UHWJ3WRZlyGFH4n6cHlI)))";
+
+/* A sample dimension 493 NTRU private key used for the selftests. */
+static const char sample_secret_ntru_key593[] =
+"(private-key"
+"(ntru"
+"(NTRU"
+"AgMABRDX622c5T6rDgfmUQVI2h1dgEZP/qC+8sx3CFo5Rj0+YQ5Tq/4xb95dmG5NuAEG"
+"DWb7sdiHbJgw6I/JxZmrjsu5cde8WxvVFTWT4O6jmxsuzJZhzq6iF7/99ne6DFy0sBCvk"
+"vEAEMFUgqyDCqFtc30EJpuTYZYOU7kIIKlhwnjqADeoK2hNKLgATGNSaWig3KztfO0o9x"
+"lThcVKLoeO0YNSNsL8IGsrbn7logFaSfglxGpxlAzrr0NFYrXbJ8+GPVpfLIQmqnIx6tb"
+"k7xOR/jtTLbfwpRsNGVwdtvA4wnigRDwF7QcRbfM60FWAWI3YEzGO2qbWGoaO8JZxcQBK"
+"kGbFWR5eNnK1RZfYPV3WPNg6LfTB4McgLHJH1X6qBzH5CQ0ehYL+ozKP0kurd7CkoI06D"
+"vae7oQOOMvxh1DtOq3dHMfG+r1a2dp9t8LGtRFp3fPgezfaCFOE8aa+MC6dnBvK+tZmLA"
+"0kKws0Nc8ZMfgyfL2pCicDBN2djVwmsYfdERRHGA11a16dkbajcHdF04dzK/9uioqF57E"
+"dkh2a7qnNw2fcSuLFXBTs31bDjh4vAE571JLWXKZkd0T2degI9apii3LIz/MESK1WBjkZ"
+"0zt5uG037RrKtSbFrDaTkkqsVYIow2zB/AiiU6RRkXe819fKEQRFXG7bqJz3RIjQ1QkS9"
+"2Sdc8DIiTeo/cVP8l38+Oi1hlacgw2F3A9TRN+YLfsJLRX0gcWciwz7pvrpyFUOgTIhxt"
+"FzkVgjwljffPdpcxkO8WSrwqqpZlxXuj08BuG9xpyN2IJ+Vw9SvLow5fVtGNi1nU4zx6l"
+"GTFOBP7rzLjHdPC+umCarBrCd9tmHN1heiiYDd7g8IfJfjbeKJ6p4Grq6WfU1f0TTzGkB"
+"a2rbJBIFjoI/tffbA6xm+P70kRkHq/ayWmk0qnQDTJQ51PJ+GvYl/VSVEGoIhS2V4YK26"
+"pJ2ieb98jelqLSozzgo/PczTd/KHO1srno5Id+YIeetf0bZ6J6gZja6WxfLvdmhMJNpXe"
+"ghdY6MsoT1kf4TQKOArchYFE7/wCl9rcg43Aj0JGdpLjVTDHnxvKXdiKjeOWAmDaDgny2"
+"KtSxqjIuiliQvAsc0ejVTkISjVJjXMeBxRXHUNlzi+GEvPFjmBBM3gnCuDCMPN8CoSNay"
+"xV8v4JARWynVwrzR)))";
+/* A sample dimension 439 NTRU public key used for the selftests. */
+static const char sample_public_ntru_key593[] =
+"(public-key"
+"(ntru"
+"(NTRU"
+"AQMABRDX622c5T6rDgfmUQVI2h1dgEZP/qC+8sx3CFo5Rj0+YQ5Tq/4xb95dmG5NuAEG"
+"DWb7sdiHbJgw6I/JxZmrjsu5cde8WxvVFTWT4O6jmxsuzJZhzq6iF7/99ne6DFy0sBCvk"
+"vEAEMFUgqyDCqFtc30EJpuTYZYOU7kIIKlhwnjqADeoK2hNKLgATGNSaWig3KztfO0o9x"
+"lThcVKLoeO0YNSNsL8IGsrbn7logFaSfglxGpxlAzrr0NFYrXbJ8+GPVpfLIQmqnIx6tb"
+"k7xOR/jtTLbfwpRsNGVwdtvA4wnigRDwF7QcRbfM60FWAWI3YEzGO2qbWGoaO8JZxcQBK"
+"kGbFWR5eNnK1RZfYPV3WPNg6LfTB4McgLHJH1X6qBzH5CQ0ehYL+ozKP0kurd7CkoI06D"
+"vae7oQOOMvxh1DtOq3dHMfG+r1a2dp9t8LGtRFp3fPgezfaCFOE8aa+MC6dnBvK+tZmLA"
+"0kKws0Nc8ZMfgyfL2pCicDBN2djVwmsYfdERRHGA11a16dkbajcHdF04dzK/9uioqF57E"
+"dkh2a7qnNw2fcSuLFXBTs31bDjh4vAE571JLWXKZkd0T2degI9apii3LIz/MESK1WBjkZ"
+"0zt5uG037RrKtSbFrDaTkkqsVYIow2zB/AiiU6RRkXe819fKEQRFXG7bqJz3RIjQ1QkS9"
+"2Sdc8DIiTeo/cVP8l38+Oi1hlacgw2F3A9TRN+YLfsJLRX0gcWciwz7pvrpyFUOgTIhxt"
+"FzkVgjwljffPdpcxkO8WSrwqqpZlxXuj08BuG9xpyN2IJ+Vw9SvLow5fVtGNi1nU4zx6l"
+"GTFOBP7rzLjHdPC+umCarBrCd9tmHN1heiiYDd7g8IfJfjbeKJ6p4Grq6WfU1f0TTzGkB"
+"a2rbJBIFjoI/tffbA6xm+P70kRkHq/ayWmk0qnQDTJQ51PJ+GvYl/VSVEGoIhS2V4YK26"
+"pJ2ieb98jelqLSozzgo/PczTd/KHO1srno5Id+YIeetf0bZ6J6gZja6WxfLvdmhMJNpXe"
+"ghdY6MsoT1kf4TQKOArchYFE7/wCl9rcg43Aj0JGdpLjVTDHnxvKXdiKjeOWA=)))";
+
+
+/* A sample dimension 493 NTRU private key used for the selftests. */
+static const char sample_secret_ntru_key743[] =
+"(private-key"
+"(ntru"
+"(NTRU"
+"AgMABhAKHhcsXOolid9nt56VJoRJiSfPdJzbH2BrvpbAj/05uFFDZcU6On43z7/cPuTv"
+"X/Ql3p/W10CZ7ymVAneaL1EqBAspeO+gkndJgBiEyo5W5DOgyB4pWpBupfLFXw5QXzpHb"
+"1m2GLQPtFFzadflevoAaf4XjlRcYB+/cQT+Z0Lrbrixd9BHdGQyw/esMZ8/FjnY8ikzx0"
+"iNCchFYNB6gPspEfrI28BQQxWRo0+lO1BaWqC9dxPHE7/WBxWErJP5YgrB/fR3UjrTJk5"
+"jSlvlRbQNPKqgWa8osjwbeJBFdvsWflA/uJPVZvrElAZ59o133CmjWnMoDpWfS8AiXDZU"
+"PP/UvSTFH78h4d71xTzxt+xZvrOnSIjDibJQyOnQ0owxSE2oBXEsjcI8zPrFtQjE0jeww"
+"MFhJagOHWHkV3S9NFrqUrFyRbLHO2ojGrUUzGwTxGyjQ8V0Mp2kkLks+wdx42BFsRnpsq"
+"3+C9mxEggLc1nIXb59c1hLBPZYAl13dE1K8wuY8J5dVWtmcZOv0Qll3qc861fGPlNwvn2"
+"Cgw81Y4HrNp4KRZNrgqnO8RV/ZVVMfY+lyXloKCPB7y+15SrXjAipFAPnXaIhwH2HAlSG"
+"onxfcsPRSXvEDNCAvjc9od0+ABW5bKLpCgiYR1o3p1iagTk6uHim47wJeogdpobrFkm40"
+"Oddub5ywml7x6Ovu9xz4nFXPMY+ptvMDRC24YsvXsWRfKCeZrWsrlA+kSNU9x3EBTD+sp"
+"hkkiXXXGh3mjYKG1jh6rxXVAV7nmclhiI1iouoo5lTpn7sPPlgQzSF+N2Kf5YywFFYgAD"
+"VQZqQHQYkbbiTUrmNqDYwx82LCPGuR2hH4SCbN5QEkI81gSiAQrGYgmk2LeOnmb5EpG9t"
+"xzYcuQ6nGlFX6LsB6Hhzf9AfPTDFAHRk7ACqw8cV8aGFb4qesfO+kEPqnzAoYqKg6hmTq"
+"R5RnKpqasgE3oiRKEM3z2vAV8SmA1FUotu1BW07n9QCnmq9VA6y9wR8jv5315XXQ6SHnw"
+"G2FBOQSTO3/XxW2/cBZIU8e+KSUE3QwY0Zj0dAM+alRJGfogpR6BDvonr34yu3jdzuCWT"
+"A9LBiLj5JRdeaIIRFHYCQYEnwl84rkPJFR7vDcv2zvNjokCU9KAd7LW3VN3EBIhDzwD7E"
+"ZWJWYzntkiWF8qgsZMqIlK/Yso7olwSUx7KFeNls00SvSpw2rM+muEfOmTq3VO7ZSYPeP"
+"QilbJoCzr0Ab5f0i0C6D/dxmM+gAaqTfr9hg/m+xBGXe0G4oDSqRaG2tl67daxwpapxqB"
+"vXUCVDj+E2WeiGKe+7CN5poVteiTvyymiwbySI8wOlaaXdBrhzNA/NnUVXIDNDSaC7fep"
+"pXOxRnfuAsSRuKRWRdJZgze+PJCTYppesCqacRpAp3Tdn6PkSP2EeAgazB6Dqjleex1sU"
+"twJqyJwNeyk37LQGEofADCzGJvR9RBQnrnchW/Kav7WtMA==)))";
+/* A sample dimension 439 NTRU public key used for the selftests. */
+static const char sample_public_ntru_key743[] =
+"(public-key"
+"(ntru"
+"(NTRU"
+"AQMABhAKHhcsXOolid9nt56VJoRJiSfPdJzbH2BrvpbAj/05uFFDZcU6On43z7/cPuTv"
+"X/Ql3p/W10CZ7ymVAneaL1EqBAspeO+gkndJgBiEyo5W5DOgyB4pWpBupfLFXw5QXzpHb"
+"1m2GLQPtFFzadflevoAaf4XjlRcYB+/cQT+Z0Lrbrixd9BHdGQyw/esMZ8/FjnY8ikzx0"
+"iNCchFYNB6gPspEfrI28BQQxWRo0+lO1BaWqC9dxPHE7/WBxWErJP5YgrB/fR3UjrTJk5"
+"jSlvlRbQNPKqgWa8osjwbeJBFdvsWflA/uJPVZvrElAZ59o133CmjWnMoDpWfS8AiXDZU"
+"PP/UvSTFH78h4d71xTzxt+xZvrOnSIjDibJQyOnQ0owxSE2oBXEsjcI8zPrFtQjE0jeww"
+"MFhJagOHWHkV3S9NFrqUrFyRbLHO2ojGrUUzGwTxGyjQ8V0Mp2kkLks+wdx42BFsRnpsq"
+"3+C9mxEggLc1nIXb59c1hLBPZYAl13dE1K8wuY8J5dVWtmcZOv0Qll3qc861fGPlNwvn2"
+"Cgw81Y4HrNp4KRZNrgqnO8RV/ZVVMfY+lyXloKCPB7y+15SrXjAipFAPnXaIhwH2HAlSG"
+"onxfcsPRSXvEDNCAvjc9od0+ABW5bKLpCgiYR1o3p1iagTk6uHim47wJeogdpobrFkm40"
+"Oddub5ywml7x6Ovu9xz4nFXPMY+ptvMDRC24YsvXsWRfKCeZrWsrlA+kSNU9x3EBTD+sp"
+"hkkiXXXGh3mjYKG1jh6rxXVAV7nmclhiI1iouoo5lTpn7sPPlgQzSF+N2Kf5YywFFYgAD"
+"VQZqQHQYkbbiTUrmNqDYwx82LCPGuR2hH4SCbN5QEkI81gSiAQrGYgmk2LeOnmb5EpG9t"
+"xzYcuQ6nGlFX6LsB6Hhzf9AfPTDFAHRk7ACqw8cV8aGFb4qesfO+kEPqnzAoYqKg6hmTq"
+"R5RnKpqasgE3oiRKEM3z2vAV8SmA1FUotu1BW07n9QCnmq9VA6y9wR8jv5315XXQ6SHnw"
+"G2FBOQSTO3/XxW2/cBZIU8e+KSUE3QwY0Zj0dAM+alRJGfogpR6BDvonr34yu3jdzuCWT"
+"A9LBiLj5JRdeaIIRFHYCQYEnwl84rkPJFR7vDcv2zvNjokCU9KAd7LW3VN3EBIhDzwD7E"
+"ZWJWYzntkiWF8qgsZMqIlK/Yso7olwSUx7KFeNls00SvSpw2rM+muEfOmTq3VO7ZSYPeP"
+"QilbJoCzr0Ab5f0i0C6D/dxmM+gAaqTfr9hg/m+xBGXe0G4oDSqRaG2tl67daxwpapxqB"
+"vXUCVDj+E2WeiGKe+7CN5poVteiTvyymiwbySI8wOlaaXdBrhzNA/NnUVXIA==)))";
+
+
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
@@ -1540,6 +1677,106 @@ ecc_bench (int iterations, int print_header)
}
#endif /*USE_ECC*/
}
+static void
+ntru_bench (int iterations, int print_header)
+{
+#if USE_NTRU
+ gpg_error_t err;
+ gcry_sexp_t pub_key[3], sec_key[3];
+ int i, counter;
+ int dim[3] = { 439, 593,743 };
+ gcry_sexp_t data;
+ gcry_sexp_t enc[iterations];
+ gcry_sexp_t plain[iterations];
+ const unsigned char* msg = (const unsigned char*) "Hello SI. Let's encrypt.";
+ char timerbuf1[100];
+
+ err = gcry_sexp_new(pub_key+0,sample_public_ntru_key439,strlen (sample_public_ntru_key439),1);
+ if (!err)
+ err = gcry_sexp_new(pub_key+1,sample_public_ntru_key593,strlen (sample_public_ntru_key593),1);
+ if (!err)
+ err = gcry_sexp_new(pub_key+2,sample_public_ntru_key743,strlen (sample_public_ntru_key743),1);
+ if (!err)
+ err = gcry_sexp_new(sec_key+0,sample_secret_ntru_key439,strlen (sample_secret_ntru_key439),1);
+ if (!err)
+ err = gcry_sexp_new(sec_key+1,sample_secret_ntru_key593,strlen (sample_secret_ntru_key593),1);
+ if (!err)
+ err = gcry_sexp_new(sec_key+2,sample_secret_ntru_key743,strlen (sample_secret_ntru_key743),1);
+
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting sample keys failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+ err = gcry_sexp_build(&data, NULL, "(data (flags raw) (value %s))", msg);
+
+ if (print_header)
+ printf ("Algorithm generate %4d*priv %4d*public\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+
+
+ for(i=0;i<3;i++)
+ {
+ for (counter=0;counter<iterations;counter++)
+ {
+ enc[counter] = NULL;
+ plain[counter] = NULL;
+ }
+
+ printf ("ntru %d dim -", dim[i]);
+ fflush (stdout);
+
+ start_timer ();
+ for (counter=0; counter< iterations; counter++)
+ {
+ err = gcry_pk_encrypt (enc+counter, data, pub_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": encrypt failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+
+ snprintf (timerbuf1, sizeof timerbuf1, " %s", elapsed_time (1));
+ fflush (stdout);
+
+ start_timer ();
+ for (counter=0; counter < iterations; counter++)
+ {
+ err = gcry_pk_decrypt (plain+counter, enc[counter], sec_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": decrypt failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ printf (" %s %s\n", elapsed_time (1), timerbuf1);
+ fflush (stdout);
+ }
+
+
+ for (counter=0; counter < iterations; counter++)
+ {
+ gcry_sexp_release (plain[counter]);
+ gcry_sexp_release (enc[counter]);
+ }
+ gcry_sexp_release (data);
+ for (i=0; i < 3; i++)
+ {
+ gcry_sexp_release (sec_key[i]);
+ gcry_sexp_release (pub_key[i]);
+ }
+
+#endif /*USE_NTRU*/
+}
@@ -1864,6 +2101,7 @@ main( int argc, char **argv )
rsa_bench (pk_count, 1, no_blinding);
elg_bench (pk_count, 0);
dsa_bench (pk_count, 0);
+ ntru_bench(pk_count, 0);
ecc_bench (pk_count, 0);
putchar ('\n');
mpi_bench ();
@@ -1917,6 +2155,7 @@ main( int argc, char **argv )
rsa_bench (pk_count, 1, no_blinding);
elg_bench (pk_count, 0);
dsa_bench (pk_count, 0);
+ ntru_bench(pk_count, 0);
ecc_bench (pk_count, 0);
}
else if ( !strcmp (*argv, "rsa"))
@@ -1939,6 +2178,11 @@ main( int argc, char **argv )
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
ecc_bench (pk_count, 1);
}
+ else if ( !strcmp (*argv, "ntru"))
+ {
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ ntru_bench (pk_count, 1);
+ }
else if ( !strcmp (*argv, "prime"))
{
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
More information about the Gcrypt-devel
mailing list