libtommath updated to the latest develop branch, commit 0fd5e6c17f Dec 11 14:59:35 2014 +0100
Karel Miko
8 years ago
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_EXPORT_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* based on gmp's mpz_export. | |
18 | * see http://gmplib.org/manual/Integer-Import-and-Export.html | |
19 | */ | |
20 | int mp_export(void* rop, size_t* countp, int order, size_t size, | |
21 | int endian, size_t nails, mp_int* op) { | |
22 | int result; | |
23 | size_t odd_nails, nail_bytes, i, j, bits, count; | |
24 | unsigned char odd_nail_mask; | |
25 | ||
26 | mp_int t; | |
27 | ||
28 | if ((result = mp_init_copy(&t, op)) != MP_OKAY) { | |
29 | return result; | |
30 | } | |
31 | ||
32 | if (endian == 0) { | |
33 | union { | |
34 | unsigned int i; | |
35 | char c[4]; | |
36 | } lint = {0x01020304}; | |
37 | ||
38 | endian = (lint.c[0] == 4 ? -1 : 1); | |
39 | } | |
40 | ||
41 | odd_nails = (nails % 8); | |
42 | odd_nail_mask = 0xff; | |
43 | for (i = 0; i < odd_nails; ++i) { | |
44 | odd_nail_mask ^= (1 << (7 - i)); | |
45 | } | |
46 | nail_bytes = nails / 8; | |
47 | ||
48 | bits = mp_count_bits(&t); | |
49 | count = bits / (size * 8 - nails) + (bits % (size * 8 - nails) ? 1 : 0); | |
50 | ||
51 | for (i = 0; i < count; ++i) { | |
52 | for (j = 0; j < size; ++j) { | |
53 | unsigned char* byte = ( | |
54 | (unsigned char*)rop + | |
55 | (order == -1 ? i : count - 1 - i) * size + | |
56 | (endian == -1 ? j : size - 1 - j) | |
57 | ); | |
58 | ||
59 | if (j >= (size - nail_bytes)) { | |
60 | *byte = 0; | |
61 | continue; | |
62 | } | |
63 | ||
64 | *byte = (unsigned char)(j == size - nail_bytes - 1 ? (t.dp[0] & odd_nail_mask) : t.dp[0] & 0xFF); | |
65 | ||
66 | if ((result = mp_div_2d(&t, (j == size - nail_bytes - 1 ? 8 - odd_nails : 8), &t, NULL)) != MP_OKAY) { | |
67 | mp_clear(&t); | |
68 | return result; | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
73 | mp_clear(&t); | |
74 | ||
75 | if (countp) { | |
76 | *countp = count; | |
77 | } | |
78 | ||
79 | return MP_OKAY; | |
80 | } | |
81 | ||
82 | #endif | |
83 | ||
84 | /* $Source$ */ | |
85 | /* $Revision$ */ | |
86 | /* $Date$ */ |
14 | 14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
15 | 15 | */ |
16 | 16 | |
17 | /* calculate c = a**b using a square-multiply algorithm */ | |
17 | /* wrapper function for mp_expt_d_ex() */ | |
18 | 18 | int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) |
19 | 19 | { |
20 | int res; | |
21 | mp_int g; | |
20 | return mp_expt_d_ex(a, b, c, 0); | |
21 | } | |
22 | 22 | |
23 | if ((res = mp_init_copy (&g, a)) != MP_OKAY) { | |
24 | return res; | |
25 | } | |
26 | ||
27 | /* set initial result */ | |
28 | mp_set (c, 1); | |
29 | ||
30 | while (b > 0) { | |
31 | /* if the bit is set multiply */ | |
32 | if (b & 1) { | |
33 | if ((res = mp_mul (c, &g, c)) != MP_OKAY) { | |
34 | mp_clear (&g); | |
35 | return res; | |
36 | } | |
37 | } | |
38 | ||
39 | /* square */ | |
40 | if (b > 1 && (res = mp_sqr (&g, &g)) != MP_OKAY) { | |
41 | mp_clear (&g); | |
42 | return res; | |
43 | } | |
44 | ||
45 | /* shift to next bit */ | |
46 | b >>= 1; | |
47 | } | |
48 | ||
49 | mp_clear (&g); | |
50 | return MP_OKAY; | |
51 | } | |
52 | 23 | #endif |
53 | 24 | |
54 | 25 | /* $Source$ */ |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_EXPT_D_EX_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* calculate c = a**b using a square-multiply algorithm */ | |
18 | int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast) | |
19 | { | |
20 | int res; | |
21 | unsigned int x; | |
22 | ||
23 | mp_int g; | |
24 | ||
25 | if ((res = mp_init_copy (&g, a)) != MP_OKAY) { | |
26 | return res; | |
27 | } | |
28 | ||
29 | /* set initial result */ | |
30 | mp_set (c, 1); | |
31 | ||
32 | if (fast) { | |
33 | while (b > 0) { | |
34 | /* if the bit is set multiply */ | |
35 | if (b & 1) { | |
36 | if ((res = mp_mul (c, &g, c)) != MP_OKAY) { | |
37 | mp_clear (&g); | |
38 | return res; | |
39 | } | |
40 | } | |
41 | ||
42 | /* square */ | |
43 | if (b > 1 && (res = mp_sqr (&g, &g)) != MP_OKAY) { | |
44 | mp_clear (&g); | |
45 | return res; | |
46 | } | |
47 | ||
48 | /* shift to next bit */ | |
49 | b >>= 1; | |
50 | } | |
51 | } | |
52 | else { | |
53 | for (x = 0; x < DIGIT_BIT; x++) { | |
54 | /* square */ | |
55 | if ((res = mp_sqr (c, c)) != MP_OKAY) { | |
56 | mp_clear (&g); | |
57 | return res; | |
58 | } | |
59 | ||
60 | /* if the bit is set multiply */ | |
61 | if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) { | |
62 | if ((res = mp_mul (c, &g, c)) != MP_OKAY) { | |
63 | mp_clear (&g); | |
64 | return res; | |
65 | } | |
66 | } | |
67 | ||
68 | /* shift to next bit */ | |
69 | b <<= 1; | |
70 | } | |
71 | } /* if ... else */ | |
72 | ||
73 | mp_clear (&g); | |
74 | return MP_OKAY; | |
75 | } | |
76 | #endif | |
77 | ||
78 | /* $Source$ */ | |
79 | /* $Revision$ */ | |
80 | /* $Date$ */ |
15 | 15 | */ |
16 | 16 | |
17 | 17 | /* get the lower 32-bits of an mp_int */ |
18 | unsigned long mp_get_int(mp_int * a) | |
18 | unsigned long mp_get_int(mp_int * a) | |
19 | 19 | { |
20 | 20 | int i; |
21 | ulong64 res; | |
21 | mp_min_u32 res; | |
22 | 22 | |
23 | 23 | if (a->used == 0) { |
24 | 24 | return 0; |
29 | 29 | |
30 | 30 | /* get most significant digit of result */ |
31 | 31 | res = DIGIT(a,i); |
32 | ||
32 | ||
33 | 33 | while (--i >= 0) { |
34 | 34 | res = (res << DIGIT_BIT) | DIGIT(a,i); |
35 | 35 | } |
36 | 36 | |
37 | 37 | /* force result to 32-bits always so it is consistent on non 32-bit platforms */ |
38 | return (unsigned long)(res & 0xFFFFFFFFUL); | |
38 | return res & 0xFFFFFFFFUL; | |
39 | 39 | } |
40 | 40 | #endif |
41 | 41 |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_GET_LONG_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* get the lower unsigned long of an mp_int, platform dependent */ | |
18 | unsigned long mp_get_long(mp_int * a) | |
19 | { | |
20 | int i; | |
21 | unsigned long res; | |
22 | ||
23 | if (a->used == 0) { | |
24 | return 0; | |
25 | } | |
26 | ||
27 | /* get number of digits of the lsb we have to read */ | |
28 | i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; | |
29 | ||
30 | /* get most significant digit of result */ | |
31 | res = DIGIT(a,i); | |
32 | ||
33 | #if ULONG_MAX != 0xfffffffful || DIGIT_BIT < 32 | |
34 | while (--i >= 0) { | |
35 | res = (res << DIGIT_BIT) | DIGIT(a,i); | |
36 | } | |
37 | #endif | |
38 | return res; | |
39 | } | |
40 | #endif |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_GET_LONG_LONG_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* get the lower unsigned long long of an mp_int, platform dependent */ | |
18 | unsigned long long mp_get_long_long (mp_int * a) | |
19 | { | |
20 | int i; | |
21 | unsigned long long res; | |
22 | ||
23 | if (a->used == 0) { | |
24 | return 0; | |
25 | } | |
26 | ||
27 | /* get number of digits of the lsb we have to read */ | |
28 | i = MIN(a->used,(int)((sizeof(unsigned long long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1; | |
29 | ||
30 | /* get most significant digit of result */ | |
31 | res = DIGIT(a,i); | |
32 | ||
33 | #if DIGIT_BIT < 64 | |
34 | while (--i >= 0) { | |
35 | res = (res << DIGIT_BIT) | DIGIT(a,i); | |
36 | } | |
37 | #endif | |
38 | return res; | |
39 | } | |
40 | #endif |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_IMPORT_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* based on gmp's mpz_import. | |
18 | * see http://gmplib.org/manual/Integer-Import-and-Export.html | |
19 | */ | |
20 | int mp_import(mp_int* rop, size_t count, int order, size_t size, | |
21 | int endian, size_t nails, const void* op) { | |
22 | int result; | |
23 | size_t odd_nails, nail_bytes, i, j; | |
24 | unsigned char odd_nail_mask; | |
25 | ||
26 | mp_zero(rop); | |
27 | ||
28 | if (endian == 0) { | |
29 | union { | |
30 | unsigned int i; | |
31 | char c[4]; | |
32 | } lint = {0x01020304}; | |
33 | ||
34 | endian = (lint.c[0] == 4 ? -1 : 1); | |
35 | } | |
36 | ||
37 | odd_nails = (nails % 8); | |
38 | odd_nail_mask = 0xff; | |
39 | for (i = 0; i < odd_nails; ++i) { | |
40 | odd_nail_mask ^= (1 << (7 - i)); | |
41 | } | |
42 | nail_bytes = nails / 8; | |
43 | ||
44 | for (i = 0; i < count; ++i) { | |
45 | for (j = 0; j < size - nail_bytes; ++j) { | |
46 | unsigned char byte = *( | |
47 | (unsigned char*)op + | |
48 | (order == 1 ? i : count - 1 - i) * size + | |
49 | (endian == 1 ? j + nail_bytes : size - 1 - j - nail_bytes) | |
50 | ); | |
51 | ||
52 | if ( | |
53 | (result = mp_mul_2d(rop, (j == 0 ? 8 - odd_nails : 8), rop)) != MP_OKAY) { | |
54 | return result; | |
55 | } | |
56 | ||
57 | rop->dp[0] |= (j == 0 ? (byte & odd_nail_mask) : byte); | |
58 | rop->used += 1; | |
59 | } | |
60 | } | |
61 | ||
62 | mp_clamp(rop); | |
63 | ||
64 | return MP_OKAY; | |
65 | } | |
66 | ||
67 | #endif | |
68 | ||
69 | /* $Source$ */ | |
70 | /* $Revision$ */ | |
71 | /* $Date$ */ |
19 | 19 | { |
20 | 20 | int res; |
21 | 21 | |
22 | if ((res = mp_init (a)) != MP_OKAY) { | |
22 | if ((res = mp_init_size (a, b->used)) != MP_OKAY) { | |
23 | 23 | return res; |
24 | 24 | } |
25 | 25 | return mp_copy (b, a); |
47 | 47 | #endif |
48 | 48 | |
49 | 49 | /* rho = -1/m mod b */ |
50 | *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; | |
50 | *rho = (mp_digit)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK; | |
51 | 51 | |
52 | 52 | return MP_OKAY; |
53 | 53 | } |
14 | 14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
15 | 15 | */ |
16 | 16 | |
17 | /* find the n'th root of an integer | |
18 | * | |
19 | * Result found such that (c)**b <= a and (c+1)**b > a | |
20 | * | |
21 | * This algorithm uses Newton's approximation | |
22 | * x[i+1] = x[i] - f(x[i])/f'(x[i]) | |
23 | * which will find the root in log(N) time where | |
24 | * each step involves a fair bit. This is not meant to | |
25 | * find huge roots [square and cube, etc]. | |
17 | /* wrapper function for mp_n_root_ex() | |
18 | * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a | |
26 | 19 | */ |
27 | 20 | int mp_n_root (mp_int * a, mp_digit b, mp_int * c) |
28 | 21 | { |
29 | mp_int t1, t2, t3; | |
30 | int res, neg; | |
22 | return mp_n_root_ex(a, b, c, 0); | |
23 | } | |
31 | 24 | |
32 | /* input must be positive if b is even */ | |
33 | if ((b & 1) == 0 && a->sign == MP_NEG) { | |
34 | return MP_VAL; | |
35 | } | |
36 | ||
37 | if ((res = mp_init (&t1)) != MP_OKAY) { | |
38 | return res; | |
39 | } | |
40 | ||
41 | if ((res = mp_init (&t2)) != MP_OKAY) { | |
42 | goto LBL_T1; | |
43 | } | |
44 | ||
45 | if ((res = mp_init (&t3)) != MP_OKAY) { | |
46 | goto LBL_T2; | |
47 | } | |
48 | ||
49 | /* if a is negative fudge the sign but keep track */ | |
50 | neg = a->sign; | |
51 | a->sign = MP_ZPOS; | |
52 | ||
53 | /* t2 = 2 */ | |
54 | mp_set (&t2, 2); | |
55 | ||
56 | do { | |
57 | /* t1 = t2 */ | |
58 | if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { | |
59 | goto LBL_T3; | |
60 | } | |
61 | ||
62 | /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ | |
63 | ||
64 | /* t3 = t1**(b-1) */ | |
65 | if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) { | |
66 | goto LBL_T3; | |
67 | } | |
68 | ||
69 | /* numerator */ | |
70 | /* t2 = t1**b */ | |
71 | if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { | |
72 | goto LBL_T3; | |
73 | } | |
74 | ||
75 | /* t2 = t1**b - a */ | |
76 | if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { | |
77 | goto LBL_T3; | |
78 | } | |
79 | ||
80 | /* denominator */ | |
81 | /* t3 = t1**(b-1) * b */ | |
82 | if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { | |
83 | goto LBL_T3; | |
84 | } | |
85 | ||
86 | /* t3 = (t1**b - a)/(b * t1**(b-1)) */ | |
87 | if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { | |
88 | goto LBL_T3; | |
89 | } | |
90 | ||
91 | if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { | |
92 | goto LBL_T3; | |
93 | } | |
94 | } while (mp_cmp (&t1, &t2) != MP_EQ); | |
95 | ||
96 | /* result can be off by a few so check */ | |
97 | for (;;) { | |
98 | if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) { | |
99 | goto LBL_T3; | |
100 | } | |
101 | ||
102 | if (mp_cmp (&t2, a) == MP_GT) { | |
103 | if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { | |
104 | goto LBL_T3; | |
105 | } | |
106 | } else { | |
107 | break; | |
108 | } | |
109 | } | |
110 | ||
111 | /* reset the sign of a first */ | |
112 | a->sign = neg; | |
113 | ||
114 | /* set the result */ | |
115 | mp_exch (&t1, c); | |
116 | ||
117 | /* set the sign of the result */ | |
118 | c->sign = neg; | |
119 | ||
120 | res = MP_OKAY; | |
121 | ||
122 | LBL_T3:mp_clear (&t3); | |
123 | LBL_T2:mp_clear (&t2); | |
124 | LBL_T1:mp_clear (&t1); | |
125 | return res; | |
126 | } | |
127 | 25 | #endif |
128 | 26 | |
129 | 27 | /* $Source$ */ |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_N_ROOT_EX_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* find the n'th root of an integer | |
18 | * | |
19 | * Result found such that (c)**b <= a and (c+1)**b > a | |
20 | * | |
21 | * This algorithm uses Newton's approximation | |
22 | * x[i+1] = x[i] - f(x[i])/f'(x[i]) | |
23 | * which will find the root in log(N) time where | |
24 | * each step involves a fair bit. This is not meant to | |
25 | * find huge roots [square and cube, etc]. | |
26 | */ | |
27 | int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast) | |
28 | { | |
29 | mp_int t1, t2, t3; | |
30 | int res, neg; | |
31 | ||
32 | /* input must be positive if b is even */ | |
33 | if ((b & 1) == 0 && a->sign == MP_NEG) { | |
34 | return MP_VAL; | |
35 | } | |
36 | ||
37 | if ((res = mp_init (&t1)) != MP_OKAY) { | |
38 | return res; | |
39 | } | |
40 | ||
41 | if ((res = mp_init (&t2)) != MP_OKAY) { | |
42 | goto LBL_T1; | |
43 | } | |
44 | ||
45 | if ((res = mp_init (&t3)) != MP_OKAY) { | |
46 | goto LBL_T2; | |
47 | } | |
48 | ||
49 | /* if a is negative fudge the sign but keep track */ | |
50 | neg = a->sign; | |
51 | a->sign = MP_ZPOS; | |
52 | ||
53 | /* t2 = 2 */ | |
54 | mp_set (&t2, 2); | |
55 | ||
56 | do { | |
57 | /* t1 = t2 */ | |
58 | if ((res = mp_copy (&t2, &t1)) != MP_OKAY) { | |
59 | goto LBL_T3; | |
60 | } | |
61 | ||
62 | /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ | |
63 | ||
64 | /* t3 = t1**(b-1) */ | |
65 | if ((res = mp_expt_d_ex (&t1, b - 1, &t3, fast)) != MP_OKAY) { | |
66 | goto LBL_T3; | |
67 | } | |
68 | ||
69 | /* numerator */ | |
70 | /* t2 = t1**b */ | |
71 | if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) { | |
72 | goto LBL_T3; | |
73 | } | |
74 | ||
75 | /* t2 = t1**b - a */ | |
76 | if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) { | |
77 | goto LBL_T3; | |
78 | } | |
79 | ||
80 | /* denominator */ | |
81 | /* t3 = t1**(b-1) * b */ | |
82 | if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) { | |
83 | goto LBL_T3; | |
84 | } | |
85 | ||
86 | /* t3 = (t1**b - a)/(b * t1**(b-1)) */ | |
87 | if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) { | |
88 | goto LBL_T3; | |
89 | } | |
90 | ||
91 | if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) { | |
92 | goto LBL_T3; | |
93 | } | |
94 | } while (mp_cmp (&t1, &t2) != MP_EQ); | |
95 | ||
96 | /* result can be off by a few so check */ | |
97 | for (;;) { | |
98 | if ((res = mp_expt_d_ex (&t1, b, &t2, fast)) != MP_OKAY) { | |
99 | goto LBL_T3; | |
100 | } | |
101 | ||
102 | if (mp_cmp (&t2, a) == MP_GT) { | |
103 | if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) { | |
104 | goto LBL_T3; | |
105 | } | |
106 | } else { | |
107 | break; | |
108 | } | |
109 | } | |
110 | ||
111 | /* reset the sign of a first */ | |
112 | a->sign = neg; | |
113 | ||
114 | /* set the result */ | |
115 | mp_exch (&t1, c); | |
116 | ||
117 | /* set the sign of the result */ | |
118 | c->sign = neg; | |
119 | ||
120 | res = MP_OKAY; | |
121 | ||
122 | LBL_T3:mp_clear (&t3); | |
123 | LBL_T2:mp_clear (&t2); | |
124 | LBL_T1:mp_clear (&t1); | |
125 | return res; | |
126 | } | |
127 | #endif | |
128 | ||
129 | /* $Source$ */ | |
130 | /* $Revision$ */ | |
131 | /* $Date$ */ |
4 | 4 | * LibTomMath is a library that provides multiple-precision |
5 | 5 | * integer arithmetic as well as number theoretic functionality. |
6 | 6 | * |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
7 | 11 | * The library is free for all purposes without any express |
8 | 12 | * guarantee it works. |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
9 | 15 | */ |
10 | 16 | |
11 | /* ideas from Dana Jacobsen's | |
12 | * https://github.com/danaj/Math-Prime-Util-GMP | |
13 | */ | |
17 | /* performs a variable number of rounds of Miller-Rabin | |
18 | * | |
19 | * Probability of error after t rounds is no more than | |
14 | 20 | |
15 | int mp_prime_is_prime_ex(mp_int * a, int t, int *result, ltm_prime_callback cb, void *dat) | |
21 | * | |
22 | * Sets result to 1 if probably prime, 0 otherwise | |
23 | */ | |
24 | int mp_prime_is_prime (mp_int * a, int t, int *result) | |
16 | 25 | { |
17 | mp_int b; | |
18 | int ix, err, res, abits, atests; | |
19 | mp_digit maxp, r; | |
26 | mp_int b; | |
27 | int ix, err, res; | |
20 | 28 | |
21 | maxp = ltm_prime_tab[PRIME_SIZE-1]; /* max. predefined prime number */ | |
22 | *result = MP_NO; /* default */ | |
29 | /* default to no */ | |
30 | *result = MP_NO; | |
23 | 31 | |
24 | /* special case: a <= max_predef_prime */ | |
25 | if (mp_cmp_d(a, maxp+1) == MP_LT) { | |
26 | /* test if a is equal to any of the first N primes */ | |
27 | for (ix = 0; ix < PRIME_SIZE; ix++) { | |
28 | if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { *result = MP_YES; return MP_OKAY; } | |
29 | } | |
30 | /* here it must be composite */ | |
32 | /* valid value of t? */ | |
33 | if (t <= 0 || t > PRIME_SIZE) { | |
34 | return MP_VAL; | |
35 | } | |
36 | ||
37 | /* is the input equal to one of the primes in the table? */ | |
38 | for (ix = 0; ix < PRIME_SIZE; ix++) { | |
39 | if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { | |
40 | *result = 1; | |
41 | return MP_OKAY; | |
42 | } | |
43 | } | |
44 | ||
45 | /* first perform trial division */ | |
46 | if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) { | |
47 | return err; | |
48 | } | |
49 | ||
50 | /* return if it was trivially divisible */ | |
51 | if (res == MP_YES) { | |
31 | 52 | return MP_OKAY; |
32 | 53 | } |
33 | 54 | |
34 | /* go through all known predefined primes - BEWARE: max_predef_prime should never go over 65536 */ | |
35 | for (ix = 0; ix < PRIME_SIZE; ix++) { | |
36 | /* return YES if A < p[ix]*p[ix] */ | |
37 | if (mp_cmp_d(a, ltm_prime_tab[ix]*ltm_prime_tab[ix]) == MP_LT) { *result = MP_YES; return MP_OKAY; } | |
38 | /* return NO if A % p[ix] == 0 */ | |
39 | if ((err = mp_mod_d(a, ltm_prime_tab[ix], &r)) != MP_OKAY) { return err; } | |
40 | if (r == 0) { return MP_OKAY; } | |
55 | /* now perform the miller-rabin rounds */ | |
56 | if ((err = mp_init (&b)) != MP_OKAY) { | |
57 | return err; | |
41 | 58 | } |
42 | 59 | |
43 | /* init b */ | |
44 | if ((err = mp_init(&b)) != MP_OKAY) { return err; } | |
60 | for (ix = 0; ix < t; ix++) { | |
61 | /* set the prime */ | |
62 | mp_set (&b, ltm_prime_tab[ix]); | |
45 | 63 | |
46 | /* Miller Rabin with base 2 */ | |
47 | mp_set(&b, 2); | |
48 | err = mp_prime_miller_rabin(a, &b, &res); | |
49 | if (err != MP_OKAY) { goto LBL_B; } | |
50 | if (res != MP_YES) { goto LBL_B; } | |
64 | if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) { | |
65 | goto LBL_B; | |
66 | } | |
51 | 67 | |
52 | /* Extra-Strong Lucas test */ | |
53 | err = mp_prime_lucas(a, 2, &res); | |
54 | if (err != MP_OKAY) { goto LBL_B; } | |
55 | if (res != MP_YES) { goto LBL_B; } | |
56 | ||
57 | /* BPSW is deterministic below 2^64 */ | |
58 | if (mp_count_bits(a) <= 64) { *result = MP_YES; return MP_OKAY; } | |
59 | ||
60 | if (cb && dat) { | |
61 | /* Miller Rabin with N random bases */ | |
62 | if (t > 0) { | |
63 | atests = t; | |
64 | } | |
65 | else { | |
66 | abits = mp_count_bits(a); | |
67 | if (abits < 80) atests = 5; | |
68 | else if (abits < 105) atests = 4; | |
69 | else if (abits < 160) atests = 3; | |
70 | else if (abits < 413) atests = 2; | |
71 | else atests = 1; | |
72 | } | |
73 | err = mp_prime_miller_rabin_random(a, atests, &res, cb, dat); | |
74 | if (err != MP_OKAY) { goto LBL_B; } | |
75 | if (res != MP_YES) { goto LBL_B; } | |
76 | } | |
77 | else { | |
78 | /* Miller Rabin with first N primes */ | |
79 | if (t > 0) { | |
80 | atests = t; | |
81 | } | |
82 | else { | |
83 | abits = mp_count_bits(a); | |
84 | atests = mp_prime_rabin_miller_trials(abits); | |
85 | } | |
86 | for (ix = 1; ix < atests; ix++) { /* skip ltm_prime_tab[0] (==2) as it was already tested) */ | |
87 | mp_set(&b, ltm_prime_tab[ix]); | |
88 | if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { goto LBL_B; } | |
89 | if (res == MP_NO) { goto LBL_B; } | |
68 | if (res == MP_NO) { | |
69 | goto LBL_B; | |
90 | 70 | } |
91 | 71 | } |
92 | 72 | |
93 | /* passed all tests */ | |
73 | /* passed the test */ | |
94 | 74 | *result = MP_YES; |
95 | err = MP_OKAY; | |
96 | ||
97 | LBL_B: | |
98 | mp_clear(&b); | |
75 | LBL_B:mp_clear (&b); | |
99 | 76 | return err; |
100 | } | |
101 | ||
102 | int mp_prime_is_prime(mp_int * a, int t, int *result) | |
103 | { | |
104 | return mp_prime_is_prime_ex(a, t, result, NULL, NULL); | |
105 | 77 | } |
106 | 78 | #endif |
107 | 79 |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_PRIME_LUCAS_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library is free for all purposes without any express | |
8 | * guarantee it works. | |
9 | */ | |
10 | ||
11 | int mp_prime_lucas (mp_int * a, int level, int *result) | |
12 | { | |
13 | /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ | |
14 | /* fprintf(stderr, "XXX-DEBUG: mp_prime_lucas begin bits=%d, level=%d\n", mp_count_bits(a), level); */ | |
15 | ||
16 | *result = MP_YES; /* XXX let's always pass */ | |
17 | return MP_OKAY; | |
18 | } | |
19 | #endif | |
20 | ||
21 | /* $Source$ */ | |
22 | /* $Revision$ */ | |
23 | /* $Date$ */ |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_PRIME_MILLER_RABIN_RANDOM_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library is free for all purposes without any express | |
8 | * guarantee it works. | |
9 | */ | |
10 | ||
11 | int mp_prime_miller_rabin_random(mp_int *a, int t, int *result, ltm_prime_callback cb, void *dat) | |
12 | { | |
13 | mp_int b, c; | |
14 | int res, err, bsize, trials; | |
15 | unsigned char *tmp; | |
16 | ||
17 | fprintf(stderr, "XXX-DEBUG: mp_prime_miller_rabin_random begin bits=%d, t=%d\n", mp_count_bits(a), t); /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ | |
18 | ||
19 | /* default */ | |
20 | *result = MP_NO; | |
21 | ||
22 | /* tests should be >0 */ | |
23 | if (t <= 0) { return MP_VAL; } | |
24 | ||
25 | /* calculate the byte size */ | |
26 | bsize = mp_unsigned_bin_size(a); | |
27 | ||
28 | /* we need a buffer of bsize bytes */ | |
29 | tmp = OPT_CAST(unsigned char) XMALLOC(bsize); | |
30 | if (tmp == NULL) { return MP_MEM; } | |
31 | ||
32 | /* initialize b */ | |
33 | if ((err = mp_init_multi(&b, &c, NULL)) != MP_OKAY) { return err; } | |
34 | ||
35 | trials = 0; | |
36 | do { | |
37 | /* read the bytes */ | |
38 | if (cb(tmp, bsize, dat) != bsize) { err = MP_VAL; goto LBL_BC; } | |
39 | ||
40 | /* read it in */ | |
41 | if ((err = mp_read_unsigned_bin(&b, tmp, bsize)) != MP_OKAY) { goto LBL_BC; } | |
42 | ||
43 | /* test if b is in [2, a-2] */ | |
44 | mp_add_d(&b, 1, &c); /* c = b + 1 */ | |
45 | if (mp_cmp_d(&c, 2) != MP_GT && mp_cmp(&c, a) != MP_LT) continue; | |
46 | ||
47 | /* do Miller Rabin */ | |
48 | if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { goto LBL_BC; } | |
49 | if (res == MP_NO) { err = MP_OKAY; goto LBL_BC; } | |
50 | trials++; | |
51 | } while (++trials < t); | |
52 | ||
53 | /* passed the test */ | |
54 | *result = MP_YES; | |
55 | err = MP_OKAY; | |
56 | ||
57 | LBL_BC: | |
58 | mp_clear_multi(&b, &c, NULL); | |
59 | return err; | |
60 | } | |
61 | #endif | |
62 | ||
63 | /* $Source$ */ | |
64 | /* $Revision$ */ | |
65 | /* $Date$ */ |
21 | 21 | */ |
22 | 22 | int mp_prime_next_prime(mp_int *a, int t, int bbs_style) |
23 | 23 | { |
24 | int err, res, x, y; | |
24 | int err, res = MP_NO, x, y; | |
25 | 25 | mp_digit res_tab[PRIME_SIZE], step, kstep; |
26 | 26 | mp_int b; |
27 | 27 |
28 | 28 | |
29 | 29 | /* first place a random non-zero digit */ |
30 | 30 | do { |
31 | d = ((mp_digit) abs (rand ())) & MP_MASK; | |
31 | d = ((mp_digit) abs (MP_GEN_RANDOM())) & MP_MASK; | |
32 | 32 | } while (d == 0); |
33 | 33 | |
34 | 34 | if ((res = mp_add_d (a, d, a)) != MP_OKAY) { |
40 | 40 | return res; |
41 | 41 | } |
42 | 42 | |
43 | if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) { | |
43 | if ((res = mp_add_d (a, ((mp_digit) abs (MP_GEN_RANDOM())), a)) != MP_OKAY) { | |
44 | 44 | return res; |
45 | 45 | } |
46 | 46 | } |
14 | 14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org |
15 | 15 | */ |
16 | 16 | |
17 | /* reduces x mod m, assumes 0 < x < m**2, mu is | |
17 | /* reduces x mod m, assumes 0 < x < m**2, mu is | |
18 | 18 | * precomputed via mp_reduce_setup. |
19 | 19 | * From HAC pp.604 Algorithm 14.42 |
20 | 20 | */ |
29 | 29 | } |
30 | 30 | |
31 | 31 | /* q1 = x / b**(k-1) */ |
32 | mp_rshd (&q, um - 1); | |
32 | mp_rshd (&q, um - 1); | |
33 | 33 | |
34 | 34 | /* according to HAC this optimization is ok */ |
35 | if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { | |
35 | if (((mp_digit) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) { | |
36 | 36 | if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) { |
37 | 37 | goto CLEANUP; |
38 | 38 | } |
45 | 45 | if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) { |
46 | 46 | goto CLEANUP; |
47 | 47 | } |
48 | #else | |
49 | { | |
48 | #else | |
49 | { | |
50 | 50 | res = MP_VAL; |
51 | 51 | goto CLEANUP; |
52 | 52 | } |
54 | 54 | } |
55 | 55 | |
56 | 56 | /* q3 = q2 / b**(k+1) */ |
57 | mp_rshd (&q, um + 1); | |
57 | mp_rshd (&q, um + 1); | |
58 | 58 | |
59 | 59 | /* x = x mod b**(k+1), quick (no division) */ |
60 | 60 | if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { |
86 | 86 | goto CLEANUP; |
87 | 87 | } |
88 | 88 | } |
89 | ||
89 | ||
90 | 90 | CLEANUP: |
91 | 91 | mp_clear (&q); |
92 | 92 |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_SET_LONG_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* set a platform dependent unsigned long int */ | |
18 | MP_SET_XLONG(mp_set_long, unsigned long) | |
19 | #endif | |
20 | ||
21 | /* $Source$ */ | |
22 | /* $Revision$ */ | |
23 | /* $Date$ */ |
0 | #include <tommath.h> | |
1 | #ifdef BN_MP_SET_LONG_LONG_C | |
2 | /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
3 | * | |
4 | * LibTomMath is a library that provides multiple-precision | |
5 | * integer arithmetic as well as number theoretic functionality. | |
6 | * | |
7 | * The library was designed directly after the MPI library by | |
8 | * Michael Fromberger but has been written from scratch with | |
9 | * additional optimizations in place. | |
10 | * | |
11 | * The library is free for all purposes without any express | |
12 | * guarantee it works. | |
13 | * | |
14 | * Tom St Denis, tomstdenis@gmail.com, http://libtom.org | |
15 | */ | |
16 | ||
17 | /* set a platform dependent unsigned long long int */ | |
18 | MP_SET_XLONG(mp_set_long_long, unsigned long long) | |
19 | #endif | |
20 | ||
21 | /* $Source$ */ | |
22 | /* $Revision$ */ | |
23 | /* $Date$ */ |
45 | 45 | |
46 | 46 | |
47 | 47 | /* detect 64-bit mode if possible */ |
48 | #if defined(__x86_64__) | |
49 | #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) | |
48 | #if defined(__x86_64__) | |
49 | #if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) | |
50 | 50 | #define MP_64BIT |
51 | 51 | #endif |
52 | 52 | #endif |
62 | 62 | #ifdef MP_8BIT |
63 | 63 | typedef unsigned char mp_digit; |
64 | 64 | typedef unsigned short mp_word; |
65 | #define MP_SIZEOF_MP_DIGIT 1 | |
66 | #ifdef DIGIT_BIT | |
67 | #error You must not define DIGIT_BIT when using MP_8BIT | |
68 | #endif | |
65 | 69 | #elif defined(MP_16BIT) |
66 | 70 | typedef unsigned short mp_digit; |
67 | typedef unsigned long mp_word; | |
71 | typedef unsigned int mp_word; | |
72 | #define MP_SIZEOF_MP_DIGIT 2 | |
73 | #ifdef DIGIT_BIT | |
74 | #error You must not define DIGIT_BIT when using MP_16BIT | |
75 | #endif | |
68 | 76 | #elif defined(MP_64BIT) |
69 | 77 | /* for GCC only on supported platforms */ |
70 | 78 | #ifndef CRYPT |
72 | 80 | typedef signed long long long64; |
73 | 81 | #endif |
74 | 82 | |
75 | #ifdef __WIN64 | |
76 | typedef unsigned long mp_digit; | |
77 | typedef unsigned long long mp_word; | |
78 | #define DIGIT_BIT 28 | |
79 | #define MP_28BIT | |
80 | #else | |
81 | typedef unsigned long mp_digit; | |
83 | typedef unsigned long long mp_digit; | |
82 | 84 | typedef unsigned long mp_word __attribute__ ((mode(TI))); |
85 | ||
83 | 86 | #define DIGIT_BIT 60 |
84 | #endif | |
85 | ||
86 | ||
87 | 87 | #else |
88 | 88 | /* this is the default case, 28-bit digits */ |
89 | ||
89 | ||
90 | 90 | /* this is to make porting into LibTomCrypt easier :-) */ |
91 | 91 | #ifndef CRYPT |
92 | #if defined(_MSC_VER) || defined(__BORLANDC__) | |
92 | #if defined(_MSC_VER) || defined(__BORLANDC__) | |
93 | 93 | typedef unsigned __int64 ulong64; |
94 | 94 | typedef signed __int64 long64; |
95 | 95 | #else |
101 | 101 | typedef unsigned long mp_digit; |
102 | 102 | typedef ulong64 mp_word; |
103 | 103 | |
104 | #ifdef MP_31BIT | |
104 | #ifdef MP_31BIT | |
105 | 105 | /* this is an extension that uses 31-bit digits */ |
106 | 106 | #define DIGIT_BIT 31 |
107 | 107 | #else |
108 | 108 | /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ |
109 | 109 | #define DIGIT_BIT 28 |
110 | 110 | #define MP_28BIT |
111 | #endif | |
111 | #endif | |
112 | 112 | #endif |
113 | 113 | |
114 | 114 | /* define heap macros */ |
115 | 115 | #ifndef CRYPT |
116 | 116 | /* default to libc stuff */ |
117 | #ifndef XMALLOC | |
117 | #ifndef XMALLOC | |
118 | 118 | #define XMALLOC malloc |
119 | 119 | #define XFREE free |
120 | 120 | #define XREALLOC realloc |
131 | 131 | |
132 | 132 | /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ |
133 | 133 | #ifndef DIGIT_BIT |
134 | #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ | |
134 | #define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ | |
135 | typedef unsigned long mp_min_u32; | |
136 | #else | |
137 | typedef mp_digit mp_min_u32; | |
138 | #endif | |
139 | ||
140 | /* platforms that can use a better rand function */ | |
141 | #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) | |
142 | #define MP_USE_ALT_RAND 1 | |
143 | #endif | |
144 | ||
145 | /* use arc4random on platforms that support it */ | |
146 | #ifdef MP_USE_ALT_RAND | |
147 | #define MP_GEN_RANDOM() arc4random() | |
148 | #else | |
149 | #define MP_GEN_RANDOM() rand() | |
135 | 150 | #endif |
136 | 151 | |
137 | 152 | #define MP_DIGIT_BIT DIGIT_BIT |
176 | 191 | #define MP_PREC 32 /* default digits of precision */ |
177 | 192 | #else |
178 | 193 | #define MP_PREC 8 /* default digits of precision */ |
179 | #endif | |
194 | #endif | |
180 | 195 | #endif |
181 | 196 | |
182 | 197 | /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ |
228 | 243 | #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) |
229 | 244 | #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) |
230 | 245 | #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) |
246 | #define mp_isneg(a) (((a)->sign) ? MP_YES : MP_NO) | |
231 | 247 | |
232 | 248 | /* set to zero */ |
233 | 249 | void mp_zero(mp_int *a); |
238 | 254 | /* set a 32-bit const */ |
239 | 255 | int mp_set_int(mp_int *a, unsigned long b); |
240 | 256 | |
257 | /* set a platform dependent unsigned long value */ | |
258 | int mp_set_long(mp_int *a, unsigned long b); | |
259 | ||
260 | /* set a platform dependent unsigned long long value */ | |
261 | int mp_set_long_long(mp_int *a, unsigned long long b); | |
262 | ||
241 | 263 | /* get a 32-bit value */ |
242 | 264 | unsigned long mp_get_int(mp_int * a); |
243 | 265 | |
266 | /* get a platform dependent unsigned long value */ | |
267 | unsigned long mp_get_long(mp_int * a); | |
268 | ||
269 | /* get a platform dependent unsigned long long value */ | |
270 | unsigned long long mp_get_long_long(mp_int * a); | |
271 | ||
244 | 272 | /* initialize and set a digit */ |
245 | 273 | int mp_init_set (mp_int * a, mp_digit b); |
246 | 274 | |
256 | 284 | /* trim unused digits */ |
257 | 285 | void mp_clamp(mp_int *a); |
258 | 286 | |
287 | /* import binary data */ | |
288 | int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op); | |
289 | ||
290 | /* export binary data */ | |
291 | int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op); | |
292 | ||
259 | 293 | /* ---> digit manipulation <--- */ |
260 | 294 | |
261 | 295 | /* right shift by "b" digits */ |
276 | 310 | /* b = a*2 */ |
277 | 311 | int mp_mul_2(mp_int *a, mp_int *b); |
278 | 312 | |
279 | /* c = a mod 2**d */ | |
313 | /* c = a mod 2**b */ | |
280 | 314 | int mp_mod_2d(mp_int *a, int b, mp_int *c); |
281 | 315 | |
282 | 316 | /* computes a = 2**b */ |
354 | 388 | |
355 | 389 | /* c = a**b */ |
356 | 390 | int mp_expt_d(mp_int *a, mp_digit b, mp_int *c); |
391 | int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast); | |
357 | 392 | |
358 | 393 | /* c = a mod b, 0 <= c < b */ |
359 | 394 | int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c); |
389 | 424 | * returns error if a < 0 and b is even |
390 | 425 | */ |
391 | 426 | int mp_n_root(mp_int *a, mp_digit b, mp_int *c); |
427 | int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast); | |
392 | 428 | |
393 | 429 | /* special sqrt algo */ |
394 | 430 | int mp_sqrt(mp_int *arg, mp_int *ret); |
473 | 509 | */ |
474 | 510 | int mp_prime_fermat(mp_int *a, mp_int *b, int *result); |
475 | 511 | |
476 | /* performs Lucas test of "a". | |
477 | * Sets result to 0 if composite or 1 if probable prime | |
478 | */ | |
479 | int mp_prime_lucas (mp_int * a, int level, int *result); | |
480 | ||
481 | 512 | /* performs one Miller-Rabin test of "a" using base "b". |
482 | 513 | * Sets result to 0 if composite or 1 if probable prime |
483 | 514 | */ |
484 | 515 | int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result); |
485 | 516 | |
486 | /* performs one Miller-Rabin test of "a" using base "t" | |
487 | * random bases chosen from [2, a-2]. | |
488 | * Sets result to 0 if composite or 1 if probable prime | |
489 | */ | |
490 | int mp_prime_miller_rabin_random(mp_int *a, int t, int *result, ltm_prime_callback cb, void *dat); | |
491 | ||
492 | 517 | /* This gives [for a given bit size] the number of trials required |
493 | * such that Miller-Rabin gives a prob of failure lower than 2^-96 | |
518 | * such that Miller-Rabin gives a prob of failure lower than 2^-96 | |
494 | 519 | */ |
495 | 520 | int mp_prime_rabin_miller_trials(int size); |
496 | 521 | |
503 | 528 | */ |
504 | 529 | int mp_prime_is_prime(mp_int *a, int t, int *result); |
505 | 530 | |
506 | /* performs extended primality tests | |
507 | * Miller-Rabin (t random or fixed bases) + Lucas | |
508 | * | |
509 | * Sets result to 1 if probably prime, 0 otherwise | |
510 | */ | |
511 | int mp_prime_is_prime_ex(mp_int *a, int t, int *result, ltm_prime_callback cb, void *dat); | |
512 | ||
513 | 531 | /* finds the next prime after the number "a" using "t" trials |
514 | 532 | * of Miller-Rabin. |
515 | 533 | * |
518 | 536 | int mp_prime_next_prime(mp_int *a, int t, int bbs_style); |
519 | 537 | |
520 | 538 | /* makes a truly random prime of a given size (bytes), |
521 | * call with bbs = 1 if you want it to be congruent to 3 mod 4 | |
539 | * call with bbs = 1 if you want it to be congruent to 3 mod 4 | |
522 | 540 | * |
523 | 541 | * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can |
524 | 542 | * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself |
531 | 549 | /* makes a truly random prime of a given size (bits), |
532 | 550 | * |
533 | 551 | * Flags are as follows: |
534 | * | |
552 | * | |
535 | 553 | * LTM_PRIME_BBS - make prime congruent to 3 mod 4 |
536 | 554 | * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) |
537 | 555 | * LTM_PRIME_2MSB_ON - make the 2nd highest bit one |
599 | 617 | |
600 | 618 | extern const char *mp_s_rmap; |
601 | 619 | |
620 | /* Fancy macro to set an MPI from another type. | |
621 | * There are several things assumed: | |
622 | * x is the counter and unsigned | |
623 | * a is the pointer to the MPI | |
624 | * b is the original value that should be set in the MPI. | |
625 | */ | |
626 | #define MP_SET_XLONG(func_name, type) \ | |
627 | int func_name (mp_int * a, type b) \ | |
628 | { \ | |
629 | unsigned int x; \ | |
630 | int res; \ | |
631 | \ | |
632 | mp_zero (a); \ | |
633 | \ | |
634 | /* set four bits at a time */ \ | |
635 | for (x = 0; x < sizeof(type) * 2; x++) { \ | |
636 | /* shift the number up four bits */ \ | |
637 | if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \ | |
638 | return res; \ | |
639 | } \ | |
640 | \ | |
641 | /* OR in the top four bits of the source */ \ | |
642 | a->dp[0] |= (b >> ((sizeof(type)) * 8 - 4)) & 15; \ | |
643 | \ | |
644 | /* shift the source up to the next four bits */ \ | |
645 | b <<= 4; \ | |
646 | \ | |
647 | /* ensure that digits are not clamped off */ \ | |
648 | a->used += 1; \ | |
649 | } \ | |
650 | mp_clamp (a); \ | |
651 | return MP_OKAY; \ | |
652 | } | |
653 | ||
602 | 654 | #ifdef __cplusplus |
603 | 655 | } |
604 | 656 | #endif |
37 | 37 | #define BN_MP_DR_REDUCE_C |
38 | 38 | #define BN_MP_DR_SETUP_C |
39 | 39 | #define BN_MP_EXCH_C |
40 | #define BN_MP_EXPORT_C | |
40 | 41 | #define BN_MP_EXPT_D_C |
42 | #define BN_MP_EXPT_D_EX_C | |
41 | 43 | #define BN_MP_EXPTMOD_C |
42 | 44 | #define BN_MP_EXPTMOD_FAST_C |
43 | 45 | #define BN_MP_EXTEUCLID_C |
45 | 47 | #define BN_MP_FWRITE_C |
46 | 48 | #define BN_MP_GCD_C |
47 | 49 | #define BN_MP_GET_INT_C |
50 | #define BN_MP_GET_LONG_C | |
51 | #define BN_MP_GET_LONG_LONG_C | |
48 | 52 | #define BN_MP_GROW_C |
53 | #define BN_MP_IMPORT_C | |
49 | 54 | #define BN_MP_INIT_C |
50 | 55 | #define BN_MP_INIT_COPY_C |
51 | 56 | #define BN_MP_INIT_MULTI_C |
72 | 77 | #define BN_MP_MUL_D_C |
73 | 78 | #define BN_MP_MULMOD_C |
74 | 79 | #define BN_MP_N_ROOT_C |
80 | #define BN_MP_N_ROOT_EX_C | |
75 | 81 | #define BN_MP_NEG_C |
76 | 82 | #define BN_MP_OR_C |
77 | 83 | #define BN_MP_PRIME_FERMAT_C |
78 | 84 | #define BN_MP_PRIME_IS_DIVISIBLE_C |
79 | 85 | #define BN_MP_PRIME_IS_PRIME_C |
80 | 86 | #define BN_MP_PRIME_MILLER_RABIN_C |
81 | #define BN_MP_PRIME_MILLER_RABIN_RANDOM_C | |
82 | #define BN_MP_PRIME_LUCAS_C | |
83 | 87 | #define BN_MP_PRIME_NEXT_PRIME_C |
84 | 88 | #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C |
85 | 89 | #define BN_MP_PRIME_RANDOM_EX_C |
100 | 104 | #define BN_MP_RSHD_C |
101 | 105 | #define BN_MP_SET_C |
102 | 106 | #define BN_MP_SET_INT_C |
107 | #define BN_MP_SET_LONG_C | |
108 | #define BN_MP_SET_LONG_LONG_C | |
103 | 109 | #define BN_MP_SHRINK_C |
104 | 110 | #define BN_MP_SIGNED_BIN_SIZE_C |
105 | 111 | #define BN_MP_SQR_C |
317 | 323 | #if defined(BN_MP_EXCH_C) |
318 | 324 | #endif |
319 | 325 | |
326 | #if defined(BN_MP_EXPORT_C) | |
327 | #define BN_MP_INIT_COPY_C | |
328 | #define BN_MP_COUNT_BITS_C | |
329 | #define BN_MP_DIV_2D_C | |
330 | #define BN_MP_CLEAR_C | |
331 | #endif | |
332 | ||
320 | 333 | #if defined(BN_MP_EXPT_D_C) |
321 | #define BN_MP_INIT_COPY_C | |
322 | #define BN_MP_SET_C | |
334 | #define BN_MP_EXPT_D_EX_C | |
335 | #endif | |
336 | ||
337 | #if defined(BN_MP_EXPT_D_EX_C) | |
338 | #define BN_MP_INIT_COPY_C | |
339 | #define BN_MP_SET_C | |
340 | #define BN_MP_MUL_C | |
341 | #define BN_MP_CLEAR_C | |
323 | 342 | #define BN_MP_SQR_C |
324 | #define BN_MP_CLEAR_C | |
325 | #define BN_MP_MUL_C | |
326 | 343 | #endif |
327 | 344 | |
328 | 345 | #if defined(BN_MP_EXPTMOD_C) |
389 | 406 | #if defined(BN_MP_GCD_C) |
390 | 407 | #define BN_MP_ISZERO_C |
391 | 408 | #define BN_MP_ABS_C |
392 | #define BN_MP_ZERO_C | |
393 | 409 | #define BN_MP_INIT_COPY_C |
394 | 410 | #define BN_MP_CNT_LSB_C |
395 | 411 | #define BN_MP_DIV_2D_C |
403 | 419 | #if defined(BN_MP_GET_INT_C) |
404 | 420 | #endif |
405 | 421 | |
422 | #if defined(BN_MP_GET_LONG_C) | |
423 | #endif | |
424 | ||
425 | #if defined(BN_MP_GET_LONG_LONG_C) | |
426 | #define BN_MP_GET_LONG_C | |
427 | #endif | |
428 | ||
406 | 429 | #if defined(BN_MP_GROW_C) |
407 | 430 | #endif |
408 | 431 | |
432 | #if defined(BN_MP_IMPORT_C) | |
433 | #define BN_MP_ZERO_C | |
434 | #define BN_MP_MUL_2D_C | |
435 | #define BN_MP_CLAMP_C | |
436 | #endif | |
437 | ||
409 | 438 | #if defined(BN_MP_INIT_C) |
410 | 439 | #endif |
411 | 440 | |
412 | 441 | #if defined(BN_MP_INIT_COPY_C) |
442 | #define BN_MP_INIT_SIZE_C | |
413 | 443 | #define BN_MP_COPY_C |
414 | 444 | #endif |
415 | 445 | |
483 | 513 | #define BN_MP_MUL_C |
484 | 514 | #define BN_MP_INIT_SIZE_C |
485 | 515 | #define BN_MP_CLAMP_C |
486 | #define BN_MP_SUB_C | |
516 | #define BN_S_MP_ADD_C | |
487 | 517 | #define BN_MP_ADD_C |
518 | #define BN_S_MP_SUB_C | |
488 | 519 | #define BN_MP_LSHD_C |
489 | 520 | #define BN_MP_CLEAR_C |
490 | 521 | #endif |
493 | 524 | #define BN_MP_INIT_SIZE_C |
494 | 525 | #define BN_MP_CLAMP_C |
495 | 526 | #define BN_MP_SQR_C |
496 | #define BN_MP_SUB_C | |
497 | 527 | #define BN_S_MP_ADD_C |
528 | #define BN_S_MP_SUB_C | |
498 | 529 | #define BN_MP_LSHD_C |
499 | 530 | #define BN_MP_ADD_C |
500 | 531 | #define BN_MP_CLEAR_C |
518 | 549 | #define BN_MP_INIT_C |
519 | 550 | #define BN_MP_DIV_C |
520 | 551 | #define BN_MP_CLEAR_C |
552 | #define BN_MP_ISZERO_C | |
553 | #define BN_MP_EXCH_C | |
521 | 554 | #define BN_MP_ADD_C |
522 | #define BN_MP_EXCH_C | |
523 | 555 | #endif |
524 | 556 | |
525 | 557 | #if defined(BN_MP_MOD_2D_C) |
585 | 617 | #endif |
586 | 618 | |
587 | 619 | #if defined(BN_MP_N_ROOT_C) |
588 | #define BN_MP_INIT_C | |
589 | #define BN_MP_SET_C | |
590 | #define BN_MP_COPY_C | |
591 | #define BN_MP_EXPT_D_C | |
620 | #define BN_MP_N_ROOT_EX_C | |
621 | #endif | |
622 | ||
623 | #if defined(BN_MP_N_ROOT_EX_C) | |
624 | #define BN_MP_INIT_C | |
625 | #define BN_MP_SET_C | |
626 | #define BN_MP_COPY_C | |
627 | #define BN_MP_EXPT_D_EX_C | |
592 | 628 | #define BN_MP_MUL_C |
593 | 629 | #define BN_MP_SUB_C |
594 | 630 | #define BN_MP_MUL_D_C |
669 | 705 | #endif |
670 | 706 | |
671 | 707 | #if defined(BN_MP_RADIX_SIZE_C) |
672 | #define BN_MP_COUNT_BITS_C | |
673 | #define BN_MP_INIT_COPY_C | |
674 | #define BN_MP_ISZERO_C | |
708 | #define BN_MP_ISZERO_C | |
709 | #define BN_MP_COUNT_BITS_C | |
710 | #define BN_MP_INIT_COPY_C | |
675 | 711 | #define BN_MP_DIV_D_C |
676 | 712 | #define BN_MP_CLEAR_C |
677 | 713 | #endif |
689 | 725 | #if defined(BN_MP_READ_RADIX_C) |
690 | 726 | #define BN_MP_ZERO_C |
691 | 727 | #define BN_MP_S_RMAP_C |
692 | #define BN_MP_RADIX_SMAP_C | |
693 | 728 | #define BN_MP_MUL_D_C |
694 | 729 | #define BN_MP_ADD_D_C |
695 | 730 | #define BN_MP_ISZERO_C |
788 | 823 | #define BN_MP_ZERO_C |
789 | 824 | #define BN_MP_MUL_2D_C |
790 | 825 | #define BN_MP_CLAMP_C |
826 | #endif | |
827 | ||
828 | #if defined(BN_MP_SET_LONG_C) | |
829 | #endif | |
830 | ||
831 | #if defined(BN_MP_SET_LONG_LONG_C) | |
791 | 832 | #endif |
792 | 833 | |
793 | 834 | #if defined(BN_MP_SHRINK_C) |
1007 | 1048 | #else |
1008 | 1049 | #define LTM_LAST |
1009 | 1050 | #endif |
1010 | ||
1011 | /* $Source$ */ | |
1012 | /* $Revision$ */ | |
1013 | /* $Date$ */ |