Coverage report: /home/ellis/comp/ext/ironclad/src/math.lisp

KindCoveredAll%
expression0675 0.0
branch0122 0.0
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;;; math.lisp
2
 (in-package :crypto)
3
 
4
 (defun egcd (a b)
5
   "Extended Euclidean algorithm, aka extended greatest common
6
 denominator."
7
   (declare (optimize (speed 3) (safety 0) (space 0) (debug 0))
8
            (type integer a b))
9
   (assert (and (>= a 0)
10
                (>= b 0)))
11
   (do ((q 0)
12
        (c a (- d (* q c)))
13
        (d b c)
14
        (u_c 1 (- u_d (* q u_c)))
15
        (v_c 0 (- v_d (* q v_c)))
16
        (u_d 0 u_c)
17
        (v_d 1 v_c))
18
       ((= c 0)
19
        (values d u_d v_d))
20
    (setq q (floor d c))))
21
 
22
 ;;; Some number theory functions taken from Maxima
23
 (defun jacobi (a b)
24
   (declare (integer a b) (optimize (speed 3)))
25
   (cond ((zerop b)
26
          (if (= 1 (abs a)) 1 0))
27
         ((and (evenp a) (evenp b))
28
          0)
29
         (t
30
          (let ((k 1)
31
                (tab2 (make-array 8 :element-type '(integer -1 1)
32
                                    :initial-contents #(0 1 0 -1 0 -1 0 1))))
33
            (declare (type (integer -1 1) k))
34
            (loop for v fixnum = 0 then (1+ v) ;remove 2's from b
35
                  while (evenp b) do (setf b (ash b -1))
36
                  finally (when (oddp v)
37
                            (setf k (aref tab2 (logand a 7))))) ; (-1)^(a^2-1)/8
38
            (when (minusp b)
39
              (setf b (- b))
40
              (when (minusp a)
41
                (setf k (- k))))
42
            (loop
43
               (when (zerop a)
44
                 (return-from jacobi (if (> b 1) 0 k)))
45
               (loop for v fixnum = 0 then (1+ v)
46
                     while (evenp a) do (setf a (ash a -1))
47
                     finally (when (oddp v)
48
                               (when (minusp (aref tab2 (logand b 7))); (-1)^(b^2-1)/8
49
                                 (setf k (- k)))))
50
               (when (plusp (logand a b 2)) ;compute (-1)^(a-1)(b-1)/4
51
                 (setf k (- k)))
52
               (let ((r (abs a)))
53
                 (setf a (rem b r))
54
                 (setf b r)))))))
55
 
56
 (defun power-mod-tab (b k m)
57
   (declare (optimize (speed 3) (safety 0)))
58
   (let* ((l (ash 1 (1- k)))
59
          (tab (make-array l :element-type 'integer :initial-element 1))
60
          (bi b)
61
          (bb (mod (* b b) m)))
62
     (setf (svref tab 0) b)
63
     (do ((i 1 (1+ i)))
64
         ((= i l) tab)
65
       (setq bi (mod (* bi bb) m))
66
       (setf (svref tab i) bi))))
67
 
68
 (defun power-mod (b e m)
69
   (declare (optimize (speed 3) (safety 0)))
70
   (cond
71
     ((zerop e)
72
       (mod 1 m))
73
     ((typep e 'fixnum)
74
       (do ((res 1)) (())
75
         (when (logbitp 0 e)
76
           (setq res (mod (* res b) m))
77
           (when (= 1 e) (return res)))
78
         (setq e (ash e -1)
79
               b (mod (* b b) m))))
80
     (t ;; sliding window variant:
81
       (let* ((l (integer-length e))
82
              (k (cond ((< l  65) 3)
83
                       ((< l 161) 4)
84
                       ((< l 385) 5)
85
                       ((< l 897) 6)
86
                       (t         7)))
87
              (tab (power-mod-tab b k m))
88
              (res 1) s u tmp)
89
         (do ((i (1- l)))
90
             ((< i 0) res)
91
           (cond
92
             ((logbitp i e)
93
               (setq s (max (1+ (- i k)) 0))
94
               (do () ((logbitp s e)) (incf s))
95
               (setq tmp (1+ (- i s)))
96
               (dotimes (h tmp) (setq res (mod (* res res) m)))
97
               (setq u (ldb (byte tmp s) e))
98
               (unless (= u 0) (setq res (mod (* res (svref tab (ash u -1))) m)))
99
               (setq i (1- s)))
100
             (t
101
               (setq res (mod (* res res) m))
102
               (decf i))))))))
103
 
104
 (defun miller-rabin-decomposition (n) ;; assume n > 2 (n-1 is even)
105
   ;; return values q,k with n-1 = q*2^k
106
   (declare (optimize (speed 3) (safety 0)))
107
   (do ((k 1 (1+ k))
108
        (q (ash n -1) (ash q -1)))
109
       ((logbitp 0 q) (values q k))))
110
 
111
 (defun miller-rabin-kernel (n q k &optional x)
112
   ;; now assume n-1 = q*2^k, k >= 1
113
   (declare (optimize (speed 3) (safety 0)))
114
   (unless x
115
     (setq x (+ (strong-random (- n 2)) 2)))
116
   (let ((y (power-mod x q n)) ;; j = 0
117
         (minus1 (1- n)))
118
     (if (or (= y 1) (= y minus1))
119
       t
120
       (do ((j 1 (1+ j)))
121
           ((= j k))
122
         (setq y (power-mod y 2 n))
123
         (when (= y minus1) (return t))
124
         (when (= y 1) (return)))))) ;; n prime => last y must have been 1 or -1
125
 
126
 (defun lucas-sequence (k p n)
127
   (declare (optimize (speed 3) (safety 0)))
128
   (let ((uh 1) (vl 2) (vh p) (s 0) l)
129
     (do ()
130
         ((logbitp 0 k))
131
       (setq k (ash k -1))
132
       (setq s (1+ s)))
133
     (setq l (integer-length k))
134
     (do ((j (1- l) (1- j)))
135
         ((= 0 j))
136
       (if (logbitp j k)
137
           (progn
138
             (setq uh (mod (* uh vh) n))
139
             (setq vl (mod (- (* vh vl) p) n))
140
             (setq vh (mod (- (* vh vh) 2) n)))
141
           (progn
142
             (setq uh (mod (1- (* uh vl)) n))
143
             (setq vh (mod (- (* vh vl) p) n))
144
             (setq vl (mod (- (* vl vl) 2) n)))))
145
     (setq uh (mod (1- (* uh vl)) n))
146
     (setq vl (mod (- (* vh vl) p) n))
147
     (dotimes (j s)
148
       (setq uh (mod (* uh vl) n))
149
       (setq vl (mod (- (* vl vl) 2) n)))
150
     uh))
151
 
152
 (defun primep-lucas (n)
153
   (declare (optimize (speed 3) (safety 0)))
154
   (let ((b 3))
155
     (loop until (= (jacobi (- (* b b) 4) n) -1) do
156
       (incf b))
157
     (zerop (lucas-sequence (1+ n) b n))))
158
 
159
 ;;; modular arithmetic utilities
160
 (defun modular-inverse (n modulus)
161
   "Returns M such that N * M mod MODULUS = 1"
162
   (declare (type (integer 1 *) modulus))
163
   (declare (type (integer 0 *) n))
164
   (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
165
   (when (or (zerop n) (and (evenp n) (evenp modulus)))
166
     (return-from modular-inverse 0))
167
   (loop
168
      with r1 of-type integer = n
169
      and r2 of-type integer = modulus
170
      and u1 of-type integer = 1
171
      and u2 of-type integer = 0
172
      and q of-type integer = 0
173
      and r of-type integer = 0
174
      until (zerop r2)
175
      do (progn
176
           (multiple-value-setq (q r) (floor r1 r2))
177
           (setf r1 r2
178
                 r2 r)
179
           (decf u1 (* q u2))
180
           (rotatef u1 u2))
181
      finally (return (let ((inverse u1))
182
                        (when (minusp inverse)
183
                          (setf inverse (mod inverse modulus)))
184
                        (if (zerop (mod (* n inverse) modulus))
185
                            0
186
                            inverse)))))
187
 
188
 (defun modular-inverse-with-blinding (n modulus)
189
   "As modular-inverse, but mask N with a blinding factor before
190
 computing the modular inverse."
191
   (declare (type (integer 1 *) modulus))
192
   (declare (type (integer 0 *) n))
193
   (declare (optimize (speed 3) (safety 0) (space 0) (debug 0)))
194
   (let* ((b (loop for b = (+ 1 (strong-random (- modulus 1)))
195
                   until (= 1 (gcd b modulus))
196
                   finally (return b)))
197
          (x (mod (* n b) modulus))
198
          (y (modular-inverse x modulus)))
199
     (mod (* y b) modulus)))
200
 
201
 (defun expt-mod (n exponent modulus)
202
   "As (mod (expt n exponent) modulus), but more efficient (Montgomery ladder)."
203
   (declare (optimize (speed 3) (safety 0) (space 0) (debug 0))
204
            (type integer n exponent modulus))
205
   (assert (<= 0 exponent modulus))
206
   (assert (> modulus 1))
207
   (do ((r0 1)
208
        (r1 n)
209
        (i (1- (integer-length modulus)) (1- i)))
210
       ((minusp i) r0)
211
     (declare (type fixnum i)
212
              (type integer r0 r1))
213
     (if (logbitp i exponent)
214
         (setf r0 (mod (* r0 r1) modulus)
215
               r1 (mod (* r1 r1) modulus))
216
         (setf r1 (mod (* r0 r1) modulus)
217
               r0 (mod (* r0 r0) modulus)))))
218
 
219
 (defun expt-mod/unsafe (n exponent modulus)
220
   "As (mod (expt n exponent) modulus), but more efficient. This function is
221
 faster than expt-mod, but it is not safe against side channel timing attacks."
222
   (power-mod n exponent modulus))
223
 
224
 ;;; prime numbers utilities
225
 (defconst +small-primes+
226
   (make-array 269
227
               :element-type 'fixnum
228
               :initial-contents '(2 3 5 7 11 13 17 19 23 29 31 37 41 43
229
           47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131
230
           137 139 149 151 157 163 167 173 179 181 191 193 197 199 211
231
           223 227 229 233 239 241 251 257 263 269 271 277 281 283 293
232
           307 311 313 317 331 337 347 349 353 359 367 373 379 383 389
233
           397 401 409 419 421 431 433 439 443 449 457 461 463 467 479
234
           487 491 499 503 509 521 523 541 547 557 563 569 571 577 587
235
           593 599 601 607 613 617 619 631 641 643 647 653 659 661 673
236
           677 683 691 701 709 719 727 733 739 743 751 757 761 769 773
237
           787 797 809 811 821 823 827 829 839 853 857 859 863 877 881
238
           883 887 907 911 919 929 937 941 947 953 967 971 977 983 991
239
           997 1009 1013 1019 1021 1031 1033 1039 1049 1051 1061 1063
240
           1069 1087 1091 1093 1097 1103 1109 1117 1123 1129 1151 1153
241
           1163 1171 1181 1187 1193 1201 1213 1217 1223 1229 1231 1237
242
           1249 1259 1277 1279 1283 1289 1291 1297 1301 1303 1307 1319
243
           1321 1327 1361 1367 1373 1381 1399 1409 1423 1427 1429 1433
244
           1439 1447 1451 1453 1459 1471 1481 1483 1487 1489 1493 1499
245
           1511 1523 1531 1543 1549 1553 1559 1567 1571 1579 1583 1597
246
           1601 1607 1609 1613 1619 1621 1627 1637 1657 1663 1667 1669
247
           1693 1697 1699 1709 1721 1723)))
248
 (defconstant +last-small-prime+ 1723)
249
 
250
 (defun generate-small-primes (n)
251
   "Generates a list of all primes up to N using the Sieve of
252
 Eratosthenes.  Was used to generate the list above; included for
253
 mathematical interest."
254
   (assert (<= 2 n (expt 2 20)))
255
   (loop for i from 2 to n
256
      with array = (make-array (1+ n) :initial-element 1)
257
      unless (zerop (aref array i))
258
      do (loop for j from 2 to (floor (/ n i))
259
            do (setf (aref array (* i j)) 0))
260
      finally (return (loop for j from 2 to n
261
                         unless (zerop (aref array j))
262
                         collect j))))
263
 
264
 (defparameter *number-of-miller-rabin-tests* 64)
265
 
266
 (defun prime-p (n &optional (prng *prng*))
267
   "True if N is a prime number (with very high probability; at most 1:2^128
268
 chance of returning true for a composite number with the default
269
 *NUMBER-OF-MILLER-RABIN-TESTS* of 64)."
270
   (declare (type integer n)
271
            (optimize (speed 3)))
272
   (if (<= n +last-small-prime+)
273
       (when (find n +small-primes+) t)
274
       (let ((*prng* prng))
275
         (and (loop for p across +small-primes+
276
                    never (zerop (mod n p)))
277
              (multiple-value-bind (q k) (miller-rabin-decomposition n)
278
                (loop repeat *number-of-miller-rabin-tests*
279
                      always (miller-rabin-kernel n q k)))
280
              (primep-lucas n)))))
281
 
282
 (defun generate-prime-in-range (lower-limit upper-limit &optional (prng *prng*))
283
   (assert (< 0 lower-limit upper-limit))
284
   (loop for r = (strong-random (- upper-limit lower-limit -1) prng)
285
      for x = (+ r lower-limit)
286
      until (prime-p x prng)
287
      finally (return x)))
288
 
289
 (defun generate-prime (num-bits &optional (prng *prng*))
290
   "Return a NUM-BITS-bit prime number with very high
291
 probability (1:2^128 chance of returning a composite number)."
292
   (loop with big = (ash 1 (1- num-bits))
293
      for x = (logior (strong-random big prng) big 1)
294
      until (prime-p x prng)
295
      finally (return x)))
296
 
297
 (defun generate-safe-prime (num-bits &optional (prng *prng*))
298
   "Generate a NUM-BITS-bit prime number p so that (p-1)/2 is prime too."
299
   (loop
300
      for q = (generate-prime (1- num-bits) prng)
301
      for p = (1+ (* 2 q))
302
      until (prime-p p prng)
303
      finally (return p)))
304
 
305
 (defun find-generator (p &optional (prng *prng*))
306
   "Find a random generator of the multiplicative group (Z/pZ)*
307
 where p is a safe prime number."
308
   (assert (> p 3))
309
   (loop
310
      with factors = (list 2 (/ (1- p) 2))
311
      for g = (strong-random p prng)
312
      until (loop
313
               for d in factors
314
               never (= 1 (expt-mod/unsafe g (/ (1- p) d) p)))
315
      finally (return g)))
316
 
317
 (defun find-subgroup-generator (p q &optional (prng *prng*))
318
   "Find a random generator of a subgroup of order Q of the multiplicative
319
 group (Z/pZ)* where p is a prime number."
320
   (let ((f (/ (1- p) q)))
321
     (assert (integerp f))
322
     (loop
323
        for h = (+ 2 (strong-random (- p 3) prng))
324
        for g = (expt-mod/unsafe h f p)
325
        while (= 1 g)
326
        finally (return g))))