Make the NTRU parameter set configurable
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 20 Nov 2013 23:15:59 +0000 (00:15 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 27 Nov 2013 19:21:41 +0000 (20:21 +0100)
man/strongswan.conf.5.in
src/libstrongswan/plugins/ntru/ntru_ke.c
src/libstrongswan/tests/suites/test_ntru.c

index 1ded524..93d2d2e 100644 (file)
@@ -867,6 +867,11 @@ Enable logging of SQL IP pool leases
 .BR libstrongswan.plugins.gcrypt.quick_random " [no]"
 Use faster random numbers in gcrypt; for testing only, produces weak keys!
 .TP
+.BR libstrongswan.plugins.ntru.param_set_selection " [optimum]"
+The following parameter sets are available: 'x9_98_speed', 'x9_98_bandwidth',
+'x9_98_balance' and 'optimum', the last set not being part of the X9.98
+standard but exhibiting the best performance.
+.TP
 .BR libstrongswan.plugins.openssl.engine_id " [pkcs11]"
 ENGINE ID to use in the OpenSSL plugin
 .TP
index 18f3b4c..8c2f614 100644 (file)
@@ -193,6 +193,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
                        chunk_free(&this->shared_secret);
                        return;
                }
+               this->computed = TRUE;
 
                /* determine the size of the ciphertext */
                if (ntru_crypto_ntru_encrypt(this->drbg,
@@ -204,7 +205,6 @@ METHOD(diffie_hellman_t, set_other_public_value, void,
                        return;
                }
                this->ciphertext = chunk_alloc(ciphertext_len);
-               this->computed = TRUE;
 
                /* encrypt the shared secret */
                if (ntru_crypto_ntru_encrypt(this->drbg,
@@ -247,35 +247,68 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p)
 {
        private_ntru_ke_t *this;
        char personalization_str[] = "strongSwan NTRU-KE";
-       NTRU_ENCRYPT_PARAM_SET_ID param_set_id;
+       NTRU_ENCRYPT_PARAM_SET_ID *param_set, param_set_id;
        DRBG_HANDLE drbg;
+       char *param_set_selection;
        u_int32_t strength;
 
-       /**
-        * We are selecting the X9.98 / IEEE 1363.1 parameter sets
-        * which balance speed and bandwidth
-        */
+       /* Best bandwidth and speed, no X9.98 compatibility */
+       NTRU_ENCRYPT_PARAM_SET_ID param_set_optimum[] = {
+               NTRU_EES401EP2, NTRU_EES439EP1, NTRU_EES593EP1, NTRU_EES743EP1
+       };
+
+       /* X9.98/IEEE 1363.1 parameter set for best speed */
+       NTRU_ENCRYPT_PARAM_SET_ID param_set_x9_98_speed[] = {
+               NTRU_EES659EP1, NTRU_EES761EP1, NTRU_EES1087EP1, NTRU_EES1499EP1
+       };
+
+       /* X9.98/IEEE 1363.1 parameter set for best bandwidth (smallest size) */
+       NTRU_ENCRYPT_PARAM_SET_ID param_set_x9_98_bandwidth[] = {
+               NTRU_EES401EP1, NTRU_EES449EP1, NTRU_EES677EP1, NTRU_EES1087EP1
+       };
+
+       /* X9.98/IEEE 1363.1 parameter set balancing speed and bandwidth */
+       NTRU_ENCRYPT_PARAM_SET_ID param_set_x9_98_balance[] = {
+               NTRU_EES541EP1, NTRU_EES613EP1, NTRU_EES887EP1, NTRU_EES1171EP1
+       };
+
+       param_set_selection = lib->settings->get_str(lib->settings,
+                               "libstrongswan.plugins.ntru.param__set_selection", "optimum");
+
+       if (streq(param_set_selection, "x9_98_speed"))
+       {
+               param_set = param_set_x9_98_speed;
+       }
+       else if (streq(param_set_selection, "x9_98_bandwidth"))
+       {
+               param_set = param_set_x9_98_bandwidth;
+       }
+       else if (streq(param_set_selection, "x9_98_balance"))
+       {
+               param_set = param_set_x9_98_balance;
+       }
+       else
+       {
+               param_set = param_set_optimum;
+       }
+
        switch (group)
        {
                case NTRU_112_BIT:
                        strength = 112;
-                       /* param_set_id = NTRU_EES541EP1; */
-                       param_set_id = NTRU_EES401EP2;
+                       param_set_id = param_set[0];
                        break;
                case NTRU_128_BIT:
                        strength = 128;
-                       /* param_set_id = NTRU_EES613EP1; */
-                       param_set_id = NTRU_EES439EP1;
+                       param_set_id = param_set[1];
                        break;
                case NTRU_192_BIT:
                        strength = 192;
-                       /* param_set_id = NTRU_EES887EP1; */
-                       param_set_id = NTRU_EES593EP1;
+                       param_set_id = param_set[2];
                        break;
                case NTRU_256_BIT:
                        strength = 256;
-                       /* param_set_id = NTRU_EES1171EP1; */
-                       param_set_id = NTRU_EES743EP1;
+                       param_set_id = param_set[3];
                        break;
                default:
                        return NULL;
index fb735e6..8687598 100644 (file)
@@ -28,12 +28,19 @@ static struct {
        { NTRU_256_BIT, "NTRU_256" }
 };
 
-START_TEST(test_ke)
+/**
+ * NTRU parameter set selection
+ */
+char *param_set_selection[] = {
+               "x9_98_speed", "x9_98_bandwidth", "x9_98_balance", "optimum"
+};
+
+START_TEST(test_ntru_ke)
 {
        chunk_t pub_key, cipher_text, i_shared_secret, r_shared_secret;
        diffie_hellman_t *i_ntru, *r_ntru;
        char buf[10];
-       int len;
+       int n, len;
        status_t status;
        
        len = snprintf(buf, sizeof(buf), "%N", diffie_hellman_group_names,
@@ -41,37 +48,63 @@ START_TEST(test_ke)
        ck_assert(len == 8);
        ck_assert(streq(buf, params[_i].group_name));
 
-       i_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
-       ck_assert(i_ntru != NULL);
-       ck_assert(i_ntru->get_dh_group(i_ntru) == params[_i].group);
+       for (n = 0; n < countof(param_set_selection); n++)
+       {
+               lib->settings->set_str(lib->settings,
+                                                         "libcharon.plugins.ntru.param_set_selection",
+                                                          param_set_selection[n]);
 
-       i_ntru->get_my_public_value(i_ntru, &pub_key);
-       ck_assert(pub_key.len > 0);
+               i_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
+               ck_assert(i_ntru != NULL);
+               ck_assert(i_ntru->get_dh_group(i_ntru) == params[_i].group);
 
-       r_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
-       ck_assert(r_ntru != NULL);
+               i_ntru->get_my_public_value(i_ntru, &pub_key);
+               ck_assert(pub_key.len > 0);
 
-       r_ntru->set_other_public_value(r_ntru, pub_key);
-       r_ntru->get_my_public_value(r_ntru, &cipher_text);
-       ck_assert(cipher_text.len > 0);
+               r_ntru = lib->crypto->create_dh(lib->crypto, params[_i].group);
+               ck_assert(r_ntru != NULL);
+
+               r_ntru->set_other_public_value(r_ntru, pub_key);
+               r_ntru->get_my_public_value(r_ntru, &cipher_text);
+               ck_assert(cipher_text.len > 0);
 
-       i_ntru->set_other_public_value(i_ntru, cipher_text);
-       status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
-       ck_assert(status == SUCCESS);
-       ck_assert(i_shared_secret.len > 0);
+               status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
+               ck_assert(status == SUCCESS);
+               ck_assert(r_shared_secret.len > 0);
 
-       status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret);
-       ck_assert(status == SUCCESS);
-       ck_assert(r_shared_secret.len > 0);
+               i_ntru->set_other_public_value(i_ntru, cipher_text);
+               status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret);
 
-       ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
+               if (status == SUCCESS)
+               {
+                       ck_assert(chunk_equals(i_shared_secret, r_shared_secret));
+               }
+               else
+               {
+                       ck_assert(i_shared_secret.len == 0);
+               }
 
-       chunk_clear(&i_shared_secret);
-       chunk_clear(&r_shared_secret);
-       chunk_free(&pub_key);
-       chunk_free(&cipher_text);
-       i_ntru->destroy(i_ntru);
+               chunk_clear(&i_shared_secret);
+               chunk_clear(&r_shared_secret);
+               chunk_free(&pub_key);
+               chunk_free(&cipher_text);
+               i_ntru->destroy(i_ntru);
+               r_ntru->destroy(r_ntru);
+       }
+}
+END_TEST
+
+START_TEST(test_ntru_pubkey)
+{
+       diffie_hellman_t *r_ntru;
+       chunk_t cipher_text;
+
+       r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT);
+       r_ntru->set_other_public_value(r_ntru, chunk_empty);
+       r_ntru->get_my_public_value(r_ntru, &cipher_text);
+       ck_assert(cipher_text.len == 0);
        r_ntru->destroy(r_ntru);
+
 }
 END_TEST
 
@@ -83,7 +116,11 @@ Suite *ntru_suite_create()
        s = suite_create("ntru");
 
        tc = tcase_create("ke");
-       tcase_add_loop_test(tc, test_ke, 0, countof(params));
+       tcase_add_loop_test(tc, test_ntru_ke, 0, countof(params));
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("pubkey");
+       tcase_add_test(tc, test_ntru_pubkey);
        suite_add_tcase(s, tc);
 
        return s;