Home

Awesome

C implementation of NTRUEncrypt

An implementation of the public-key encryption scheme NTRUEncrypt in C, following the IEEE P1363.1 standard.

NTRU's main strengths are high performance and resistance to quantum computer attacks. Its main drawback is that it is patent encumbered. The patents expire in 2021; when built with the NTRU_AVOID_HAMMING_WT_PATENT flag (see below), libntru becomes patent-free in 2017.

Benchmark results:

Benchmark results

For more information on the NTRUEncrypt algorithm, see the NTRU introduction page at https://tbuktu.github.com/ntru/.

Compiling

Run make to build the library, or make test to run unit tests. make bench builds a benchmark program. On *BSD, use gmake instead of make.

The SIMD environment variable controls SSSE3 and AVX2 support. The default is auto which means SSSE3 and AVX2 are detected at runtime. Other values are none, ssse3, and avx2.

If the NTRU_AVOID_HAMMING_WT_PATENT preprocessor flag is supplied, the library won't support parameter sets that will be patent encumbered after Aug 19, 2017. See the Parameter Sets section for information on patent expiration dates.

Usage

#include "ntru.h"

/* key generation */
struct NtruEncParams params = NTRU_DEFAULT_PARAMS_128_BITS; /*see section "Parameter Sets" below*/
NtruRandGen rng_def = NTRU_RNG_DEFAULT;
NtruRandContext rand_ctx_def;
if (ntru_rand_init(&rand_ctx_def, &rng_def) != NTRU_SUCCESS)
    printf("rng fail\n");
NtruEncKeyPair kp;
if (ntru_gen_key_pair(&params, &kp, &rand_ctx_def) != NTRU_SUCCESS)
    printf("keygen fail\n");

/* deterministic key generation from password */
uint8_t seed[17];
strcpy(seed, "my test password");
NtruRandGen rng_ctr_drbg = NTRU_RNG_CTR_DRBG;
NtruRandContext rand_ctx_ctr_drbg;
if (ntru_rand_init_det(&rand_ctx_ctr_drbg, &rng_ctr_drbg, seed, strlen(seed)) != NTRU_SUCCESS)
    printf("rng fail\n");
if (ntru_gen_key_pair(&params, &kp, &rand_ctx_ctr_drbg) != NTRU_SUCCESS)
    printf("keygen fail\n");

/* encryption */
uint8_t msg[9];
strcpy(msg, "whatever");
uint8_t enc[ntru_enc_len(&params)];
if (ntru_encrypt(msg, strlen(msg), &kp.pub, &params, &rand_ctx_def, enc) != NTRU_SUCCESS)
    printf("encrypt fail\n");

/* decryption */
uint8_t dec[ntru_max_msg_len(&params)];
uint16_t dec_len;
if (ntru_decrypt((uint8_t*)&enc, &kp, &params, (uint8_t*)&dec, &dec_len) != NTRU_SUCCESS)
    printf("decrypt fail\n");

/* generate another public key for the existing private key */
NtruEncPubKey pub2;
if (ntru_gen_pub(&params, &kp.priv, &pub2, &rand_ctx_def) != NTRU_SUCCESS)
    printf("pub key generation fail\n");

/* release RNG resources */
if (ntru_rand_release(&rand_ctx_def) != NTRU_SUCCESS)
    printf("rng fail\n");
if (ntru_rand_release(&rand_ctx_ctr_drbg) != NTRU_SUCCESS)
    printf("rng fail\n");

/* export key to uint8_t array */
uint8_t pub_arr[ntru_pub_len(&params)];
ntru_export_pub(&kp.pub, pub_arr);

/* import key from uint8_t array */
NtruEncPubKey pub;
ntru_import_pub(pub_arr, &pub);

For encryption of messages longer than ntru_max_msg_len(...), see src/hybrid.c (requires libsodium+headers, use make hybrid to build).

Parameter Sets

NameStrengthSizes (CText/Pub/Priv)<sup>1</sup>Enc / Dec Time<sup>2</sup>Pat. Until
EES401EP1112 bits552 / 556 / 2642.5 / 2.78/19/2017
EES541EP1112 bits744 / 748 / 1321.5 / 1.98/19/2017
EES659EP1112 bits907 / 911 / 1041.5 / 2.08/19/2017
EES401EP2112 bits552 / 556 / 671.0 / 1.28/24/2021
NTRU_DEFAULT_PARAMS_112_BITS112 bitsSynonym for EES401EP2 or EES401EP1<sup>3</sup>
EES449EP1128 bits618 / 622 / 3112.7 / 3.48/19/2017
EES613EP1128 bits843 / 847 / 1471.6 / 2.28/19/2017
EES761EP1128 bits1047 / 1051 / 1141.6 / 2.28/19/2017
EES439EP1128 bits604 / 608 / 681.1 / 1.48/24/2021
EES443EP1128 bits610 / 614 / 681.1 / 1.38/24/2021
NTRU_DEFAULT_PARAMS_128_BITS128 bitsSynonym for EES443EP1 or EES449EP1<sup>3</sup>
EES677EP1192 bits931 / 935 / 4024.4 / 5.58/19/2017
EES887EP1192 bits1220 / 1224 / 2122.8 / 3.98/19/2017
EES1087EP1192 bits1495 / 1499 / 1833.0 / 4.08/19/2017
EES593EP1192 bits816 / 820 / 871.7 / 2.18/24/2021
EES587EP1192 bits808 / 812 / 871.9 / 2.38/24/2021
NTRU_DEFAULT_PARAMS_192_BITS192 bitsSynonym for EES587EP1 or EES677EP1<sup>3</sup>
EES1087EP2256 bits1495 / 1499 / 3394.5 / 6.18/19/2017
EES1171EP1256 bits1611 / 1615 / 3014.3 / 6.08/19/2017
EES1499EP1256 bits2062 / 2066 / 2274.3 / 6.08/19/2017
EES743EP1256 bits1022 / 1026 / 1112.2 / 2.98/24/2021
NTRU_DEFAULT_PARAMS_256_BITS256 bitsSynonym for EES743EP1 or EES1087EP2<sup>3</sup>

<a name="footnote1"><sup>1</sup></a> in bytes <br> <a name="footnote2"><sup>2</sup></a> relative to EES401EP2 encryption on a 1.6 GHz Intel Xeon <br> <a name="footnote3"><sup>3</sup></a> depending on the NTRU_AVOID_HAMMING_WT_PATENT flag

Random Number Generators

Other RNGs are NTRU_RNG_WINCRYPT, NTRU_RNG_DEVURANDOM, and NTRU_RNG_DEVRANDOM but these may be removed in a future release.

To use your own RNG, make an array of 3 function pointers: {init, generate, release} with the following signatures:

Ignore rand_ctx->seed in init() if your RNG is non-deterministic.

Supported Platforms

libntru has been tested on Linux, FreeBSD, OpenBSD, Mac OS X, and Windows (MingW).

Further reading