1 /* Copyright (c) 1998,2011,2014 Apple 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, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
11 * curveParams.c - FEE curve parameter static data and functions
16 * Changed to compile with C++.
18 * Added y1Plus for IEEE P1363 compliance.
19 * Added curveParamsInferFields().
21 * Mods for giantDigit.
23 * Added primeType, m, basePrimeRecip; added a few PT_GENERAL curves.
24 * 19 Jan 1998 at Apple
25 * New curve: q=160, k=57
26 * 09 Jan 1998 at Apple
27 * Removed obsolete (i.e., incomplete) curves parameters.
28 * 11 Jun 1997 at Apple
29 * Added x1OrderPlusRecip and lesserX1OrderRecip fields
30 * Added curveParamsInitGiants()
32 * Major mods for IEEE-style parameters.
37 #include "curveParams.h"
38 #include "giantIntegers.h"
40 #include "ellipticProj.h"
46 typedef unsigned short arrayDigit
;
48 static giant
arrayToGiant(const arrayDigit
*array
);
51 * Can't declare giants statically; we declare them here via static arrayDigit
52 * arrays which contain the 'digits' in base 65536 of a giant
53 * used as a curve parameter. First element is sign; next element is
54 * l.s. digit; size of each array is abs(sign) + 1. These arrays are
55 * converted to a giant via arrayToGiant().
57 * Static q and k values, as well as pointers to the arrayDigit arrays
58 * associated with the various giants for a given curve, are kept in an
59 * array of curveParamsStatic structs; a feeDepth is an index into this
60 * array. A curveParamsStatic struct is converted to a curveParams struct in
61 * curveParamsForDepth().
64 feePrimeType primeType
;
65 feeCurveType curveType
;
68 const arrayDigit
*basePrime
; // FPT_General only
69 arrayDigit m
; // must be 1 for current release
73 const arrayDigit
*x1Plus
;
74 const arrayDigit
*y1Plus
; // optional, currently only used for ECDSA curves
75 const arrayDigit
*x1Minus
; // optional, not used for ECDSA curves
76 const arrayDigit
*cOrderPlus
;
77 const arrayDigit
*cOrderMinus
; // optional, not used for ECDSA curves
78 const arrayDigit
*x1OrderPlus
;
79 const arrayDigit
*x1OrderMinus
; // optional, not used for ECDSA curves
80 const arrayDigit
*x1OrderPlusRecip
;
83 * A null lesserX1OrderRecip when x1OrderPlusRecip is non-null
84 * means that the two values are identical; in this case, only
85 * one giant is alloc'd in the actual curveParams struct.
87 const arrayDigit
*lesserX1OrderRecip
;
91 * First some common giant-arrays used in lots of curveGiants.
93 static const arrayDigit ga_666
[] = {1, 666 }; // a common value for 'c'
94 static const arrayDigit ga_zero
[] = {1, 0 }; // (giant)0
95 static const arrayDigit ga_one
[] = {1, 1 }; // (giant)1
98 * Here are the actual static arrays, one for each giant we know about.
99 * Since they're variable size, we have to allocate and name each one
103 #if FEE_PROTOTYPE_CURVES
104 #include "curveParamDataOld.h"
106 #include "curveParamData.h"
110 * Now the curveParamsStatic structs, which provide templates for creating the
111 * fields in a specific curveParams struct.
113 * All giants in a curveParamsStatic struct except for basePrime are
116 * Note these are stored as an array, an index into which is a feeDepth
119 #if FEE_PROTOTYPE_CURVES
120 static curveParamsStatic curveParamsArray
[] = {
125 NULL
, // basePrime only used for FPT_General
135 ga_w31_1_x1OrderPlus
,
136 ga_w31_1_x1OrderMinus
,
137 ga_w31_1_x1OrderPlusRecip
,
138 ga_w31_1_lesserX1OrderRecip
154 ga_m31_1_x1OrderPlus
,
155 ga_m31_1_x1OrderMinus
,
156 ga_m31_1_x1OrderPlusRecip
,
157 ga_m31_1_lesserX1OrderRecip
163 31, 1, // q=31, k=1, prime curve orders
166 ga_31_1P_a
, // a = 5824692
167 ga_31_1P_b
, // b = 2067311435
174 ga_31_1P_x1OrderPlus
,
175 ga_31_1P_x1OrderMinus
,
176 ga_31_1P_x1OrderPlusRecip
,
177 NULL
// x1PlusOrder is lesser
183 40, 213, // q=40, k=213, prime curve orders
186 ga_40_213_a
, // a = 1627500953
187 ga_40_213_b
, // b = 523907505
193 ga_40_213_minusOrder
,
194 ga_40_213_x1OrderPlus
,
195 ga_40_213_x1OrderMinus
,
196 ga_40_213_x1OrderPlusRecip
,
197 ga_40_213_lesserX1OrderRecip
214 ga_127_1_x1OrderPlus
,
215 ga_127_1_x1OrderMinus
,
216 ga_127_1_x1OrderPlusRecip
,
217 ga_127_1_lesserX1OrderRecip
223 127, 1, // q=127, k=1 Weierstrass
233 ga_127_1W_minusOrder
,
234 ga_127_1W_x1OrderPlus
,
235 ga_127_1W_x1OrderMinus
,
236 ga_127_1W_x1OrderPlusRecip
,
237 NULL
// x1PlusOrder is lesser
242 FCT_Weierstrass
, // also Atkin3
247 ga_160_57_b
, // b = 3
253 ga_160_57_minusOrder
,
254 ga_160_57_x1OrderPlus
,
255 ga_160_57_x1OrderMinus
,
256 ga_160_57_x1OrderPlusRecip
,
257 NULL
// x1PlusOrder is lesser
261 FCT_Weierstrass
, // also Atkin3
266 ga_192_1425_b
, // b = -11
271 ga_192_1425_plusOrder
,
272 ga_192_1425_minusOrder
,
273 ga_192_1425_x1OrderPlus
,
274 ga_192_1425_x1OrderMinus
,
275 ga_192_1425_x1OrderPlusRecip
,
276 NULL
// x1PlusOrder is lesser
285 ga_192_M529891_a
, // a = -152
286 ga_192_M529891_b
, // b = 722
288 ga_192_M529891_x1Plus
,
290 ga_192_M529891_x1Minus
,
291 ga_192_M529891_plusOrder
,
292 ga_192_M529891_minusOrder
,
293 ga_192_M529891_x1OrderPlus
,
294 ga_192_M529891_x1OrderMinus
,
295 ga_192_M529891_x1OrderPlusRecip
,
296 ga_192_M529891_lesserX1OrderRecip
300 * FPT_General curves, currently just copies of known FPT_FEE or FPT_Mersenne
301 * curves with primeType set to FPT_General. These are just for
302 * verification the general curve are handled properly.
303 * We include the q parameter here for use by feeKeyBitsToDepth().
309 ga_127_1_bp
, // explicit basePrime
319 ga_127_1_x1OrderPlus
,
320 ga_127_1_x1OrderMinus
,
321 ga_127_1_x1OrderPlusRecip
,
322 ga_127_1_lesserX1OrderRecip
326 { // depth=10, FPT_General version of q=160
329 160, 0, // we don't use these...
330 ga_160_57_bp
, // explicit basePrime
333 ga_160_57_b
, // b = 3
339 ga_160_57_minusOrder
,
340 ga_160_57_x1OrderPlus
,
341 ga_160_57_x1OrderMinus
,
342 ga_160_57_x1OrderPlusRecip
,
343 NULL
// x1PlusOrder is lesser
346 { // depth=11, FPT_General, 161 bits
350 161, 0, // for verifying we don't use these...
351 ga_161_gen_bp
, // explicit basePrime
353 ga_161_gen_a
, // a = -152
354 ga_161_gen_b
, // b = 722
359 ga_161_gen_plusOrder
,
360 ga_161_gen_minusOrder
,
361 ga_161_gen_x1OrderPlus
,
362 ga_161_gen_x1OrderMinus
,
363 ga_161_gen_x1OrderPlusRecip
,
364 NULL
// x1PlusOrder is lesser
369 #else /* FEE_PROTOTYPE_CURVES */
371 static const curveParamsStatic curveParamsArray
[] = {
375 * FEE CURVE: USE FOR FEE SIG. & FEED ONLY.
376 * primeType->Mersenne
377 * curveType->Montgomery
378 * q = 31; k = 1; p = 2^q - k;
379 * a = 1; b = 0; c = 666;
380 * Both orders composite.
385 NULL
, // basePrime only used for FPT_General
397 ga_31m_x1OrderPlusRecip
,
398 ga_31m_lesserX1OrderRecip
403 * IEEE P1363 COMPATIBLE.
404 * primeType->Mersenne
405 * curveType->Weierstrass
406 * q = 31; k = 1; p = 2^q-k;
407 * a = 5824692 b = 2067311435 c = 0
413 NULL
, // basePrime only used for FPT_General
425 ga_31w_x1OrderPlusRecip
,
426 NULL
// x1PlusOrder is lesser
431 * FEE CURVE: USE FOR FEE SIG. & FEED ONLY.
432 * primeType->Mersenne
433 * curveType->Montgomery
434 * q = 127; k = 1; p = 2^q - k;
435 * a = 1; b = 0; c = 666;
436 * Both orders composite.
440 127, 1, // q = 127; k = 1
441 NULL
, // basePrime only used for FPT_General
452 ga_127m_x1OrderMinus
,
453 ga_127m_x1OrderPlusRecip
,
454 ga_127m_lesserX1OrderRecip
459 * IEEE P1363 COMPATIBLE.
461 * curveType->Weierstrass
462 * q = 127; k = -57675; p = 2^q - k;
463 * a = 170141183460469025572049133804586627403;
464 * b = 170105154311605172483148226534443139403; c = 0;
469 127, -57675, // q = 127; k = -57675
470 NULL
, // basePrime only used for FPT_General
481 ga_128w_x1OrderMinus
,
482 ga_128w_x1OrderPlusRecip
,
483 /* REC said NULL, dmitch says: */
484 ga_128w_lesserX1OrderRecip
// x1PlusOrder is lesser
489 * IEEE P1363 COMPATIBLE.
491 * curveType->Weierstrass
492 * q = 160; k = -5875; p = 2^q - k;
493 * a = 1461501637330902918203684832716283019448563798259;
494 * b = 36382017816364032; c = 0;
495 * Both orders prime.:
499 160, -5875, // q = 160; k = -5875
500 NULL
, // basePrime only used for FPT_General
511 ga_161w_x1OrderMinus
,
512 ga_161w_x1OrderPlusRecip
,
513 /* dmitch addenda - REC said NULL */
514 ga_161w_lesserX1OrderRecip
519 * IEEE P1363 COMPATIBLE.
521 * curveType->Weierstrass
522 * p is a 161-bit random prime (below, ga_161_gen_bp[]);
523 * a = -152; b = 722; c = 0;
524 * Both orders composite.
529 ga_161_gen_bp
, // basePrime
537 ga_161_gen_plusOrder
,
538 ga_161_gen_minusOrder
,
539 ga_161_gen_x1OrderPlus
,
540 ga_161_gen_x1OrderMinus
,
541 ga_161_gen_x1OrderPlusRecip
,
542 NULL
// x1PlusOrder is lesser
547 * IEEE P1363 COMPATIBLE.
548 * (NIST-P-192 RECOMMENDED PRIME)
550 * curveType->Weierstrass
551 * p is a 192-bit random prime (below, ga_161_gen_bp[]);
553 * b = 2455155546008943817740293915197451784769108058161191238065;
555 * Plus-order is prime, minus-order is composite.
559 192, 0, // only used for initGiantStacks(giantMaxDigits())
560 ga_192_gen_bp
, // basePrime
568 ga_192_gen_plusOrder
,
569 ga_192_gen_minusOrder
,
570 ga_192_gen_x1OrderPlus
,
571 ga_192_gen_x1OrderMinus
,
572 ga_192_gen_x1OrderPlusRecip
,
573 ga_192_gen_lesserX1OrderRecip
576 /* ANSI X9.62/Certicom curves */
580 * ANSI X9.62/Certicom secp192r1
584 192, 0, // only used for initGiantStacks(giantMaxDigits())
585 ga_192_secp_bp
, // basePrime
593 ga_192_secp_plusOrder
,
595 ga_192_secp_x1OrderPlus
,
596 NULL
, // x1OrderMinus,
597 ga_192_secp_x1OrderPlusRecip
,
602 * ANSI X9.62/Certicom secp256r1
606 256, 0, // only used for initGiantStacks(giantMaxDigits())
607 ga_256_secp_bp
, // basePrime
615 ga_256_secp_plusOrder
,
617 ga_256_secp_x1OrderPlus
,
619 ga_256_secp_x1OrderPlusRecip
,
625 * ANSI X9.62/Certicom secp384r1
629 384, 0, // only used for initGiantStacks(giantMaxDigits())
630 ga_384_secp_bp
, // basePrime
638 ga_384_secp_plusOrder
,
640 ga_384_secp_x1OrderPlus
,
642 ga_384_secp_x1OrderPlusRecip
,
648 * ANSI X9.62/Certicom secp521r1
653 ga_521_secp_bp
, // basePrime
661 ga_521_secp_plusOrder
,
663 ga_521_secp_x1OrderPlus
,
665 ga_521_secp_x1OrderPlusRecip
,
669 #endif /* FEE_PROTOTYPE_CURVES */
672 * Convert the static form of a giant - i.e., an array of arrayDigits,
673 * the first of which is the sign, the remainder of which are base 65536
674 * digits - into a giant. A null pointer on input results in a null return.
676 static giant
arrayToGiant(const arrayDigit
*array
)
678 unsigned numBytes
; // in result->n[]
679 int numDigits
; // ditto
684 unsigned digitDex
; // index into result->n[]
685 unsigned digitByte
; // byte selector in digit
686 const arrayDigit
*ap
; // running ptr into array
690 CKRaise("arrayToGiant: NULL array");
692 sign
= (short)array
[0];
693 numBytes
= abs(sign
) * sizeof(unsigned short);
694 numDigits
= BYTES_TO_GIANT_DIGITS(numBytes
);
696 /* note giantstruct has one explicit giantDigit */
697 result
= (giant
) fmalloc(sizeof(giantstruct
) +
698 ((numDigits
- 1) * GIANT_BYTES_PER_DIGIT
));
699 result
->capacity
= numDigits
;
705 for(i
=0; i
<numBytes
;) {
706 for(digitByte
=0; digitByte
<GIANT_BYTES_PER_DIGIT
; digitByte
++) {
707 /* grab a byte from the array */
709 /* odd byte - snag it and advance to next array digit */
710 byte
= (unsigned char)(*ap
++ >> 8);
713 /* even, i.e., l.s. byte */
714 byte
= (unsigned char)(*ap
);
717 /* add byte to current digit */
718 digit
|= (byte
<< (8 * digitByte
));
719 if(++i
== numBytes
) {
720 /* end of array, perhaps in the midst of a digit */
724 result
->n
[digitDex
++] = digit
;
729 * -- array elements are unsigned. The first element is
730 * he number of SHORTS in the array; convert to native
732 * -- in the very odd (test only) case of giantDigit = unsigned char,
733 * we might have fewer valid digits than numDigits (might have
737 result
->sign
= -numDigits
;
740 result
->sign
= numDigits
;
747 * Obtain a malloc'd and uninitialized curveParams, to be init'd by caller.
749 curveParams
*newCurveParams(void)
751 curveParams
*params
= (curveParams
*) fmalloc(sizeof(curveParams
));
753 bzero(params
, sizeof(curveParams
));
758 * Alloc and zero reciprocal giants, when maxDigits is known.
759 * Currently only called when creating a curveParams from a public key.
760 * cp->primeType must be valid on input.
762 void allocRecipGiants(curveParams
*cp
)
764 cp
->lesserX1OrderRecip
= newGiant(cp
->maxDigits
);
765 cp
->x1OrderPlusRecip
= newGiant(cp
->maxDigits
);
766 int_to_giant(0, cp
->lesserX1OrderRecip
);
767 int_to_giant(0, cp
->x1OrderPlusRecip
);
771 * Obtain a malloc'd curveParams for a specified feeDepth.
773 curveParams
*curveParamsForDepth(feeDepth depth
)
776 const curveParamsStatic
*cps
= &curveParamsArray
[depth
];
778 if(depth
> FEE_DEPTH_MAX
) {
782 curveParamsInitGiants();
784 cp
= newCurveParams();
785 cp
->primeType
= cps
->primeType
;
786 cp
->curveType
= cps
->curveType
;
790 if(cp
->primeType
== FPT_General
) {
791 cp
->basePrime
= arrayToGiant(cps
->basePrime
);
793 cp
->a
= arrayToGiant(cps
->a
);
794 cp
->b
= arrayToGiant(cps
->b
);
795 cp
->c
= arrayToGiant(cps
->c
);
796 cp
->x1Plus
= arrayToGiant(cps
->x1Plus
);
798 cp
->y1Plus
= arrayToGiant(cps
->y1Plus
);
801 cp
->x1Minus
= arrayToGiant(cps
->x1Minus
);
803 cp
->cOrderPlus
= arrayToGiant(cps
->cOrderPlus
);
804 if(cps
->cOrderMinus
) {
805 cp
->cOrderMinus
= arrayToGiant(cps
->cOrderMinus
);
807 cp
->x1OrderPlus
= arrayToGiant(cps
->x1OrderPlus
);
808 if(cps
->x1OrderMinus
) {
809 cp
->x1OrderMinus
= arrayToGiant(cps
->x1OrderMinus
);
811 cp
->x1OrderPlusRecip
= arrayToGiant(cps
->x1OrderPlusRecip
);
814 * Special case optimization for equal reciprocals.
816 if(cps
->lesserX1OrderRecip
== NULL
) {
817 cp
->lesserX1OrderRecip
= cp
->x1OrderPlusRecip
;
820 cp
->lesserX1OrderRecip
= arrayToGiant(cps
->lesserX1OrderRecip
);
823 /* remainder calculated at runtime */
824 curveParamsInferFields(cp
);
829 * Alloc a new curveParams struct as a copy of specified instance.
830 * This is the only way we can create a curveParams struct which doesn't
831 * match any existing known curve params.
833 curveParams
*curveParamsCopy(curveParams
*cp
)
835 curveParams
*newcp
= newCurveParams();
837 newcp
->primeType
= cp
->primeType
;
838 newcp
->curveType
= cp
->curveType
;
842 newcp
->basePrime
= copyGiant(cp
->basePrime
);
843 newcp
->minBytes
= cp
->minBytes
;
844 newcp
->maxDigits
= cp
->maxDigits
;
846 newcp
->a
= copyGiant(cp
->a
);
847 newcp
->b
= copyGiant(cp
->b
);
848 newcp
->c
= copyGiant(cp
->c
);
849 newcp
->x1Plus
= copyGiant(cp
->x1Plus
);
851 newcp
->x1Minus
= copyGiant(cp
->x1Minus
);
853 newcp
->y1Plus
= copyGiant(cp
->y1Plus
);
854 newcp
->cOrderPlus
= copyGiant(cp
->cOrderPlus
);
855 if(cp
->cOrderMinus
) {
856 newcp
->cOrderMinus
= copyGiant(cp
->cOrderMinus
);
858 newcp
->x1OrderPlus
= copyGiant(cp
->x1OrderPlus
);
859 if(cp
->x1OrderMinus
) {
860 newcp
->x1OrderMinus
= copyGiant(cp
->x1OrderMinus
);
863 newcp
->x1OrderPlusRecip
= copyGiant(cp
->x1OrderPlusRecip
);
864 if(cp
->x1OrderPlusRecip
== cp
->lesserX1OrderRecip
) {
866 * Equal reciprocals; avoid new malloc
868 newcp
->lesserX1OrderRecip
= newcp
->x1OrderPlusRecip
;
871 newcp
->lesserX1OrderRecip
= copyGiant(cp
->lesserX1OrderRecip
);
873 if(cp
->primeType
== FPT_General
) {
874 newcp
->basePrimeRecip
= copyGiant(cp
->basePrimeRecip
);
880 * Free a curveParams struct.
882 void freeCurveParams(curveParams
*cp
)
884 if(cp
->basePrime
!= NULL
) {
885 freeGiant(cp
->basePrime
);
896 if(cp
->x1Plus
!= NULL
) {
897 freeGiant(cp
->x1Plus
);
899 if(cp
->x1Minus
!= NULL
) {
900 freeGiant(cp
->x1Minus
);
902 if(cp
->y1Plus
!= NULL
) {
903 freeGiant(cp
->y1Plus
);
905 if(cp
->cOrderPlus
!= NULL
) {
906 freeGiant(cp
->cOrderPlus
);
908 if(cp
->cOrderMinus
!= NULL
) {
909 freeGiant(cp
->cOrderMinus
);
911 if(cp
->x1OrderPlus
!= NULL
) {
912 freeGiant(cp
->x1OrderPlus
);
914 if(cp
->x1OrderMinus
!= NULL
) {
915 freeGiant(cp
->x1OrderMinus
);
917 if(cp
->x1OrderPlusRecip
!= NULL
) {
918 freeGiant(cp
->x1OrderPlusRecip
);
922 * Special case - if these are equal, we only alloc'd one giant
924 if(cp
->lesserX1OrderRecip
!= cp
->x1OrderPlusRecip
) {
925 freeGiant(cp
->lesserX1OrderRecip
);
927 if(cp
->basePrimeRecip
!= NULL
) {
928 freeGiant(cp
->basePrimeRecip
);
934 * Returns 1 if two sets of curve parameters are equivalent, else returns 0.
936 int curveParamsEquivalent(curveParams
*cp1
, curveParams
*cp2
)
940 * Trivial case, actually common for signature verify
944 if(cp1
->primeType
!= cp2
->primeType
) {
947 if(cp1
->curveType
!= cp2
->curveType
) {
950 if(cp1
->k
!= cp2
->k
) {
953 if(cp1
->q
!= cp2
->q
) {
956 if(cp1
->m
!= cp2
->m
) {
959 if(gcompg(cp1
->basePrime
, cp2
->basePrime
)) {
962 if(gcompg(cp1
->a
, cp2
->a
)) {
965 if(gcompg(cp1
->b
, cp2
->b
)) {
968 if(gcompg(cp1
->c
, cp2
->c
)) {
971 if(gcompg(cp1
->x1Plus
, cp2
->x1Plus
)) {
974 if((cp1
->x1Minus
!= NULL
) && (cp2
->x1Minus
!= NULL
)) {
975 if(gcompg(cp1
->x1Minus
, cp2
->x1Minus
)) {
979 if(gcompg(cp1
->cOrderPlus
, cp2
->cOrderPlus
)) {
982 if((cp1
->cOrderMinus
!= NULL
) && (cp2
->cOrderMinus
!= NULL
)) {
983 if(gcompg(cp1
->cOrderMinus
, cp2
->cOrderMinus
)) {
987 if(gcompg(cp1
->x1OrderPlus
, cp2
->x1OrderPlus
)) {
990 if((cp1
->x1OrderMinus
!= NULL
) && (cp2
->x1OrderMinus
!= NULL
)) {
991 if(gcompg(cp1
->x1OrderMinus
, cp2
->x1OrderMinus
)) {
996 * If we got this far, reciprocals can't possibly be different
1002 * Obtain the lesser of {x1OrderPlus, x1OrderMinus}. Returned value is not
1003 * malloc'd; it's a pointer to one of the orders in *cp.
1005 giant
lesserX1Order(curveParams
*cp
)
1007 CKASSERT(!isZero(cp
->x1OrderPlus
));
1009 if(cp
->x1OrderMinus
== NULL
) {
1010 return(cp
->x1OrderPlus
);
1012 else if(gcompg(cp
->x1OrderPlus
, cp
->x1OrderMinus
) >= 0) {
1013 return(cp
->x1OrderMinus
);
1016 return(cp
->x1OrderPlus
);
1020 #if GIANTS_VIA_STACK
1023 * Prime the curveParams and giants modules for quick allocs of giants.
1025 static int giantsInitd
= 0;
1027 void curveParamsInitGiants(void)
1029 const curveParamsStatic
*cps
= &curveParamsArray
[FEE_DEPTH_MAX
];
1036 * Figure the max giant size of the largest depth we know about...
1038 initGiantStacks(giantMaxDigits(giantMinBytes(cps
->q
, cps
->k
)));
1042 #endif // GIANTS_VIA_STACK
1045 * Infer the following fields from a partially constructed curveParams:
1047 * basePrimeRecip if primeType == FPT_General
1048 * basePrime if primeType != FPT_General
1049 * y1Plus if curveType == FCT_Weierstrass and not pre-calculated
1053 * Assumes the following valid on entry:
1056 * basePrime if primeType == FPT_General
1057 * q, k if primeType != FPT_General
1059 void curveParamsInferFields(curveParams
*cp
)
1061 /* calc maxDigits, minBytes */
1064 /* basePrime or its reciprocal */
1065 if(cp
->primeType
== FPT_General
) {
1066 /* FIXME this should be declared statically! */
1067 cp
->basePrimeRecip
= newGiant(cp
->maxDigits
);
1068 make_recip(cp
->basePrime
, cp
->basePrimeRecip
);
1072 * FPT_FEE, FPT_Mersenne
1074 cp
->basePrime
= newGiant(cp
->maxDigits
);
1079 #if CRYPTKIT_ELL_PROJ_ENABLE
1080 if(cp
->curveType
== FCT_Weierstrass
) {
1081 if(cp
->y1Plus
== NULL
) {
1082 /* ECDSA Curves already have this */
1083 pointProj pt
= newPointProj(cp
->maxDigits
);
1084 findPointProj(pt
, cp
->x1Plus
, cp
);
1086 /* initial point is supposed to be on curve! */
1087 if(gcompg(pt
->x
, cp
->x1Plus
)) {
1088 CKRaise("curveParamsInferFields failure");
1090 cp
->y1Plus
= copyGiant(pt
->y
);
1095 cp
->y1Plus
= newGiant(1);
1097 #else /* CRYPTKIT_ELL_PROJ_ENABLE */
1098 cp
->y1Plus
= newGiant(1);
1101 if((cp
->x1OrderPlusRecip
== NULL
) || isZero(cp
->x1OrderPlusRecip
)) {
1103 * an easy way of figuring this one out, this should not
1106 cp
->x1OrderPlusRecip
= newGiant(cp
->maxDigits
);
1107 make_recip(cp
->x1OrderPlus
, cp
->x1OrderPlusRecip
);
1108 if(cp
->lesserX1OrderRecip
!= NULL
) {
1109 freeGiant(cp
->lesserX1OrderRecip
);
1111 cp
->lesserX1OrderRecip
= cp
->x1OrderPlusRecip
;
1116 * Given key size in bits, obtain the asssociated depth.
1117 * Returns FR_IllegalDepth if specify key size not found
1118 * in current curve tables.
1122 #if FEE_PROTOTYPE_CURVES
1123 feeReturn
feeKeyBitsToDepth(unsigned keySize
,
1124 feePrimeType primeType
, /* FPT_Fefault means "best one" */
1125 feeCurveType curveType
, /* FCT_Default means "best one" */
1128 feeReturn frtn
= FR_Success
;
1132 case FCT_Montgomery
:
1134 *depth
= FEE_DEPTH_31_1_M
;
1136 case FCT_Weierstrass
:
1137 *depth
= FEE_DEPTH_31_1_P
;
1143 case FCT_Weierstrass
:
1145 *depth
= FEE_DEPTH_40_213
;
1147 case FCT_Montgomery
:
1148 return FR_IllegalDepth
;
1153 case FCT_Montgomery
:
1154 if(primeType
== FPT_General
) {
1155 *depth
= FEE_DEPTH_127_GEN
;
1158 *depth
= FEE_DEPTH_127_1
;
1161 case FCT_Weierstrass
:
1163 *depth
= FEE_DEPTH_127_1W
;
1169 case FCT_Montgomery
:
1170 return FR_IllegalDepth
;
1171 case FCT_Weierstrass
:
1173 if(primeType
== FPT_General
) {
1174 *depth
= FEE_DEPTH_160_GEN
;
1177 *depth
= FEE_DEPTH_160_57
;
1184 case FCT_Montgomery
:
1185 *depth
= FEE_DEPTH_192_M529891
;
1186 case FCT_Weierstrass
:
1188 *depth
= FEE_DEPTH_192_1425
;
1193 frtn
= FR_IllegalDepth
;
1197 printf("feeKeyBitsToDepth: depth %d\n", *depth
);
1202 #else /* FEE_PROTOTYPE_CURVES */
1204 feeReturn
feeKeyBitsToDepth(unsigned keySize
,
1205 feePrimeType primeType
, /* FPT_Fefault means "best one" */
1206 feeCurveType curveType
, /* FCT_Default means "best one" */
1209 feeReturn frtn
= FR_Success
;
1212 if(primeType
== FPT_General
) {
1213 return FR_IllegalDepth
;
1215 /* note we cut a request for FPT_FEE some slack...this is actually
1216 * FPT_Mersenne, but that is technically a subset of FEE. */
1218 case FCT_Montgomery
:
1219 *depth
= FEE_DEPTH_31M
;
1221 case FCT_Weierstrass
:
1223 *depth
= FEE_DEPTH_31W
;
1226 return FR_IllegalDepth
;
1230 /* Montgomery only */
1231 if(primeType
== FPT_General
) {
1232 return FR_IllegalDepth
;
1234 /* note we cut a request for FPT_FEE some slack...this is actually
1235 * FPT_Mersenne, but that is technically a subset of FEE. */
1237 case FCT_Montgomery
:
1239 *depth
= FEE_DEPTH_127M
;
1241 case FCT_Weierstrass
:
1243 return FR_IllegalDepth
;
1247 /* Weierstrass/feemod only */
1251 return FR_IllegalDepth
;
1253 /* FPT_Default, FPT_FEE */
1257 case FCT_Weierstrass
:
1259 *depth
= FEE_DEPTH_128W
;
1262 return FR_IllegalDepth
;
1267 case FCT_Weierstrass
:
1271 *depth
= FEE_DEPTH_161G
;
1275 *depth
= FEE_DEPTH_161W
;
1278 /* i.e., FPT_Mersenne */
1279 return FR_IllegalDepth
;
1283 return FR_IllegalDepth
;
1288 case FCT_Montgomery
:
1290 return FR_IllegalDepth
;
1291 case FCT_Weierstrass
:
1296 *depth
= FEE_DEPTH_192G
;
1299 /* i.e., FPT_Mersenne, FPT_FEE */
1300 return FR_IllegalDepth
;
1309 return FR_IllegalDepth
;
1311 *depth
= FEE_DEPTH_secp192r1
;
1321 return FR_IllegalDepth
;
1328 return FR_IllegalDepth
;
1330 *depth
= FEE_DEPTH_secp256r1
;
1338 return FR_IllegalDepth
;
1345 return FR_IllegalDepth
;
1347 *depth
= FEE_DEPTH_secp384r1
;
1355 return FR_IllegalDepth
;
1362 return FR_IllegalDepth
;
1364 *depth
= FEE_DEPTH_secp521r1
;
1368 frtn
= FR_IllegalDepth
;
1372 printf("feeKeyBitsToDepth: depth %d\n", *depth
);
1377 #endif /* FEE_PROTOTYPE_CURVES */
1380 * Obtain depth for specified curveParams
1382 feeReturn
curveParamsDepth(
1387 return FR_IllegalArg
;
1390 /* We do it this way to allow reconstructing depth from an encoded curveParams */
1391 feeCurveType curveType
= cp
->curveType
;
1392 if((curveType
== FCT_Weierstrass
) && (cp
->x1Minus
== NULL
)) {
1393 /* actually an ANSI curve */
1394 curveType
= FCT_ANSI
;
1396 return feeKeyBitsToDepth(cp
->q
, cp
->primeType
, curveType
, depth
);