]>
git.saurik.com Git - apple/security.git/blob - libsecurity_cryptkit/lib/engineNSA127.c
1 /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE COMPUTER, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
11 CONFIDENTIAL CONFIDENTIAL CONFIDENTIAL
14 Security Engine code, to be compiled prior to software
15 distribution. The code performs the
16 elliptic curve algebra fundamental to the patented FEE
19 This Engine is designed to be virtually nonmalleable
20 with respect to key size. This is achieved herein
21 via hard-coding of numerical algorithms with respect to
22 the DEPTH = 4 security level (127 bit Mersenne prime).
24 In meetings between the NSA and NeXT Software, Inc. in
25 1995-1996, the notion of Security Engine emerged as a
26 means by which one could discourage disassembly of
27 FEE compilations, especially when such disassembly
28 has the sinister goal of modifying encryption depth.
30 DO NOT EVEN THINK ABOUT READING THE SOURCE CODE
31 BELOW UNLESS YOU ARE EXPLICITLY AUTHORIZED TO DO SO
32 BY NeXT OR ITS DESIGNEE.
35 c. 1996, NeXT Software, Inc.
39 /* This engine requires no initialization. There is one
40 function to becalled externally, namely elliptic().
65 * Changed to compile with C++.
66 * 6 Aug 06 Doug Mitchell at NeXT
67 * 'a' argument to elliptic() and ell_even() is now a giant.
68 * 25 Jul 96 Richard Crandall and Doug Mitchell at NeXT
69 * Wrapped ENGINEmul() with gmersennemod(127,.) to guarantee no
70 * overflow in the hard-coded mul.
71 * Fixed sign calculation bug in ENGINEmul().
72 * 24 Jul 96 Doug Mitchell at NeXT
73 * Made conditional on ENGINE_127_BITS.
74 * Made all functions except for elliptic() static.
75 * Renamed some giants function calls via #define.
76 * Deleted use of array of static pseudo-giants.
77 * Cosmetic changes for debuggability.
78 * 19 Jun 96 Richard Crandall at NeXT
86 * This file is obsolete as of 8 January 1997.
88 #error Hey! New curveParam-dependent 127-bit elliptic() needed!
89 #warning Using NSA-approved 127-bit security engine...
91 #include "NSGiantIntegers.h"
97 * Size of 127-bit giantstruct n[] array, in shorts.
99 #define SHORTCOUNT (8 * 2)
100 #define BORROW_SIZE 0
104 ENGINEmul(giant a
, giant b
) {
105 int a0
,a1
,a2
,a3
,a4
,a5
,a6
,a7
,
106 b0
,b1
,b2
,b3
,b4
,b5
,b6
,b7
;
112 gmersennemod(127, a
);
113 gmersennemod(127, b
);
117 for(j
= abs(asign
); j
< SHORTCOUNT
; j
++) a
->n
[j
] = 0;
118 for(j
= abs(bsign
); j
< SHORTCOUNT
; j
++) b
->n
[j
] = 0;
135 for(j
= 0; j
< SHORTCOUNT
; j
++) b
->n
[j
] = 0;
141 prod
= a0
* mult
+ b
->n
[i
] + car
;
142 b
->n
[i
++] = prod
& DM
;
145 prod
= a1
* mult
+ b
->n
[i
] + car
;
146 b
->n
[i
++] = prod
& DM
;
149 prod
= a2
* mult
+ b
->n
[i
] + car
;
150 b
->n
[i
++] = prod
& DM
;
153 prod
= a3
* mult
+ b
->n
[i
] + car
;
154 b
->n
[i
++] = prod
& DM
;
157 prod
= a4
* mult
+ b
->n
[i
] + car
;
158 b
->n
[i
++] = prod
& DM
;
161 prod
= a5
* mult
+ b
->n
[i
] + car
;
162 b
->n
[i
++] = prod
& DM
;
165 prod
= a6
* mult
+ b
->n
[i
] + car
;
166 b
->n
[i
++] = prod
& DM
;
169 prod
= a7
* mult
+ b
->n
[i
] + car
;
170 b
->n
[i
++] = prod
& DM
;
179 prod
= a0
* mult
+ b
->n
[i
] + car
;
180 b
->n
[i
++] = prod
& DM
;
183 prod
= a1
* mult
+ b
->n
[i
] + car
;
184 b
->n
[i
++] = prod
& DM
;
187 prod
= a2
* mult
+ b
->n
[i
] + car
;
188 b
->n
[i
++] = prod
& DM
;
191 prod
= a3
* mult
+ b
->n
[i
] + car
;
192 b
->n
[i
++] = prod
& DM
;
195 prod
= a4
* mult
+ b
->n
[i
] + car
;
196 b
->n
[i
++] = prod
& DM
;
199 prod
= a5
* mult
+ b
->n
[i
] + car
;
200 b
->n
[i
++] = prod
& DM
;
203 prod
= a6
* mult
+ b
->n
[i
] + car
;
204 b
->n
[i
++] = prod
& DM
;
207 prod
= a7
* mult
+ b
->n
[i
] + car
;
208 b
->n
[i
++] = prod
& DM
;
217 prod
= a0
* mult
+ b
->n
[i
] + car
;
218 b
->n
[i
++] = prod
& DM
;
221 prod
= a1
* mult
+ b
->n
[i
] + car
;
222 b
->n
[i
++] = prod
& DM
;
225 prod
= a2
* mult
+ b
->n
[i
] + car
;
226 b
->n
[i
++] = prod
& DM
;
229 prod
= a3
* mult
+ b
->n
[i
] + car
;
230 b
->n
[i
++] = prod
& DM
;
233 prod
= a4
* mult
+ b
->n
[i
] + car
;
234 b
->n
[i
++] = prod
& DM
;
237 prod
= a5
* mult
+ b
->n
[i
] + car
;
238 b
->n
[i
++] = prod
& DM
;
241 prod
= a6
* mult
+ b
->n
[i
] + car
;
242 b
->n
[i
++] = prod
& DM
;
245 prod
= a7
* mult
+ b
->n
[i
] + car
;
246 b
->n
[i
++] = prod
& DM
;
255 prod
= a0
* mult
+ b
->n
[i
] + car
;
256 b
->n
[i
++] = prod
& DM
;
259 prod
= a1
* mult
+ b
->n
[i
] + car
;
260 b
->n
[i
++] = prod
& DM
;
263 prod
= a2
* mult
+ b
->n
[i
] + car
;
264 b
->n
[i
++] = prod
& DM
;
267 prod
= a3
* mult
+ b
->n
[i
] + car
;
268 b
->n
[i
++] = prod
& DM
;
271 prod
= a4
* mult
+ b
->n
[i
] + car
;
272 b
->n
[i
++] = prod
& DM
;
275 prod
= a5
* mult
+ b
->n
[i
] + car
;
276 b
->n
[i
++] = prod
& DM
;
279 prod
= a6
* mult
+ b
->n
[i
] + car
;
280 b
->n
[i
++] = prod
& DM
;
283 prod
= a7
* mult
+ b
->n
[i
] + car
;
284 b
->n
[i
++] = prod
& DM
;
293 prod
= a0
* mult
+ b
->n
[i
] + car
;
294 b
->n
[i
++] = prod
& DM
;
297 prod
= a1
* mult
+ b
->n
[i
] + car
;
298 b
->n
[i
++] = prod
& DM
;
301 prod
= a2
* mult
+ b
->n
[i
] + car
;
302 b
->n
[i
++] = prod
& DM
;
305 prod
= a3
* mult
+ b
->n
[i
] + car
;
306 b
->n
[i
++] = prod
& DM
;
309 prod
= a4
* mult
+ b
->n
[i
] + car
;
310 b
->n
[i
++] = prod
& DM
;
313 prod
= a5
* mult
+ b
->n
[i
] + car
;
314 b
->n
[i
++] = prod
& DM
;
317 prod
= a6
* mult
+ b
->n
[i
] + car
;
318 b
->n
[i
++] = prod
& DM
;
321 prod
= a7
* mult
+ b
->n
[i
] + car
;
322 b
->n
[i
++] = prod
& DM
;
331 prod
= a0
* mult
+ b
->n
[i
] + car
;
332 b
->n
[i
++] = prod
& DM
;
335 prod
= a1
* mult
+ b
->n
[i
] + car
;
336 b
->n
[i
++] = prod
& DM
;
339 prod
= a2
* mult
+ b
->n
[i
] + car
;
340 b
->n
[i
++] = prod
& DM
;
343 prod
= a3
* mult
+ b
->n
[i
] + car
;
344 b
->n
[i
++] = prod
& DM
;
347 prod
= a4
* mult
+ b
->n
[i
] + car
;
348 b
->n
[i
++] = prod
& DM
;
351 prod
= a5
* mult
+ b
->n
[i
] + car
;
352 b
->n
[i
++] = prod
& DM
;
355 prod
= a6
* mult
+ b
->n
[i
] + car
;
356 b
->n
[i
++] = prod
& DM
;
359 prod
= a7
* mult
+ b
->n
[i
] + car
;
360 b
->n
[i
++] = prod
& DM
;
369 prod
= a0
* mult
+ b
->n
[i
] + car
;
370 b
->n
[i
++] = prod
& DM
;
373 prod
= a1
* mult
+ b
->n
[i
] + car
;
374 b
->n
[i
++] = prod
& DM
;
377 prod
= a2
* mult
+ b
->n
[i
] + car
;
378 b
->n
[i
++] = prod
& DM
;
381 prod
= a3
* mult
+ b
->n
[i
] + car
;
382 b
->n
[i
++] = prod
& DM
;
385 prod
= a4
* mult
+ b
->n
[i
] + car
;
386 b
->n
[i
++] = prod
& DM
;
389 prod
= a5
* mult
+ b
->n
[i
] + car
;
390 b
->n
[i
++] = prod
& DM
;
393 prod
= a6
* mult
+ b
->n
[i
] + car
;
394 b
->n
[i
++] = prod
& DM
;
397 prod
= a7
* mult
+ b
->n
[i
] + car
;
398 b
->n
[i
++] = prod
& DM
;
407 prod
= a0
* mult
+ b
->n
[i
] + car
;
408 b
->n
[i
++] = prod
& DM
;
411 prod
= a1
* mult
+ b
->n
[i
] + car
;
412 b
->n
[i
++] = prod
& DM
;
415 prod
= a2
* mult
+ b
->n
[i
] + car
;
416 b
->n
[i
++] = prod
& DM
;
419 prod
= a3
* mult
+ b
->n
[i
] + car
;
420 b
->n
[i
++] = prod
& DM
;
423 prod
= a4
* mult
+ b
->n
[i
] + car
;
424 b
->n
[i
++] = prod
& DM
;
427 prod
= a5
* mult
+ b
->n
[i
] + car
;
428 b
->n
[i
++] = prod
& DM
;
431 prod
= a6
* mult
+ b
->n
[i
] + car
;
432 b
->n
[i
++] = prod
& DM
;
435 prod
= a7
* mult
+ b
->n
[i
] + car
;
436 b
->n
[i
++] = prod
& DM
;
440 b
->sign
= abs(b
->sign
) + abs(a
->sign
);
441 for(j
= (b
->sign
)-1; j
>= 0; j
--) {
451 ell_even(giant x1
, giant z1
, giant x2
, giant z2
, giant a
, int q
)
455 t1
= borrowGiant(BORROW_SIZE
);
456 t2
= borrowGiant(BORROW_SIZE
);
457 t3
= borrowGiant(BORROW_SIZE
);
459 gtog(x1
, t1
); gsquare(t1
); gmersennemod(q
, t1
);
460 gtog(z1
, t2
); gsquare(t2
); gmersennemod(q
, t2
);
461 gtog(x1
, t3
); ENGINEmul(z1
, t3
);
462 gtog(t1
, x2
); subg(t2
, x2
); gsquare(x2
); gmersennemod(q
, x2
);
465 addg(t1
, z2
); addg(t2
, z2
); ENGINEmul(t3
, z2
);
475 ell_odd(giant x1
, giant z1
, giant x2
, giant z2
, giant
xor, giant zor
, int q
)
479 t1
= borrowGiant(BORROW_SIZE
);
480 t2
= borrowGiant(BORROW_SIZE
);
481 t3
= borrowGiant(BORROW_SIZE
);
483 gtog(x1
, t1
); subg(z1
, t1
);
484 gtog(x2
, t2
); addg(z2
, t2
);
486 gtog(x1
, t1
); addg(z1
, t1
);
487 gtog(x2
, t3
); subg(z2
, t3
);
489 gtog(t2
, x2
); addg(t1
, x2
);
490 gsquare(x2
); gmersennemod(q
, x2
); //?
491 gtog(t2
, z2
); subg(t1
, z2
);
492 gsquare(z2
); gmersennemod(q
, z2
); //?
501 /* Elliptic multiply.
502 For given curve parameter a and given prime p = 2^q-1,
503 the point (xx,zz) becomes k * (xx,zz), in place.
506 elliptic(giant xx
, giant zz
, giant k
, giant a
, int q
)
508 int len
= bitlen(k
), pos
= len
-2;
514 if(scompg(1,k
)) return;
516 ell_even(xx
, zz
, xx
, zz
, a
, q
);
520 zs
= borrowGiant(BORROW_SIZE
);
521 xs
= borrowGiant(BORROW_SIZE
);
522 zorg
= borrowGiant(BORROW_SIZE
);
523 xorg
= borrowGiant(BORROW_SIZE
);
525 gtog(xx
, xorg
); gtog(zz
, zorg
);
526 ell_even(xx
, zz
, xs
, zs
, a
, q
);
528 if(bitval(k
, pos
--)) {
529 ell_odd(xs
, zs
, xx
, zz
, xorg
, zorg
, q
);
530 ell_even(xs
, zs
, xs
, zs
, a
, q
);
532 ell_odd(xx
, zz
, xs
, zs
, xorg
, zorg
, q
);
533 ell_even(xx
, zz
, xx
, zz
, a
, q
);
543 #endif /* ENGINE_127_BITS */