bliss: Implemented FFT with fast Montgomery arithmetic
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 22 Jul 2016 09:36:59 +0000 (11:36 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 29 Jul 2016 10:36:14 +0000 (12:36 +0200)
src/libstrongswan/plugins/bliss/Makefile.am
src/libstrongswan/plugins/bliss/bliss_fft.c
src/libstrongswan/plugins/bliss/bliss_fft_params.c
src/libstrongswan/plugins/bliss/bliss_fft_params.h
src/libstrongswan/plugins/bliss/bliss_private_key.c
src/libstrongswan/plugins/bliss/bliss_public_key.c
src/libstrongswan/plugins/bliss/bliss_reduce.h [new file with mode: 0644]
src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c

index e2aaaf5..7ce6f32 100644 (file)
@@ -20,7 +20,7 @@ libbliss_la_SOURCES = \
        bliss_signature.h bliss_signature.c \
        bliss_utils.h bliss_utils.c \
        bliss_bitpacker.h bliss_bitpacker.c \
-       bliss_fft.h bliss_fft.c \
+       bliss_reduce.h bliss_fft.h bliss_fft.c \
        bliss_huffman_code.h bliss_huffman_code.c \
        bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \
        bliss_huffman_coder.h bliss_huffman_coder.c \
index 033c214..00005cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -14,6 +14,7 @@
  */
 
 #include "bliss_fft.h"
+#include "bliss_reduce.h"
 
 typedef struct private_bliss_fft_t private_bliss_fft_t;
 
@@ -21,6 +22,7 @@ typedef struct private_bliss_fft_t private_bliss_fft_t;
  * Private data structure for bliss_fft_t object
  */
 struct private_bliss_fft_t {
+
        /**
         * Public interface.
         */
@@ -65,8 +67,8 @@ static void butterfly(private_bliss_fft_t *this, uint32_t *x, int i1,int i2,
        {
                xp -= this->p->q;
        }
-       x[i1] =  xp;
-       x[i2] = (xm * this->p->w[iw]) % this->p->q;
+       x[i1] = xp;
+       x[i2] = bliss_mreduce(xm * this->p->wr[iw], this->p);
 }
 
 /**
@@ -95,19 +97,17 @@ METHOD(bliss_fft_t, transform, void,
        private_bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse)
 {
        int stage, i, j, k, m, n, t, iw, i_rev;
-       uint16_t q;
        uint32_t tmp;
 
-       /* we are going to use the transform size n and the modulus q a lot */
+       /* we are going to use the transform size n a lot */
        n = this->p->n;
-       q = this->p->q;
 
        if (!inverse)
        {
                /* apply linear phase needed for negative wrapped convolution */
                for (i = 0; i < n; i++)
                {
-                       b[i] = (a[i] * this->p->w[i]) % q;
+                       b[i] = bliss_mreduce(a[i] * this->p->wf[i], this->p);
                }
        }
        else if (a != b)
@@ -137,7 +137,7 @@ METHOD(bliss_fft_t, transform, void,
                        {
                                for (i = 0; i < m; i++)
                                {
-                                       iw = 2 * (inverse ? (n - i * k) : (i * k));
+                                       iw = inverse ? (n - i * k) : (i * k);
                                        butterfly(this, b, t + i, t + i + m, iw);
                                }                               
                        }
@@ -167,7 +167,7 @@ METHOD(bliss_fft_t, transform, void,
        {
                for (i = 0; i < n; i++)
                {
-                       b[i] = (((b[i] * this->p->w[2*n - i]) % q) * this->p->n_inv) % q;
+                       b[i] = bliss_mreduce(b[i] * this->p->wi[i], this->p);
                }
        }
 }
index c892c06..aac5d0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 #include "bliss_fft_params.h"
 
 /**
- * FFT parameters for q = 12289 and 2n = 1024
+ * FFT twiddle factors in Montgomery form for q = 12289 and n = 512
  */
-static uint16_t w_12289_1024[] = {
-           1,    49,  2401,  7048,  1260,   295,  2166,  7822,  2319,  3030,
-        1002, 12231,  9447,  8210,  9042,   654,  7468,  9551,  1017,   677,
-        8595,  3329,  3364,  5079,  3091,  3991, 11224,  9260, 11336,  2459,
-        9890,  5339,  3542,  1512,   354,  5057,  2013,   325,  3636,  6118,
-        4846,  3963,  9852,  3477, 10616,  4046,  1630,  6136,  5728, 10314,
-        1537,  1579,  3637,  6167,  7247, 11011, 11112,  3772,   493, 11868,
-        3949,  9166,  6730, 10256, 10984,  9789,   390,  6821,  2426,  8273,
-       12129,  4449,  9088,  2908,  7313,  1956,  9821,  1958,  9919,  6760,
-       11726,  9280,    27,  1323,  3382,  5961,  9442,  7965,  9326,  2281,
-        1168,  8076,  2476, 10723,  9289,   468, 10643,  5369,  5012, 12097,
-
-        2881,  5990, 10863,  3860,  4805,  1954,  9723,  9445,  8112,  4240,
-       11136,  4948,  8961,  8974,  9611,  3957,  9558,  1360,  5195,  8775,
-       12149,  5429,  7952,  8689,  7935,  7856,  3985, 10930,  7143,  5915,
-        7188,  8120,  4632,  5766, 12176,  6752, 11334,  2361,  5088,  3532,
-        1022,   922,  8311,  1702,  9664,  6554,  1632,  6234, 10530, 12121,
-        4057,  2169,  7969,  9522, 11885,  4782,   827,  3656,  7098,  3710,
-        9744, 10474,  9377,  4780,   729, 11143,  5291,  1190,  9154,  6142,
-        6022,   142,  6958,  9139,  5407,  6874,  5023,   347,  4714,  9784,
-         145,  7105,  4053,  1973, 10654,  5908,  6845,  3602,  4452,  9235,
-       10111,  3879,  5736, 10706,  8456,  8807,  1428,  8527, 12286, 12142,
-
-        5086,  3434,  8509, 11404,  5791,  1112,  5332,  3199,  9283,   174,
-        8526, 12237,  9741, 10327,  2174,  8214,  9238, 10258, 11082,  2302,
-        2197,  9341,  3016,   316,  3195,  9087,  2859,  4912,  7197,  8561,
-        1663,  7753, 11227,  9407,  6250, 11314,  1381,  6224, 10040,   400,
-     7311,  1858,  5019,   151,  7399,  6170,  7394,  5925,  7678,  7552,
-        1378,  6077,  2837,  3834,  3531,   973, 10810,  1263,   442,  9369,
-        4388,  6099,  3915,  7500, 11119,  4115,  5011, 12048,   480, 11231,
-        9603,  3565,  2639,  6421,  7404,  6415,  7110,  4298,  1689,  9027,
-       12208,  8320,  2143,  6695,  8541,   683,  8889,  5446,  8785,   350,
-        4861,  4698,  9000, 10885,  4938,  8471,  9542,   576,  3646,  6608,
-
-        4278,   709, 10163,  6427,  7698,  8532,   242, 11858,  3459,  9734,
-        9984,  9945,  8034,   418,  8193,  8209,  8993, 10542,   420,  8291,
-         722, 10800,   773,  1010,   334,  4077,  3149,  6833,  3014,   218,
-       10682,  7280,   339,  4322,  2865,  5206,  9314,  1693,  9223,  9523,
-       11934,  7183,  7875,  4916,  7393,  5876,  5277,   504,   118,  5782,
-         671,  8301,  1212, 10232,  9808,  1321,  3284,  1159,  7635,  5445,
-        8736, 10238, 10102,  3438,  8705,  8719,  9405,  6152,  6512, 11863,
-        3704,  9450,  8357,  3956,  9509, 11248, 10436,  7515, 11854,  3263,
-         130,  6370,  4905,  6854,  4043,  1483, 11222,  9162,  6534,   652,
-        7370,  4749, 11499, 10446,  8005, 11286,     9,   441,  9320,  1987,
-
-       11340,  2655,  7205,  8953,  8582,  2692,  9018, 11767, 11289,   156,
-        7644,  5886,  5767, 12225,  9153,  6093,  3621,  5383,  5698,  8844,
-        3241, 11341,  2704,  9606,  3712,  9842,  2987, 11184,  7300,  1319,
+static uint16_t wr_12289_512[] = {
+        4075,  2031,  9987,  2948, 11973,  3202,  7377,  3728,  4536,  2882,
+         975,  6065, 11889, 10431, 12138,  6119,  6364,  4737,  6212,  8455,
+       11316, 11026,  2920,  6190,  4789,  8174,   241,  1058,  8724,  5868,
+        5874,  7991,  3262,  3969,  5594, 11606,  6843, 11939,  7591,  1404,
+        3818, 11713,  5681, 11580,  5862,  3757,   431,  2555,  2344, 11871,
+        4080,  1747,  3998,  1489, 11279,  8212,  5456, 12071,  5009,  7967,
+        7083, 10596,  2766,  5106,  7373,  6413, 11785,  6507,  3988,  2057,
+       10968, 11130,  6844,  2051,  8851,  3570,  6137,   426,  2839,  8333,
+        1041,  4774,  9026,  5919,  5435, 10806,  3127, 11637,  7540,  1843,
+        1003, 11848, 10302,  9634,  3336,  9597,   522, 12133,  6403,    64,
+
+        6196,  6906,  3445,   948,  2683,  2447,  1105, 10970,  3643,  9364,
+        6383,  1200,  5574,   453,  6221,  5486, 10367,  5942, 11502,  2919,
+        3789,  3529,  6008, 10211,    56, 11566,  9115, 10695,  6974,  6956,
+         605,  2503,   382,  7796,  2049,  4049,  1050,  1805,  8077,   835,
+        1728,  7535,  2127,  6992,  1018, 10996,  4624,  5257,  1254,    49,
+        7048,   295,  7822,  3030, 12231,  8210,   654,  9551,   677,  3329,
+        5079,  3991,  9260,  2459,  5339,  1512,  5057,   325,  6118,  3963,
+        3477,  4046,  6136, 10314,  1579,  6167, 11011,  3772, 11868,  9166,
+       10256,  9789,  6821,  8273,  4449,  2908,  1956,  1958,  6760,  9280,
+        1323,  5961,  7965,  2281,  8076, 10723,   468,  5369, 12097,  5990,
+
+        3860,  1954,  9445,  4240,  4948,  8974,  3957,  1360,  8775,  5429,
+        8689,  7856, 10930,  5915,  8120,  5766,  6752,  2361,  3532,   922,
+        1702,  6554,  6234, 12121,  2169,  9522,  4782,  3656,  3710, 10474,
+        4780, 11143,  1190,  6142,   142,  9139,  6874,   347,  9784,  7105,
+        1973,  5908,  3602,  9235,  3879, 10706,  8807,  8527, 12142,  3434,
+       11404,  1112,  3199,   174, 12237, 10327,  8214, 10258,  2302,  9341,
+         316,  9087,  4912,  8561,  7753,  9407, 11314,  6224,   400,  1858,
+         151,  6170,  5925,  7552,  6077,  3834,   973,  1263,  9369,  6099,
+        7500,  4115, 12048, 11231,  3565,  6421,  6415,  4298,  9027,  8320,
+        6695,   683,  5446,   350,  4698, 10885,  8471,   576,  6608,   709,
+
+        6427,  8532, 11858,  9734,  9945,   418,  8209, 10542,  8291, 10800,
+        1010,  4077,  6833,   218,  7280,  4322,  5206,  1693,  9523,  7183,
+        4916,  5876,   504,  5782,  8301, 10232,  1321,  1159,  5445, 10238,
+        3438,  8719,  6152, 11863,  9450,  3956, 11248,  7515,  3263,  6370,
+        6854,  1483,  9162,   652,  4749, 10446, 11286,   441,  1987,  2655,
+        8953,  2692, 11767,   156,  5886, 12225,  6093,  5383,  8844, 11341,
+        9606,  9842, 11184,  1319,  8646,  2925,  5906, 11089,  6715, 11836,
+        6068,  6803,  1922,  6347,   787,  9370,  8500,  8760,  6281,  2078,
+       12233,   723,  3174,  1594,  5315,  5333, 11684,  9786, 11907,  4493,
+       10240,  8240, 11239, 10484,  4212, 11454, 10561,  4754, 10162,  5297,
+
+       11271,  1293,  7665,  7032, 11035, 12240,  5241, 11994,  4467,  9259,
+          58,  4079, 11635,  2738, 11612,  8960,  7210,  8298,  3029,  9830,
+        6950, 10777,  7232, 11964,  6171,  8326,  8812,  8243,  6153,  1975,
+       10710,  6122,  1278,  8517,   421,  3123,  2033,  2500,  5468,  4016,
+        7840,  9381, 10333, 10331,  5529,  3009, 10966,  6328,  4324, 10008,
+        4213,  1566, 11821,  6920,   192,  6299,  8429, 10335,  2844,  8049,
+        7341,  3315,  8332, 10929,  3514,  6860,  3600,  4433,  1359,  6374,
+        4169,  6523,  5537,  9928,  8757, 11367, 10587,  5735,  6055,   168,
+       10120,  2767,  7507,  8633,  8579,  1815,  7509,  1146, 11099,  6147,
+       12147,  3150,  5415, 11942,  2505,  5184, 10316,  6381,  8687,  3054,
+
+        8410,  1583,  3482,  3762,   147,  8855,   885, 11177,  9090, 12115,
+          52,  1962,  4075
+};
+
+/**
+ * FFT phase shift in forward transform for q = 12289 and n = 512
+ */
+static uint16_t wf_12289_512[] = {
         3186,  8646,  5828,  2925,  8146,  5906,  6747, 11089,  2645,  6715,
         9521, 11836,  2381,  6068,  2396,  6803,  1544,  1922,  8155,  6347,
         3778,   787,  1696,  9370,  4437,  8500, 10963,  8760, 11414,  6281,
@@ -73,21 +89,21 @@ static uint16_t w_12289_1024[] = {
         4372,  5315,  2366,  5333,  3248, 11684,  7222,  9786,   243, 11907,
         5860,  4493, 11244, 10240, 10200,  8240, 10512, 11239,  9995, 10484,
         9867,  4212,  9764, 11454,  8241, 10561,  1351,  4754, 11744, 10162,
-
         6378,  5297,  1484, 11271, 11563,  1293,  1912,  7665,  6915,  7032,
          476, 11035, 12288, 12240,  9888,  5241, 11029, 11994, 10123,  4467,
         9970,  9259, 11287,    58,  2842,  4079,  3247, 11635,  4821,  2738,
+
        11272, 11612,  3694,  8960,  8925,  7210,  9198,  8298,  1065,  3029,
          953,  9830,  2399,  6950,  8747, 10777, 11935,  7232, 10276, 11964,
         8653,  6171,  7443,  8326,  2437,  8812,  1673,  8243, 10659,  6153,
         6561,  1975, 10752, 10710,  8652,  6122,  5042,  1278,  1177,  8517,
        11796,   421,  8340,  3123,  5559,  2033,  1305,  2500, 11899,  5468,
         9863,  4016,   160,  7840,  3201,  9381,  4976, 10333,  2468, 10331,
-        2370,  5529,  563,   3009, 12262, 10966,  8907,  6328,  2847,  4324,
-
+        2370,  5529,   563,  3009, 12262, 10966,  8907,  6328,  2847,  4324,
         2963, 10008, 11121,  4213,  9813,  1566,  3000, 11821,  1646,  6920,
         7277,   192,  9408,  6299,  1426,  8429,  7484, 10335,  2566,  2844,
         4177,  8049,  1153,  7341,  3328,  3315,  2678,  8332,  2731, 10929,
+
         7094,  3514,   140,  6860,  4337,  3600,  4354,  4433,  8304,  1359,
         5146,  6374,  5101,  4169,  7657,  6523,   113,  5537,   955,  9928,
         7201,  8757, 11267, 11367,  3978, 10587,  2625,  5735, 10657,  6055,
@@ -95,10 +111,10 @@ static uint16_t w_12289_1024[] = {
         5191,  8579,  2545,  1815,  2912,  7509, 11560,  1146,  6998, 11099,
         3135,  6147,  6267, 12147,  5331,  3150,  6882,  5415,  7266, 11942,
         7575,  2505, 12144,  5184,  8236, 10316,  1635,  6381,  5444,  8687,
-
         7837,  3054,  2178,  8410,  6553,  1583,  3833,  3482, 10861,  3762,
            3,   147,  7203,  8855,  3780,   885,  6498, 11177,  6957,  9090,
         3006, 12115,  3763,    52,  2548,  1962, 10115,  4075,  3051,  2031,
+
         1207,  9987, 10092,  2948,  9273, 11973,  9094,  3202,  9430,  7377,
         5092,  3728, 10626,  4536,  1062,  2882,  6039,   975, 10908,  6065,
         2249, 11889,  4978, 10431,  7270, 12138,  4890,  6119,  4895,  6364,
@@ -106,32 +122,86 @@ static uint16_t w_12289_1024[] = {
        11847,  2920,  7901,  6190,  8374,  4789,  1170,  8174,  7278,   241,
        11809,  1058,  2686,  8724,  9650,  5868,  4885,  5874,  5179,  7991,
        10600,  3262,    81,  3969, 10146,  5594,  3748, 11606,  3400,  6843,
-
         3504, 11939,  7428,  7591,  3289,  1404,  7351,  3818,  2747, 11713,
         8643,  5681,  8011, 11580,  2126,  5862,  4591,  3757, 12047,   431,
         8830,  2555,  2305,  2344,  4255, 11871,  4096,  4080,  3296,  1747,
+
        11869,  3998, 11567,  1489, 11516, 11279, 11955,  8212,  9140,  5456,
         9275, 12071,  1607,  5009, 11950,  7967,  9424,  7083,  2975, 10596,
         3066,  2766,   355,  5106,  4414,  7373,  4896,  6413,  7012, 11785,
        12171,  6507, 11618,  3988, 11077,  2057,  2481, 10968,  9005, 11130,
         4654,  6844,  3553,  2051,  2187,  8851,  3584,  3570,  2884,  6137,
-        5777,   426,  8585,  2839,  3932,  8333,  2780,  1041,  1853,  4774,
+        5777,   426,  8585,  2839,  3932,  8333,  2780,  1041,  1853,  4774,
          435,  9026, 12159,  5919,  7384,  5435,  8246, 10806,  1067,  3127,
-
         5755, 11637,  4919,  7540,   790,  1843,  4284,  1003, 12280, 11848,
         2969, 10302,   949,  9634,  5084,  3336,  3707,  9597,  3271,   522,
         1000, 12133,  4645,  6403,  6522,    64,  3136,  6196,  8668,  6906,
+
         6591,  3445,  9048,   948,  9585,  2683,  8577,  2447,  9302,  1105,
-        4989, 10970,  9103,  3643,  6461,  9364,  4143,  6383,  5542,  1200,
-        9644,  5574,  2768,   453,  9908,  6221,  9893,  5486, 10745, 10367,
-        4134,  5942,  8511, 11502, 10593,  2919,  7852,  3789,  1326,  3529,
-         875,  6008, 11745, 10211,  8779,    56,  2744, 11566,  1440,  9115,
-        4231, 10695,  7917,  6974,  9923,  6956,  9041,   605,  5067,  2503,
-       12046,   382,  6429,  7796,  1045,  2049,  2089,  4049,  1777,  1050,
-
-        2294,  1805,  2422,  8077,  2525,   835,  4048,  1728, 10938,  7535,
-         545,  2127,  5911,  6992, 10805,  1018,   726, 10996, 10377,  4624,
-         5374, 5257, 11813,  1254,     1
+        4989, 10970,
+};
+
+/**
+ * FFT phase shift and scaling inverse transform for q = 11289 and n = 512
+ */
+static uint16_t wi_12289_512[] = {
+       12265,  6771, 11424,  9011,  6203, 11914,  9021,  6454,  7154,   146,
+       11038,  4238,  5604, 10397, 11498,  3495,  7846,  7684,  1160,  4538,
+         845,  2776,  3317,  5836,  6389, 11667,  6508,  1136, 11309, 12269,
+       11787,  9520,  5461,  3121,  5832,  1373,  1282, 10058,  4218,  5102,
+        7628,  4670,  6616,  1389,  9057,  2442,  2307,  5063,  7878, 10945,
+       10506,   716,   767,  3276,  3578,  1327,  5043,  7376,  8176,  3678,
+        3837,  6599,  4649,  4860, 11385,  9261,   189,  3515,  8348, 10453,
+        7988,  1417,  7302,  1403,  2035,  8067,  2171,  6565, 11169,  8755,
+        4693, 10880,  2730,  7078,  3154, 10347, 10243,  2717,  3065,  9342,
+        3451,  1826,  4050,  3343,  1573,  6302,   881, 11053, 10759, 10753,
+
+        3229,  6085, 11410,  3744,   578, 12050,  7519,  3163,  9344,  5959,
+         874,  2275,  1802, 10821,  2478, 10584,   216,   506,  7785,  4924,
+        5618,  3375,  4834,  3359,  9348, 10975, 11259, 11014, 11009,  4739,
+        7119,  5412,  3120,  4578,  1849,  8314,  4684, 11883,  7014,  8921,
+        3944,  5598,  2873,  2065,  8820,   180,  4518,   343,     7,  8778,
+        8957, 12221,   751,  7790, 11194,  3238,  5082,  7126,  1901, 12077,
+        4510,  2600,  3815,  3589,  2832, 12096,  3758,  5845,  5386,  7383,
+        4665,   346,  3769,  7350,   150,  3765,  2334,  2054,  7315,  5416,
+        8136,  2674, 10588,  5232, 10891,  4235,  1842, 11825,  8016, 11951,
+        6263,  1131,  5039,  2360, 10080,  7228,  6919,   392,     8, 10032,
+
+        8481,  5189,  6125,   125,  9282,  1945,  5808,  8144,   417,  6780,
+       10421,  4727,  4360, 11124,  1481,  1535,  7806,  6680,  7911,  3171,
+        7087,  2151,  6063,  8400,  1927,  7814,  4423,  4103,  8360,   923,
+        2276,  3056, 10345,  7735,  3669,  4840, 10883,  6492,  5650,  6636,
+        1891, 11826,  9270, 11475, 11520,  6505,  9663,   448,  8787,  7954,
+        7937, 11197,  7000,  3654, 10608,  5734,  1371, 11063, 11010,  5993,
+        6643, 10669,  8494,  9202, 12226,  7021,  5410,   612,  5530,  3624,
+        9855,  7725,  3418,  9600,  7469,  1908,  8566,  1178,  2532,  4566,
+       11379,  1737,  3045,  8840,   682,  7287,  7171,  9175,  2946,  7584,
+       10939,  2982,  3572,  6092,  7899,   412,   510,   512,  3020,  2068,
+
+         293, 11041,  8000,  4176,  1590,  3042,  5078,  2110,  3805,  3338,
+        7592,  8682, 11463,  8761, 12217,  8024,  9694,  2455,  6320, 11164,
+        2485,  7073,  9173,   438,  8536,   425,  4523,  6613,  9916, 10485,
+       11249, 10763,  3480,  1325,  2535,  8328,  9951,  5219,  6878, 10423,
+        7235,  3408,  9349, 12229, 10783,  3982,  4094,  9363,  5207,  4119,
+        3846,  5596,   365,  3017, 10595,  1721,  7559,  4167,  2593,  7326,
+        6921,  2900, 11345,  8257,  6940,  2148,  2301,  9828, 10734,  3981,
+        2840,  9839, 12239, 11034, 11511,  7508,  1658,  2291,  9577,  3205,
+         567, 10545,   466,  6781, 11675,  4251,  9617,  4209,  6105, 11912,
+        6513,  7406,  8929,  1687,  1790,  8062,  8190,  8945,  9462,  6463,
+
+        6151,  8151,  9195,  3448, 10353,  5478, 12150, 10029,  4719,  6617,
+        2643,  8581,  7699,  7681,  9687,  5966,  9652, 11232,  1734, 11572,
+       10268,  9489,  3454,  5588,  2622,  6825,  5406,  7885,  7434,  7174,
+         648,  1518, 11066,  2483,  4565, 10125,  2213, 10077,  3466,  8347,
+        9199,  8464,  8449,  1928,  9068,  3947,  9360,  1445,  5547,   364,
+        1763, 11071,  8753,  2185, 11832,  4505,  8619,  6195,  1882,   540,
+        1265,  1029,    21,  1756,  2293, 12085,  2253, 11081,  9004,  9714,
+        2957,  9089,  5703, 11653,  1241,  7800, 11445, 10767,  8496, 11710,
+       11274,  5246,  3869,  9860,  1706,  1038, 11307,  9761,   450, 11295,
+        7002,  6162,  9656,  3959, 12119,  8022,  7186,  3407,  8095,   416,
+
+        5526, 10897, 11759, 11275,  6500,  3393,  2828,  7080,  5662,  9395,
+        8468,  1176,
 };
 
 /**
@@ -198,18 +268,30 @@ static uint16_t rev_512[] = {
 };
 
 bliss_fft_params_t bliss_fft_12289_512 = {
-       12289, 512, 12265, 9, w_12289_1024, rev_512
+       12289, 12287, 18, 3186, (1<<18)-1, 512, 12265, 9,
+       wr_12289_512, wf_12289_512, wi_12289_512, rev_512
 };
 
 /**
- * FFT parameters for q = 17 and n = 16
+ * FFT twiddle factors in Montgomery form for q = 17 and n = 8
+ */
+static uint16_t wr_17_8[] = { 15, 16, 8, 4, 2, 1, 9, 13, 15 };
+
+/**
+ * FFT phase shift in forward transform for q = 17 and n = 8
  */
-static uint16_t w_17_16[] = {
-       1, 3, 9, 10, 13, 5, 15, 11, 16, 14, 8, 7, 4, 12, 2, 6, 1 };
+static uint16_t wf_17_8[] = { 4, 12, 2, 6, 1, 3, 9, 10 };
+
+/**
+ * FFT phase shift and scaling inverse transform for q = 17 and n = 8
+ */
+static uint16_t wi_17_8[] = { 15, 5, 13, 10, 9, 3, 1, 6 };
 
 /**
  * Bit-reversed indices for n = 8
  */
 static uint16_t rev_8[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
 
-bliss_fft_params_t bliss_fft_17_8 = { 17, 8, 15, 3, w_17_16, rev_8 };
+bliss_fft_params_t bliss_fft_17_8 = {
+       17, 15, 5, 4, (1<<5)-1, 8, 15, 3, wr_17_8, wf_17_8, wi_17_8, rev_8
+};
index 31b151b..a709ee4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -36,6 +36,26 @@ struct bliss_fft_params_t {
        uint16_t q;
 
        /**
+        * Inverse of Prime modulus (-q_inv * q mod r = 1)
+        */
+       uint16_t q_inv;
+
+       /**
+        * Logarithm of Montgomery radix: log2(r)
+        */
+       uint16_t rlog;
+
+       /**
+        * Square of Montgomery radix: r^2 mod q
+        */
+       uint32_t r2;
+
+       /**
+        * Montgomery radix mask: (1<<rlog) - 1
+        */
+       uint32_t rmask;
+
+       /**
         * Size of the FFT with the condition k * n = q-1
         */
        uint16_t n;
@@ -51,9 +71,19 @@ struct bliss_fft_params_t {
        uint16_t stages;
 
        /**
-        * FFT twiddle factors (n-th roots of unity)
+        * FFT twiddle factors (n-th roots of unity) in Montgomery form
+        */
+       uint16_t *wr;
+
+       /**
+        * FFT phase shift (2n-th roots of unity) in forward transform
+        */
+       uint16_t *wf;
+
+       /**
+        * FFT phase shift (2n-th roots of unity) and scaling in inverse transform
         */
-       uint16_t *w;
+       uint16_t *wi;
 
        /**
         * FFT bit reversal
index 20bbc6a..68c0ea2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014-2015 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
 #include "bliss_signature.h"
 #include "bliss_bitpacker.h"
 #include "bliss_fft.h"
+#include "bliss_reduce.h"
 
 #include <crypto/mgf1/mgf1_bitspender.h>
 #include <asn1/asn1.h>
@@ -64,6 +65,11 @@ struct private_bliss_private_key_t {
        uint32_t *A;
 
        /**
+        * NTT of BLISS public key in Montgomery representation Ar = rA mod
+        */
+       uint32_t *Ar;
+
+       /**
         * reference count
         */
        refcount_t ref;
@@ -337,7 +343,7 @@ static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg,
 
                for (i = 0; i < n; i++)
                {
-                       ay[i] = (this->A[i] * ay[i]) % q;
+                       ay[i] = bliss_mreduce(this->Ar[i] * ay[i], this->set->fft_params);
                }
                fft->transform(fft, ay, ay, TRUE);
 
@@ -668,6 +674,7 @@ METHOD(private_key_t, destroy, void,
                        free(this->s2);
                }
                free(this->A);
+               free(this->Ar);
                free(this);
        }
 }
@@ -795,13 +802,13 @@ static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa)
 /**
  * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q
  */
-static uint32_t invert(uint32_t x, uint16_t q)
+static uint32_t invert(private_bliss_private_key_t *this, uint32_t x)
 {
        uint32_t x1, x2;
        uint16_t q2;
        int i, i_max;
 
-       q2 = q - 2;
+       q2 = this->set->q - 2;
        x1 = (q2 & 1) ? x : 1;
        x2 = x;
        i_max = 15;
@@ -812,11 +819,11 @@ static uint32_t invert(uint32_t x, uint16_t q)
        }
        for (i = 1; i <= i_max; i++)
        {
-               x2 = (x2 * x2) % q;
+               x2 = bliss_mreduce(x2 * x2, this->set->fft_params);
 
                if (q2 & (1 << i))
                {
-                       x1 = (x1 * x2) % q;
+                       x1 = bliss_mreduce(x1 * x2, this->set->fft_params);
                }
        }
 
@@ -1068,7 +1075,8 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
        S1 = malloc(n * sizeof(uint32_t));
        S2 = malloc(n * sizeof(uint32_t));
        a  = malloc(n * sizeof(uint32_t));
-       this->A = malloc(n * sizeof(uint32_t));
+       this->A  = malloc(n * sizeof(uint32_t));
+       this->Ar = malloc(n * sizeof(uint32_t));
 
        /* Instantiate a true random generator */
        rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
@@ -1091,6 +1099,7 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
                fft->transform(fft, S2, S2, FALSE);
 
                success = TRUE;
+
                for (i = 0; i < n; i++)
                {
                        if (S1[i] == 0)
@@ -1103,8 +1112,9 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
                                success = FALSE;
                                break;
                        }
-                       this->A[i] = invert(S1[i], q);
-                       this->A[i] = (S2[i] * this->A[i]) % q;
+                       this->Ar[i] = invert(this, S1[i]);
+                       this->Ar[i] = bliss_mreduce(S2[i] * this->Ar[i], set->fft_params);
+                       this->A[i]  = bliss_mreduce(this->Ar[i], set->fft_params);
                }
        }
        while (!success && trials < SECRET_KEY_TRIALS_MAX);
@@ -1114,13 +1124,15 @@ bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args)
 
        if (success)
        {
-               fft->transform(fft, this->A, a, TRUE);
+               fft->transform(fft, this->Ar, a, TRUE);
 
                DBG4(DBG_LIB, "   i   f   g     a     F     G     A");
                for (i = 0; i < n; i++)
                {
                        DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u",
-                                i, this->s1[i], this->s2[i], a[i], S1[i], S2[i], this->A[i]);
+                                                 i, this->s1[i], this->s2[i],
+                                                 bliss_mreduce(a[i], set->fft_params),
+                                                 S1[i], S2[i], this->A[i]);
                }
        }
        else
@@ -1167,7 +1179,7 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
        asn1_parser_t *parser;
        size_t s_bits = 0;
        int8_t s, s_min = 0, s_max = 0;
-       uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value;
+       uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value, r2;
        bool success = FALSE;
        int objectID, oid, i;
 
@@ -1248,6 +1260,14 @@ bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args)
                                {
                                        goto end;
                                }
+                               this->Ar = malloc(this->set->n * sizeof(uint32_t));
+                               r2 = this->set->fft_params->r2;
+
+                               for (i = 0; i < this->set->n; i++)
+                               {
+                                       this->Ar[i] = bliss_mreduce(this->A[i] * r2,
+                                                                                               this->set->fft_params);
+                               }
                                break;
                        case PRIV_KEY_SECRET1:
                                if (object.len != 1 + (s_bits * this->set->n + 7)/8)
index 93d1165..2f63fdb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Andreas Steffen
+ * Copyright (C) 2014-2016 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -17,6 +17,7 @@
 #include "bliss_signature.h"
 #include "bliss_bitpacker.h"
 #include "bliss_fft.h"
+#include "bliss_reduce.h"
 #include "bliss_utils.h"
 
 #include <asn1/asn1.h>
@@ -45,6 +46,11 @@ struct private_bliss_public_key_t {
        uint32_t *A;
 
        /**
+        * NTT of BLISS public key in Montgomery representation Ar = rA mod
+        */
+       uint32_t *Ar;
+
+       /**
         * reference counter
         */
        refcount_t ref;
@@ -125,7 +131,7 @@ static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg,
 
        for (i = 0; i < n; i++)
        {
-               az[i] = (this->A[i] * az[i]) % q;
+               az[i] = bliss_mreduce(this->Ar[i] * az[i], this->set->fft_params);
        }
        fft->transform(fft, az, az, TRUE);
 
@@ -279,6 +285,7 @@ METHOD(public_key_t, destroy, void,
        {
                lib->encoding->clear_cache(lib->encoding, this);
                free(this->A);
+               free(this->Ar);
                free(this);
        }
 }
@@ -304,7 +311,8 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
        chunk_t blob = chunk_empty, object, param;
        asn1_parser_t *parser;
        bool success = FALSE;
-       int objectID, oid;
+       int objectID, oid, i;
+       uint32_t r2;
 
        while (TRUE)
        {
@@ -380,6 +388,14 @@ bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args)
                                {
                                        goto end;
                                }
+                               this->Ar = malloc(this->set->n * sizeof(uint32_t));
+                               r2 = this->set->fft_params->r2;
+
+                               for (i = 0; i < this->set->n; i++)
+                               {
+                                       this->Ar[i] = bliss_mreduce(this->A[i] * r2,
+                                                                                               this->set->fft_params);
+                               }
                                break;
                }
        }
