Browse Source

Make ntruprime_rand_tern_t() constant time

Tim Buktu 1 year ago
parent
commit
e08df57c2f
1 changed files with 20 additions and 16 deletions
  1. 20 16
      src/poly.c

+ 20 - 16
src/poly.c

@@ -56,30 +56,34 @@ uint8_t ntruprime_rand_tern(uint16_t N, NtruIntPoly *poly, NtruRandContext *rand
56 56
     return 1;
57 57
 }
58 58
 
59
-int ntru_cmp_uint32(const void *a, const void *b) {
60
-    uint32_t a_int = *(uint32_t*)a;
61
-    uint32_t b_int = *(uint32_t*)b;
62
-    return a_int<b_int ? -1 : 1;
63
-}
64
-
65
-/* not constant time! */
66 59
 uint8_t ntruprime_rand_tern_t(uint16_t N, uint16_t t, NtruIntPoly *poly, NtruRandContext *rand_ctx) {
67 60
     poly->N = N;
68 61
 
69
-    uint32_t arr[N];
70
-    if (ntru_rand_generate((uint8_t*)arr, N*sizeof(arr[0]), rand_ctx) != NTRU_SUCCESS)
62
+    uint8_t rand_bits[(2*t+7)/8];
63
+    if (ntru_rand_generate((uint8_t*)rand_bits, sizeof rand_bits, rand_ctx) != NTRU_SUCCESS)
71 64
         return 0;
72
-
73 65
     uint16_t i;
74
-    for (i=0; i<t; i++)
75
-        arr[i] &= arr[i]%2==0 ? 0xFFFFFFFC : 0xFFFFFFFE;
66
+    for (i=0; i<2*t; i++) {
67
+        uint8_t r = (rand_bits[i/8] >> (i%8)) & 1;
68
+        poly->coeffs[i] = r ? 1 : 2;
69
+    }
76 70
     for (; i<N; i++)
77
-        arr[i] &= 0xFFFFFFFB;
71
+        poly->coeffs[i] = 0;
78 72
 
79
-    qsort(arr, N, sizeof arr[0], &ntru_cmp_uint32);
73
+    uint32_t rand_indices[N];
74
+    if (ntru_rand_generate((uint8_t*)rand_indices, N*sizeof(rand_indices[0]), rand_ctx) != NTRU_SUCCESS)
75
+        return 0;
80 76
 
81
-    for (i=0; i<N; i++)
82
-        poly->coeffs[i] = arr[i] % 4;
77
+    /* Fisher-Yates shuffle */
78
+    uint32_t rand_idx = 0;
79
+    for (i=N-1; i>0; i--) {
80
+        /* slightly biased; for N=739, P(poly contains a biased coeff) = 1/10798 */
81
+        uint32_t j = rand_indices[rand_idx] % (i+1);
82
+        uint16_t temp = poly->coeffs[i];
83
+        poly->coeffs[i] = poly->coeffs[j];
84
+        poly->coeffs[j] = temp;
85
+        rand_idx++;
86
+    }
83 87
     return 1;
84 88
 }
85 89