diff --git a/src/libstrongswan/plugins/bliss/bliss_reduce.h b/src/libstrongswan/plugins/bliss/bliss_reduce.h
new file mode 100644 (file)
index 0000000..2a53d9a
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup bliss_fft bliss_fft
+ * @{ @ingroup bliss_p
+ */
+
+#ifndef BLISS_REDUCE_H_
+#define BLISS_REDUCE_H_
+
+#include "bliss_fft_params.h"
+
+/**
+ * Montgomery Reduction
+ *
+ * Montgomery, P. L. Modular multiplication without trial division.
+ * Mathematics of Computation 44, 170 (1985), 519–521.
+ */
+static inline uint32_t bliss_mreduce(uint32_t x, bliss_fft_params_t *p)
+{
+       uint32_t m, t;
+       
+       m = (x * p->q_inv) & p->rmask;
+       t = (x + m * p->q) >> p->rlog;
+
+       return (t < p->q) ? t : t - p->q;
+}
+
+#endif /** BLISS_REDUCE_H_ @}*/
index 1ad7dfc..ec67f07 100644 (file)
@@ -16,6 +16,7 @@
 #include "test_suite.h"
 
 #include <bliss_fft.h>
+#include <bliss_reduce.h>
 
 #include <time.h>
 
@@ -28,6 +29,7 @@ START_TEST(test_bliss_fft_impulse)
 {
        bliss_fft_t *fft;
        uint16_t n = fft_params[_i]->n;
+       uint32_t rq = (1 << fft_params[_i]->rlog) % fft_params[_i]->q;
        uint32_t x[n], X[n];
        int i;
 
@@ -42,7 +44,7 @@ START_TEST(test_bliss_fft_impulse)
 
        for (i = 0; i < n; i++)
        {
-               ck_assert(X[i] == 1);
+               ck_assert(X[i] == rq);
        }
        fft->transform(fft, X, x, TRUE);
 
@@ -79,7 +81,7 @@ START_TEST(test_bliss_fft_wrap)
 
                for (i = 0; i < n; i++)
                {
-                       Y[i] = (X[i] * Y[i]) % q;
+                       Y[i] = bliss_mreduce(X[i] * Y[i], fft_params[_i]);
                }
                fft->transform(fft, Y, Y, TRUE);